Summary of computer graphics experiment in Shandong University

preface

This paper is a summary of computer graphics experiments. The experiments are written in glad and glfw. There are still many imperfections in the code. For example, the operations of drawing lines and polygons can be reasonably encapsulated to form a perfect graphics header file and even namespace, which is very helpful to the follow-up experiments, and the code will be more beautiful at the same time.

glfw's learning website is LearnOpenGl , if you want to complete the following code, basically half of the introductory part is enough. You can learn more advanced if you are interested.

Plagiarism is strictly prohibited! The code is for reference only!

Basic requirements of experiment

Homework topicContent requirements
Liang Barsky clipping algorithmSupport users to input / move / modify two end points interactively; The algorithm follows the spirit of "parameterization of straight line segments" and draws straight lines in real time. Please note that the line drawing command can call the ready-made API (instead of drawing pixel by pixel).
The polygon is cropped by the matrix windowThe window can be fixed; Support users to input arbitrary complex polygons; The output polygon boundary must be complete (no filling is allowed); Duplicate vertices and edges are not included.
Scanline filled polygonSupport users to input arbitrary complex polygons
Interactive Bezier curveSupport insert/delete/move control points; Based on De Casteljau's corner cutting algorithm; Draw control vertices / control polygons / splines at the same time.
Interactive B-splineBased on de boor corner cutting algorithm; Support insert/delete/move control points; Support modifying order; Draw control vertices / control polygons / splines at the same time.
Interactive display of geodesic distance fieldDisplay a 3D model based on libigl:( https://www.dropbox.com/s/vgzo0a0lxm692xk/kitten_simplified.obj?dl=0 ), select a vertex with the mouse and use the texture image( https://www.dropbox.com/s/tkih7u1libss633/MyColorBar2.png?dl=0 )Displays the distance field effect. Distance field algorithm code, please use( https://github.com/YipengQin/VTP_source_code )If you don't understand, please read readme: https://www.dropbox.com/s/a8iq4f238n07fgb/README.md?dl=0

CmakeList.txt

cmake_minimum_required(VERSION 3.14)
project(ComputerGraphics)

set(CMAKE_CXX_STANDARD 14)

# Add header file
set(GLFW_H /usr/local/Cellar/glfw/3.3.2/include/GLFW)
set(GLAD_H /usr/local/include/glad)
set(KH_H /usr/local/include/KHR)
include_directories(${GLFW_H} ${GLAD_H} ${KH_H})

find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})

find_package(GLUT REQUIRED)
include_directories(${GLUT_INCLUDE_DIR})

# Add target link
#set(GLEW_LINK /usr/local/Cellar/glew/2.1.0_1/lib/libGLEW.2.1.0.dylib)
set(GLFW_LINK /usr/local/Cellar/glfw/3.3.2/lib/libglfw.3.dylib)
set(CMAKE_CXX_FLAGS "-g -Wall")

link_libraries(${OPENGL} ${GLFW_LINK})

# Execute compile command
set(SOURCE_FILES0 "glad.c" LearnOpenGl.cpp)
set(SOURCE_FILES1 "glad.c" LearnOpenGL_template.cpp)
set(SOURCE_FILES2 "glad.c" LiangBarsky.cpp)
set(SOURCE_FILES3 "glad.c" Scan_Line.cpp)
set(SOURCE_FILES4 "glad.c" Bezier.cpp)
set(SOURCE_FILES5 "glad.c" Bresenham.cpp)
set(SOURCE_FILES6 "glad.c" B_spline.cpp)
set(SOURCE_FILES7 "glad.c" SutherlandHodgeman.cpp)
set(SOURCE_FILES8 "glad.c" DistanceField.cpp)
set(SOURCE_FILES9 "glad.c" test9.cpp)

add_executable(LearnOpenGl ${SOURCE_FILES0} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(LearnOpenGL_template ${SOURCE_FILES1} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(LiangBarsky ${SOURCE_FILES2} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Scan_Line ${SOURCE_FILES3} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Bezier ${SOURCE_FILES4} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Bresenham ${SOURCE_FILES5} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(B_spline ${SOURCE_FILES6} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(SutherlandHodgeman ${SOURCE_FILES7} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(DistanceField ${SOURCE_FILES8} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(test9 ${SOURCE_FILES9} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})

if (APPLE)
    target_link_libraries(LearnOpenGl "-framework OpenGL" "-framework GLUT")
    target_link_libraries(LearnOpenGL_template "-framework OpenGL" "-framework GLUT")
    target_link_libraries(LiangBarsky "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Scan_Line "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Bezier "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Bresenham "-framework OpenGL" "-framework GLUT")
    target_link_libraries(B_spline "-framework OpenGL" "-framework GLUT")
    target_link_libraries(SutherlandHodgeman "-framework OpenGL" "-framework GLUT")
    target_link_libraries(DistanceField "-framework OpenGL" "-framework GLUT")
    target_link_libraries(test9 "-framework OpenGL" "-framework GLUT")
endif()

Vertex shader code: shader vs

#version 330 core
layout (location = 0) in vec3 aPos;

out vec3 ourColor;

void main(){
    gl_Position = vec4(aPos, 1.0);

}

Fragment shader code: shader fs

#version 330 core

out vec4 FragColor;
uniform vec4 ourColor;

void main(){
    FragColor = ourColor;
}

Shader class: shader h

#ifndef COMPUTERGRAPHICS_SHADER_H
#define COMPUTERGRAPHICS_SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;

class Shader{
public:
    unsigned int ID;//Program ID
    Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr){//Vertex shader, clip shader, geometry shader
        string vertexCode;//Store shader code
        string fragmentCode;
        string geometryCode;
        ifstream vShaderFile;
        ifstream fShaderFile;
        ifstream gShaderFile;
        //Ensure that an exception can be thrown if the opening fails
        vShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
        fShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
        gShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
        try{
            vShaderFile.open(vertexPath);
            fShaderFile.open(fragmentPath);
            stringstream vShaderStream, fShaderStream;

            vShaderStream << vShaderFile.rdbuf();
            fShaderStream << fShaderFile.rdbuf();

            vShaderFile.close();
            fShaderFile.close();

            vertexCode = vShaderStream.str();
            fragmentCode = fShaderStream.str();

            if(geometryPath != nullptr){
                gShaderFile.open(geometryPath);
                stringstream gShaderStream;
                gShaderStream << gShaderFile.rdbuf();
                gShaderFile.close();
                geometryCode = gShaderStream.str();
            }
        }
        catch (ifstream::failure& e){
            cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl;
        }
        const char* vShaderCode = vertexCode.c_str();
        const char * fShaderCode = fragmentCode.c_str();

        //Create and compile vertex shaders
        unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);//Create a vertex shader
        glShaderSource(vertex, 1, &vShaderCode, nullptr);//Attach vertex shader source code to shader object
        glCompileShader(vertex);//Compile this shader object
        checkCompileErrors(vertex, "VERTEX");//Check for errors
        unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);//Create a clip shader
        glShaderSource(fragment, 1, &fShaderCode, nullptr);//Attach clip shader source code to shader object
        glCompileShader(fragment);//Compile this shader object
        checkCompileErrors(fragment, "FRAGMENT");//Check for errors
        unsigned int geometry;
        if(geometryPath != nullptr){//If you have a geometry shader, repeat the above steps
            const char * gShaderCode = geometryCode.c_str();
            geometry = glCreateShader(GL_GEOMETRY_SHADER);
            glShaderSource(geometry, 1, &gShaderCode, nullptr);
            glCompileShader(geometry);
            checkCompileErrors(geometry, "GEOMETRY");
        }
        ID = glCreateProgram();//Create a shader program object
        glAttachShader(ID, vertex);//Attaches a vertex shader object to a procedural object
        glAttachShader(ID, fragment);//Attaches a clip shader object to a program object
        if(geometryPath != nullptr)
            glAttachShader(ID, geometry);
        glLinkProgram(ID);//Link shader
        checkCompileErrors(ID, "PROGRAM");//Check for link errors

        glDeleteShader(vertex);//Delete previously unwanted shader objects
        glDeleteShader(fragment);
        if(geometryPath != nullptr)
            glDeleteShader(geometry);

    }
    void use(){//Activate shader object
        glUseProgram(ID);
    }
    //uniform tool function
    void setBool(const string &name, bool value) const{//name is a uniform value
        glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
    }
    void setInt(const string &name, int value) const{
        glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
    }
    void setFloat(const string &name, float value) const{
        glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
    }
    void setVec2(const string &name, const glm::vec2 &value) const{
        glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec2(const string &name, float x, float y) const{
        glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
    }
    void setVec3(const string &name, const glm::vec3 &value) const{
        glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec3(const string &name, float x, float y, float z) const{
        glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
    }
    void setVec4(const string &name, const glm::vec4 &value) const{
        glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec4(const string &name, float x, float y, float z, float w){
        glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
    }
    void setMat2(const string &name, const glm::mat2 &mat) const{
        glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    void setMat3(const string &name, const glm::mat3 &mat) const{
        glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    void setMat4(const string &name, const glm::mat4 &mat) const{
        glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }

private:
    void checkCompileErrors(GLuint shader, string type){//Error checking
        GLint success;
        GLchar infoLog[1024];
        if(type != "PROGRAM"){
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if(!success){
                glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
                cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << endl;
            }
        }
        else{
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if(!success){
                glGetProgramInfoLog(shader, 1024, nullptr, infoLog);
                cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << endl;
            }
        }
    }
};

#endif //COMPUTERGRAPHICS_SHADER_H

Keywords: C++ Computer Graphics OpenGL

Added by thinkgfx on Wed, 19 Jan 2022 20:25:25 +0200