-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcube.h
220 lines (184 loc) · 7.2 KB
/
cube.h
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>
#include <algorithm>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace std;
struct VAO {
GLuint VertexArrayID;
GLuint VertexBuffer;
GLuint ColorBuffer;
GLuint NormalBuffer;
GLenum PrimitiveMode;
GLenum FillMode;
int NumVertices;
};
struct GLMatrices {
glm::mat4 projection;
glm::mat4 model;
glm::mat4 view;
GLuint MatrixID;
} Matrices;
GLuint programID;
float clamp(float value, float min, float max) {
return std::max(min, std::min(max, value));
}
/* Function to load Shaders - Use it as it is */
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path) {
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open())
{
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage( max(InfoLogLength, int(1)) );
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
void quit(GLFWwindow *window)
{
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
/* Generate VAO, VBOs and return VAO handle */
struct VAO* create3DObject (GLenum primitive_mode, int numVertices, const GLfloat* vertex_buffer_data, const GLfloat* color_buffer_data, GLenum fill_mode=GL_FILL, const GLfloat* normal_buffer_data = NULL)
{
struct VAO* vao = new struct VAO;
vao->PrimitiveMode = primitive_mode;
vao->NumVertices = numVertices;
vao->FillMode = fill_mode;
// Create Vertex Array Object
// Should be done after CreateWindow and before any other GL calls
glGenVertexArrays(1, &(vao->VertexArrayID)); // VAO
glGenBuffers (1, &(vao->VertexBuffer)); // VBO - vertices
glGenBuffers (1, &(vao->ColorBuffer)); // VBO - colors
glGenBuffers (1, &(vao->NormalBuffer)); // VBO - normals
glBindVertexArray (vao->VertexArrayID); // Bind the VAO
glBindBuffer (GL_ARRAY_BUFFER, vao->VertexBuffer); // Bind the VBO vertices
glBufferData (GL_ARRAY_BUFFER, 3*numVertices*sizeof(GLfloat), vertex_buffer_data, GL_STATIC_DRAW); // Copy the vertices into VBO
glVertexAttribPointer(
0, // attribute 0. Vertices
3, // size (x,y,z)
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glBindBuffer (GL_ARRAY_BUFFER, vao->ColorBuffer); // Bind the VBO colors
glBufferData (GL_ARRAY_BUFFER, 3*numVertices*sizeof(GLfloat), color_buffer_data, GL_STATIC_DRAW); // Copy the vertex colors
glVertexAttribPointer(
1, // attribute 1. Color
3, // size (r,g,b)
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glBindBuffer (GL_ARRAY_BUFFER, vao->NormalBuffer); // Bind the VBO normals
glBufferData (GL_ARRAY_BUFFER, 3*numVertices*sizeof(GLfloat), normal_buffer_data, GL_STATIC_DRAW); // Copy the normals
glVertexAttribPointer(
2, // attribute 1. Color
3, // size (r,g,b)
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
return vao;
}
/* Generate VAO, VBOs and return VAO handle - Common Color for all vertices */
struct VAO* create3DObject (GLenum primitive_mode, int numVertices, const GLfloat* vertex_buffer_data, const GLfloat red, const GLfloat green, const GLfloat blue, GLenum fill_mode=GL_FILL, const GLfloat* normal_buffer_data = NULL)
{
GLfloat* color_buffer_data = new GLfloat [3*numVertices];
for (int i=0; i<numVertices; i++) {
color_buffer_data [3*i] = red;
color_buffer_data [3*i + 1] = green;
color_buffer_data [3*i + 2] = blue;
}
return create3DObject(primitive_mode, numVertices, vertex_buffer_data, color_buffer_data, fill_mode, normal_buffer_data);
}
/* Render the VBOs handled by VAO */
void draw3DObject (struct VAO* vao)
{
// Change the Fill Mode for this object
glPolygonMode (GL_FRONT_AND_BACK, vao->FillMode);
// Bind the VAO to use
glBindVertexArray (vao->VertexArrayID);
// Enable Vertex Attribute 0 - 3d Vertices
glEnableVertexAttribArray(0);
// Bind the VBO to use
glBindBuffer(GL_ARRAY_BUFFER, vao->VertexBuffer);
// Enable Vertex Attribute 1 - Color
glEnableVertexAttribArray(1);
// Bind the VBO to use
glBindBuffer(GL_ARRAY_BUFFER, vao->ColorBuffer);
// Enable Vertex Attribute 2 - Normals
glEnableVertexAttribArray(2);
// Bind the VBO to use
glBindBuffer(GL_ARRAY_BUFFER, vao->NormalBuffer);
// Draw the geometry !
glDrawArrays(vao->PrimitiveMode, 0, vao->NumVertices); // Starting from vertex 0; 3 vertices total -> 1 triangle
}