/* glew.h 源代码中的一些宏定义 typedef unsigned int GLenum; typedef unsigned int GLbitfield; typedef unsigned int GLuint; typedef int GLint; typedef int GLsizei; typedef unsigned char GLboolean; typedef signed char GLbyte; typedef short GLshort; typedef unsigned char GLubyte; typedef unsigned short GLushort; typedef unsigned long GLulong; typedef float GLfloat; typedef float GLclampf; typedef double GLdouble; typedef double GLclampd; typedef void GLvoid; */ #include#define GLEW_STATIC #include #include void key_callback(GLFWwindow *windows, int key, int scancode, int actin, int mode); const GLuint WIDTH = 800, HEIGHT = 600; //Shaders const GLchar *vertexShaderSource = "#version 330 core\n" " \n" "layout (location = 0) in vec3 position;\n" "\n" "void main()\n" "{\n" " gl_Position = vec4(position.x, position.y, position.z, 1.0);\n" "}"; const GLchar *fragmentShaderSource = "#version 330 core\n" "out vec4 color;\n" "void main()\n" "{\n" "color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" "}\n\0"; const GLchar* fragmentShaderSource2 = "#version 330 core\n" "out vec4 color;\n" "void main()\n" "{\n" "color = vec4(1.0f, 1.0f, 0.0f, 1.0f); // The color yellow \n" "}\n\0"; int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); //返回指向 GLFWwindow 对象的指针,参数有五个,前两个是高和宽,中间是窗口的名字,后两个是模式和共享的选项, //现在都是 null, 注意 nullptr 是 c++11 的语法 GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); //用 GLFW 在当前现成创建主环境 glewExperimental = GL_TRUE;//将其设为 true 来使 glew 用更新的技术来处理 opengl 函数 glewInit();//初始化glew //用 viewport 来定义尺寸来使其能在高 dpi 屏幕上也能正常工作 int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); //创建 vertexShader,glShaderSource 将 shader 的代码给定到指定的 shader 中,返回对象的 ID //glCompileShader 来编译. GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); //当编译 Shader 错误时报错 GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader ,同上 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // 检查编译错误 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader ,同上 GLuint fragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader2, 1, &fragmentShaderSource2, NULL); glCompileShader(fragmentShader2); // Check for compile time errors glGetShaderiv(fragmentShader2, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader2, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); //检查 link 是否出错 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } GLuint shaderProgram2 = glCreateProgram(); glAttachShader(shaderProgram2, vertexShader); glAttachShader(shaderProgram2, fragmentShader2); glLinkProgram(shaderProgram2); //检查 link 是否出错 glGetProgramiv(shaderProgram2, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram2, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } //用完后删除 Shader glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glDeleteShader(fragmentShader2); //定义点数据 GLfloat vertices1[] = { 0.0f, -0.5f, 0.0f, 1.0f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, }; GLfloat vertices2[] = { 0.0f, -0.5f, 0.0f, -1.0, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f }; GLuint VBOs[2], VAOs[2]; //第一个三角形 glGenVertexArrays(1, &VAOs[0]); glGenBuffers(1, &VBOs[0]); glBindVertexArray(VAOs[0]); glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]); //绑定 VBO glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);//将定义好的点放入缓存中, glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0);//定义如何使用点数据,第一个参数是 location,确定我们要设置哪些点属性 glEnableVertexAttribArray(0); //使 location 为 0 的点可以使用属性,默认是关闭的 glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑 VBO glBindVertexArray(0);//解绑 VAO //第二个三角形 glGenVertexArrays(1, &VAOs[1]); glGenBuffers(1, &VBOs[1]); glBindVertexArray(VAOs[1]); glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]); //绑定 VBO glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);//将定义好的点放入缓存中, glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0);//定义如何使用点数据,第一个参数是 location,确定我们要设置哪些点属性 glEnableVertexAttribArray(0); //使 location 为 0 的点可以使用属性,默认是关闭的 glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑 VBO glBindVertexArray(0);//解绑 VAO //游戏循环 while (!glfwWindowShouldClose(window)) { //检查是否有事件发生 glfwPollEvents(); //重置颜色 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); //运行shaderProgram glUseProgram(shaderProgram); glBindVertexArray(VAOs[0]); //画出三角形 glDrawArrays(GL_TRIANGLES, 0, 3); glUseProgram(shaderProgram2); glBindVertexArray(VAOs[1]); //画出三角形 glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); //交换缓存 glfwSwapBuffers(window); } glDeleteVertexArrays(2, VAOs); glDeleteBuffers(2, VBOs); glfwTerminate(); return 0; } void key_callback(GLFWwindow *window, int key, int scancode, int action, int mode) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); }
这是 learnopengl 里的习题