2019/11/26
1 #include <glad/glad.h> 2 #include <GLFW/glfw3.h> 3 #include <iostream> 4 5 void framebuffer_size_callback(GLFWwindow* window, int width, int height) 6 { 7 glViewport(0, 0, width, height); 8 } 9 void processInput(GLFWwindow *window) 10 { 11 if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 12 glfwSetWindowShouldClose(window, true); 13 } 14 const char *vertexShaderSource = "#version 330 core\n" 15 "layout (location = 0) in vec3 aPos;\n" 16 "void main()\n" 17 "{\n" 18 " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" 19 "}\0"; 20 const char *fragmentShaderSource1 = "#version 330 core\n" 21 "out vec4 FragColor;\n" 22 "void main()\n" 23 "{\n" 24 " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" 25 "}\n\0"; 26 const char *fragmentShaderSource2 = "#version 330 core\n" 27 "out vec4 FragColor;\n" 28 "void main()\n" 29 "{\n" 30 " FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n" 31 "}\n\0"; 32 33 int main() 34 { 35 glfwInit(); 36 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 37 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 38 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 39 //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 40 41 GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); 42 if (window == NULL) 43 { 44 std::cout << "Failed to create GLFW window" << std::endl; 45 glfwTerminate(); 46 return -1; 47 } 48 glfwMakeContextCurrent(window); 49 50 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 51 52 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 53 { 54 std::cout << "Failed to initialize GLAD" << std::endl; 55 return -1; 56 } 57 58 //vertex shader 59 int vertexShader = glCreateShader(GL_VERTEX_SHADER); 60 glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 61 glCompileShader(vertexShader); 62 // check for shader compile errors 63 int success; 64 char infoLog[512]; 65 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 66 if (!success) 67 { 68 glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); 69 std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 70 } 71 72 //first fragment shader 73 int fragmentShader1 = glCreateShader(GL_FRAGMENT_SHADER); 74 glShaderSource(fragmentShader1, 1, &fragmentShaderSource1, NULL); 75 glCompileShader(fragmentShader1); 76 77 //second fragment shader 78 int fragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER); 79 glShaderSource(fragmentShader2, 1, &fragmentShaderSource2, NULL); 80 glCompileShader(fragmentShader2); 81 82 // first link shaders 83 int shaderProgram1 = glCreateProgram(); 84 glAttachShader(shaderProgram1, vertexShader); 85 glAttachShader(shaderProgram1, fragmentShader1); 86 glLinkProgram(shaderProgram1); 87 88 //second link shaders 89 int shaderProgram2 = glCreateProgram(); 90 glAttachShader(shaderProgram2, vertexShader); 91 glAttachShader(shaderProgram2, fragmentShader2); 92 glLinkProgram(shaderProgram2); 93 94 glDeleteShader(vertexShader); 95 glDeleteShader(fragmentShader1); 96 glDeleteShader(fragmentShader2); 97 98 float firstTriangle[] = { 99 -0.9f, -0.5f, 0.0f, // left 100 -0.0f, -0.5f, 0.0f, // right 101 -0.45f, 0.5f, 0.0f, // top 102 }; 103 float secondTriangle[] = { 104 0.0f, -0.5f, 0.0f, // left 105 0.9f, -0.5f, 0.0f, // right 106 0.45f, 0.5f, 0.0f // top 107 }; 108 109 unsigned int VBO[2], VAO[2]; 110 glGenVertexArrays(2, VAO); 111 glGenBuffers(2, VBO); 112 // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 113 glBindVertexArray(VAO[0]); 114 glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); 115 glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW); 116 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 117 glEnableVertexAttribArray(0); 118 119 glBindVertexArray(VAO[1]); 120 glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); 121 glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW); 122 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 123 glEnableVertexAttribArray(0); 124 125 // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind 126 //glBindBuffer(GL_ARRAY_BUFFER, 0); 127 128 // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other 129 // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 130 //glBindVertexArray(0); 131 132 while (!glfwWindowShouldClose(window)) 133 { 134 //输入 135 processInput(window); 136 137 //渲染指令 138 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 139 glClear(GL_COLOR_BUFFER_BIT); 140 141 // draw our first triangle 142 glUseProgram(shaderProgram1); 143 glBindVertexArray(VAO[0]); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized 144 glDrawArrays(GL_TRIANGLES, 0, 3); 145 146 glUseProgram(shaderProgram2); 147 glBindVertexArray(VAO[1]); 148 glDrawArrays(GL_TRIANGLES, 0, 3); 149 // glBindVertexArray(0); // no need to unbind it every time 150 151 //检查并调用事件,交换缓冲 152 glfwSwapBuffers(window); 153 glfwPollEvents(); 154 } 155 156 // optional: de-allocate all resources once they've outlived their purpose: 157 glDeleteVertexArrays(2, VAO); 158 glDeleteBuffers(2, VBO); 159 160 glfwTerminate(); 161 return 0; 162 }