1 #include <GL\glew.h> 2 #include <GLFW\glfw3.h> 3 #include <iostream> 4 5 using namespace std; 6 7 constexpr auto numVAOs = 1; 8 9 GLuint renderingProgram; 10 GLuint vao[numVAOs]; 11 12 void printShaderLog(GLuint shader) { 13 int len = 0; 14 int chWrittn = 0; 15 char *log; 16 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); 17 if (len > 0) { 18 log = (char*)malloc(len); 19 glGetShaderInfoLog(shader, len, &chWrittn, log); 20 cout << "Shader Info Log: " << log << endl; 21 free(log); 22 } 23 } 24 25 void printProgramLog(int prog) { 26 int len = 0; 27 int chWrittn = 0; 28 char *log; 29 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len); 30 if (len > 0) { 31 log = (char*)malloc(len); 32 glGetProgramInfoLog(prog, len, &chWrittn, log); 33 cout << "Program Info Log: " << log << endl; 34 free(log); 35 } 36 } 37 38 bool checkOpenGLError() { 39 bool foundError = false; 40 int glErr = glGetError(); 41 while (glErr != GL_NO_ERROR) { 42 cout << "glError: " << glErr << endl; 43 foundError = true; 44 glErr = glGetError(); 45 } 46 return foundError; 47 } 48 49 GLuint createShaderProgram() { 50 GLint vertCompiled; 51 GLint fragCompiled; 52 GLint linked; 53 54 const char* vshaderSource = 55 "#version 430 \n" 56 "void main(void) \n" 57 "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"; 58 59 const char* fshaderSource = 60 "#version 430 \n" 61 "out vec4 color; \n" 62 "void main(void) \n" 63 "{ if(gl_FragCoord.x < 200) color = vec4(1.0f, 0.0f, 0.0f, 1.0f);else color = vec4(0.0, 0.0, 1.0, 1.0);}"; 64 65 /** 66 * @brief 创建着色器,返回一个整数ID作为索引号,便于后续引用 67 * OpenGL中要使用一个shader需要如下几步: 68 * 1.使用glCreateShader()方法创建一个空的着色器对象,用来接收源代码并进行编译 69 * 2.使用glShaderSource()方法将着色器源码传递给着色器对象,以便保留该源代码的副本 70 * 3.使用glCompileShader()方法对着色器对象中包含的任何源代码进行编译 71 * 4.使用glCreateProgram()方法创建一个着色器程序,我们可以将着色器对象附加到该对象 72 * 5.使用glAttachShader()方法将着色器附加到着色器程序 73 * 6.使用glLinkProgram()方法将所有附加到程序对象的着色器对象链接在一起 74 * 7.使用glDeleteShader()方法删除着色器对象。一旦着色器链接到一个程序对象,程序将包含二进制代码,不再需要着色器了 75 **/ 76 GLuint vShader = glCreateShader(GL_VERTEX_SHADER); 77 GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER); 78 79 /** 80 * @brief 创建程序对象,返回整数ID索引值 81 **/ 82 GLuint vfProgram = glCreateProgram(); 83 84 /** 85 * @brief 将GLSL代码从字符串载入空着色器对象中 86 **/ 87 glShaderSource(vShader, 1, &vshaderSource, NULL); 88 glShaderSource(fShader, 1, &fshaderSource, NULL); 89 90 /** 91 * @brief 编译着色器 92 **/ 93 glCompileShader(vShader); 94 checkOpenGLError(); 95 glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled); 96 if (vertCompiled != 1) { 97 cout << "vertex compilation failed" << endl; 98 printShaderLog(vShader); 99 } 100 101 glCompileShader(fShader); 102 checkOpenGLError(); 103 glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragCompiled); 104 if (fragCompiled != 1) { 105 cout << "fragment compilation failed" << endl; 106 printShaderLog(fShader); 107 } 108 109 110 /** 111 * @brief 将着色器附加到程序对象 112 **/ 113 glAttachShader(vfProgram, vShader); 114 glAttachShader(vfProgram, fShader); 115 glLinkProgram(vfProgram); 116 checkOpenGLError(); 117 glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked); 118 if (linked != 1) { 119 cout << "linked failed" << endl; 120 printProgramLog(vfProgram); 121 } 122 123 glDeleteShader(vShader); 124 glDeleteShader(fShader); 125 126 return vfProgram; 127 } 128 129 130 131 void init(GLFWwindow* window) { 132 renderingProgram = createShaderProgram(); 133 glGenVertexArrays(numVAOs, vao); 134 glBindVertexArray(vao[0]); 135 } 136 137 void display(GLFWwindow* window, double currentTime) { 138 139 /** 140 * @brief OpenGL函数,用于指定颜色缓存区清除后填充的颜色值 141 **/ 142 //glClearColor(1.0, 0.0, 0.0, 1.0); 143 144 /** 145 * @brief OpenGL函数,用指定的颜色清除(填充)颜色缓存区 146 **/ 147 //glClear(GL_COLOR_BUFFER_BIT); 148 149 /** 150 * @brief 将含有已编译着色器的程序载入OpenGL管线阶段(GPU),并没有运行着色器,只是载入。 151 **/ 152 glUseProgram(renderingProgram); 153 154 155 glPointSize(400.0f); 156 glDrawArrays(GL_POINTS, 0, 1); 157 } 158 159 int main(void) { 160 161 /** 162 * @brief 初始化glfw库 163 **/ 164 if (!glfwInit()) { exit(EXIT_FAILURE); } 165 166 /** 167 * @brief 为glfwCreateWindow设置可选项 168 **/ 169 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 170 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 171 172 /** 173 * @brief 创建glfw窗口及其相关的OpenGL上下文 174 **/ 175 GLFWwindow* window = glfwCreateWindow(600, 600, "OpenGL", NULL, NULL); 176 177 /** 178 * @brief 创建glfw窗口及其相关的OpenGL上下文之后,并不会将它们自动关联,需要调用函数glfwMakeContextCurrent 179 **/ 180 glfwMakeContextCurrent(window); 181 182 /** 183 * @brief 初始化glew库 184 **/ 185 if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); } 186 187 /** 188 * @brief 开启垂直同步 189 **/ 190 glfwSwapInterval(1); 191 192 init(window); 193 194 while (!glfwWindowShouldClose(window)) { 195 196 /** 197 * @brief glfwGetTime返回glfw初始化之后经过的时间 198 **/ 199 display(window, glfwGetTime()); 200 201 /** 202 * @brief 交换缓存内容,绘制屏幕 203 **/ 204 glfwSwapBuffers(window); 205 206 /** 207 * @brief 处理窗口相关的事件 208 **/ 209 glfwPollEvents(); 210 } 211 212 /** 213 * @brief 退出循环后,表示窗口关闭,需要销毁glfw窗口对象,终止程序运行 214 **/ 215 glfwDestroyWindow(window); 216 glfwTerminate(); 217 218 exit(EXIT_SUCCESS); 219 return 0; 220 }