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 }
