-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.cpp
128 lines (109 loc) · 4.21 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "../common/util.h"
#include "../common/shader.h"
const char* VERTEX_SRC = "#version 330 core\n"
"layout(location=0) in vec2 position;" // Vertex position (x, y)
"layout(location=1) in vec3 color;" // Vertex color (r, g, b)
"out vec3 fColor;" // Vertex shader has to pass color to fragment shader
"void main()"
"{"
" fColor = color;" // Pass color to fragment shader
" gl_Position=vec4(position, 0.0, 1.0);" // Place vertex at (x, y, 0, 1)
"}";
const char* FRAGMENT_SRC = "#version 330 core\n"
"in vec3 fColor;" // From the vertex shader
"out vec4 outputColor;" // The color of the resulting fragment
"void main()"
"{"
" outputColor = vec4(fColor, 1.0);" // Color it (r, g, b, 1.0) for fully opaque
"}";
int main(void)
{
GLFWwindow* window;
// The OpenGL context creation code is in
// ../common/util.cpp
window = init("Hello Triangle", 640, 480);
if(!window)
{
return -1;
}
// We start by creating a vertex and fragment shader
// from the above strings
GLuint vertex = createShader(VERTEX_SRC, GL_VERTEX_SHADER);
if(!vertex)
{
return -1;
}
GLuint fragment = createShader(FRAGMENT_SRC, GL_FRAGMENT_SHADER);
if(!fragment)
{
return -1;
}
// Now we must make a shader program: this program
// contains both the vertex and the fragment shader
GLuint program = createShaderProgram(vertex, fragment);
if(!program)
{
return -1;
}
// We link the program, just like your C compiler links
// .o files
bool result = linkShader(program);
if(!result)
{
return -1;
}
// We make sure the shader is validated
result = validateShader(program);
if(!result)
{
return -1;
}
// Detach and delete the shaders, because we no longer need them
glDetachShader(program, vertex);
glDeleteShader(vertex);
glDetachShader(program, fragment);
glDeleteShader(fragment);
glUseProgram(program); // Set this as the current shader program
// We now create the data to send to the GPU
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
float vertices[] =
{
// x y r g b
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
};
// Upload the vertices to the buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Enable the vertex attributes and upload their data (see: layout(location=x))
glEnableVertexAttribArray(0); // position
// 2 floats: x and y, but 5 floats in total per row
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(1); // color
// 3 floats: r, g and b, but 5 floats in total per row and start at the third one
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
// We have now successfully created a drawable Vertex Array Object
// Set the clear color to a light grey
glClearColor(0.75f, 0.75f, 0.75f, 1.0f);
while(!glfwWindowShouldClose(window))
{
// Clear
glClear(GL_COLOR_BUFFER_BIT);
// The VAO is still bound so just draw the 3 vertices
glDrawArrays(GL_TRIANGLES, 0, 3);
// Tip: if nothing is drawn, check the return value of glGetError and google it
// Swap buffers to show current image on screen (for more information google 'backbuffer')
glfwSwapBuffers(window);
glfwPollEvents();
}
// Clean up
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
return 0;
}