TazGraph Project v0.1.0
Loading...
Searching...
No Matches
GLSLProgram.h
1#pragma once
2
3#include <iostream>
4#include <string>
5#include "GL/glew.h"
6
7#include <vector>
8#include <fstream>
9
10#include "./Vertex.h"
11
12#include "TextureManager/TextureManager.h"
13#include "ConsoleLogger.h"
14
15#define LINE_OFFSET 2
16#define SQUARE_OFFSET 4
17
18#define TRIANGLE_VERTICES 3
19#define QUAD_INDICES 6
20#define BOX_OFFSET 8
21
22#define TOTAL_MESHES 4
23
24#define TRIANGLE_MESH_IDX 0
25#define RECTANGLE_MESH_IDX 1
26#define BOX_MESH_IDX 2
27#define SPHERE_MESH_IDX 3
28
29constexpr int INDICES_LINE_OFFSET = LINE_OFFSET;
30constexpr int INDICES_SQUARE_OFFSET = 2 * SQUARE_OFFSET;
31constexpr int INDICES_BOX_OFFSET = 3 * BOX_OFFSET;
32
33constexpr int ARRAY_BOX_OFFSET = 36;
34
35
36static Position triangleVertices[3] = {
37 { 0.0f, 0.5f, 0.0f }, // Top
38 { -0.5f, -0.5f, 0.0f }, // Bottom Left
39 { 0.5f, -0.5f, 0.0f } // Bottom Right
40};
41
42static GLuint triangleIndices[3] = {
43 0, 1, 2
44};
45
46static Position quadVertices[4] = {
47 { -0.5f, 0.5f, 0.0f },
48 { -0.5f, -0.5f, 0.0f },
49 { 0.5f, -0.5f, 0.0f },
50 { 0.5f, 0.5f, 0.0f }
51};
52
53static UV uv_quadVertices[4] = {
54 {0.0f, 0.0f},
55 {1.0f, 0.0f},
56 {1.0f, 1.0f},
57 {0.0f, 1.0f}
58};
59
60static TextureVertex tex_quadVertices[4] = {
61 { glm::vec3(-0.5f, 0.5f, 0.0f), glm::vec2(0.0f, 1.0f) }, // top-left
62 { glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec2(0.0f, 0.0f) }, // bottom-left
63 { glm::vec3(0.5f, -0.5f, 0.0f), glm::vec2(1.0f, 0.0f) }, // bottom-right
64 { glm::vec3(0.5f, 0.5f, 0.0f), glm::vec2(1.0f, 1.0f) } // top-right
65};
66
67static GLuint quadIndices[6] = {
68 0, 1, 2,
69 2, 3, 0
70};
71
72static Position cubeVertices[8] = {
73 { -0.5f, -0.5f, -0.5f },
74 { 0.5f, -0.5f, -0.5f },
75 { 0.5f, 0.5f, -0.5f },
76 { -0.5f, 0.5f, -0.5f },
77 { -0.5f, -0.5f, 0.5f },
78 { 0.5f, -0.5f, 0.5f },
79 { 0.5f, 0.5f, 0.5f },
80 { -0.5f, 0.5f, 0.5f }
81};
82
83static LightVertex light_cubeVertices[24] = {
84 // Front face
85 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
86 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
87 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
88 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
89
90 // Back face
91 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
92 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
93 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
94 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
95
96 // Left face
97 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
98 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
99 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
100 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
101
102 // Right face
103 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
104 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
105 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
106 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
107
108 // Bottom face
109 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
110 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
111 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
112 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
113
114 // Top face
115 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
116 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
117 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
118 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f) }
119};
120
121static GLuint cubeIndices[36] = {
122 0, 1, 2,
123 2, 3, 0,
124
125 // Back face (vertices 4-7)
126 4, 5, 6,
127 6, 7, 4,
128
129 // Left face (vertices 8-11)
130 8, 9,10,
131 10,11,8,
132
133 // Right face (vertices 12-15)
134 12,13,14,
135 14,15,12,
136
137 // Bottom face (vertices 16-19)
138 16,17,18,
139 18,19,16,
140
141 // Top face (vertices 20-23)
142 20,21,22,
143 22,23,20
144};
145
146
147static void generateSphereMesh(std::vector<Position>& vertices, std::vector<GLuint>& indices,
148 float radius = 1.0f, unsigned int sectorCount = 36, unsigned int stackCount = 18) {
149 const float PI = 3.14159265359f;
150
151 vertices.clear();
152 indices.clear();
153
154 for (unsigned int i = 0; i <= stackCount; ++i) {
155 float stackAngle = PI / 2.0f - i * PI / stackCount; // from pi/2 to -pi/2
156 float xy = radius * cosf(stackAngle);
157 float z = radius * sinf(stackAngle);
158
159 for (unsigned int j = 0; j <= sectorCount; ++j) {
160 float sectorAngle = j * 2.0f * PI / sectorCount;
161
162 float x = xy * cosf(sectorAngle);
163 float y = xy * sinf(sectorAngle);
164 glm::vec3 pos(x, y, z);
165
166 vertices.push_back(pos);
167 }
168 }
169
170 for (unsigned int i = 0; i < stackCount; ++i) {
171 unsigned int k1 = i * (sectorCount + 1);
172 unsigned int k2 = k1 + sectorCount + 1;
173
174 for (unsigned int j = 0; j < sectorCount; ++j, ++k1, ++k2) {
175 if (i != 0) {
176 indices.push_back(k1);
177 indices.push_back(k2);
178 indices.push_back(k1 + 1);
179 }
180 if (i != (stackCount - 1)) {
181 indices.push_back(k1 + 1);
182 indices.push_back(k2);
183 indices.push_back(k2 + 1);
184 }
185 }
186 }
187}
188
189static void generateSphereMesh(std::vector<LightVertex>& vertices, std::vector<GLuint>& indices,
190 float radius = 1.0f, unsigned int sectorCount = 36, unsigned int stackCount = 18) {
191 const float PI = 3.14159265359f;
192
193 vertices.clear();
194 indices.clear();
195
196 for (unsigned int i = 0; i <= stackCount; ++i) {
197 float stackAngle = PI / 2.0f - i * PI / stackCount; // from pi/2 to -pi/2
198 float xy = radius * cosf(stackAngle);
199 float z = radius * sinf(stackAngle);
200
201 for (unsigned int j = 0; j <= sectorCount; ++j) {
202 float sectorAngle = j * 2.0f * PI / sectorCount;
203
204 float x = xy * cosf(sectorAngle);
205 float y = xy * sinf(sectorAngle);
206 glm::vec3 pos(x, y, z);
207
208 glm::vec3 normal = glm::normalize(pos);
209 vertices.push_back({ pos, normal });
210 }
211 }
212
213 for (unsigned int i = 0; i < stackCount; ++i) {
214 unsigned int k1 = i * (sectorCount + 1);
215 unsigned int k2 = k1 + sectorCount + 1;
216
217 for (unsigned int j = 0; j < sectorCount; ++j, ++k1, ++k2) {
218 if (i != 0) {
219 indices.push_back(k1);
220 indices.push_back(k2);
221 indices.push_back(k1 + 1);
222 }
223 if (i != (stackCount - 1)) {
224 indices.push_back(k1 + 1);
225 indices.push_back(k2);
226 indices.push_back(k2 + 1);
227 }
228 }
229 }
230}
231
233
234 InstanceData() {}
235 InstanceData(glm::vec3 mSize, Position mBodyCenter, Rotation mRotation) :
236 size(mSize),
237 bodyCenter(mBodyCenter),
238 rotation(mRotation)
239 {
240 }
241
242 InstanceData(glm::vec2 mSize, Position mBodyCenter, Rotation mRotation) :
243 size(glm::vec3(mSize, 0.0f)),
244 bodyCenter(mBodyCenter),
245 rotation(mRotation)
246 {
247 }
248
249 ~InstanceData() {}
250
251 Size size = glm::vec3(0.0f);
252 Position bodyCenter = glm::vec3(0.0f);
253 Rotation rotation = glm::vec3(0.0f);
254};
255
256
258
260 ColorInstanceData(glm::vec3 mSize, Position mBodyCenter, Rotation mRotation, Color mColor) : InstanceData(mSize, mBodyCenter, mRotation), color(mColor) {
261 }
262 ColorInstanceData(glm::vec2 mSize, Position mBodyCenter, Rotation mRotation, Color mColor) : InstanceData(mSize, mBodyCenter, mRotation), color(mColor) {
263 }
264
266
267 Color color = Color(255, 255, 255, 255);
268};
269
271
273 TextureInstanceData(glm::vec3 mSize, Position mBodyCenter, Rotation mRotation, GLuint Texture) : InstanceData(mSize, mBodyCenter, mRotation), texture(Texture) {
274 }
275 TextureInstanceData(glm::vec2 mSize, Position mBodyCenter, Rotation mRotation, GLuint Texture) : InstanceData(mSize, mBodyCenter, mRotation), texture(Texture) {
276 }
277
279
280 GLuint texture = 0;
281 UV uv = glm::vec2(0.0f);
282};
283
285 size_t meshIndices = 0;
286
287 GLuint vao;
288
289 //for static draws
290 GLuint vbo;
291 GLuint ibo;
292};
293
295 std::vector<InstanceData> instances;
296};
297
299 std::vector<ColorInstanceData> instances;
300};
301
303 std::vector<TextureInstanceData> instances;
304};
305
307public:
308 GLSLProgram() : _programID(0), _vertexShaderID(0), _geometryShaderID(0), _fragmentShaderID(0), _numAttributes(0)
309 {
310
311 }
312
313 ~GLSLProgram() {
314
315 }
316
317 // Vertex + Fragment
318 void compileAndLinkShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath) {
319 std::string vertSource = readShaderFile(vertexShaderFilePath);
320 std::string fragSource = readShaderFile(fragmentShaderFilePath);
321
322 compileAndLinkShadersFromSource(vertSource.c_str(), fragSource.c_str());
323 }
324
325 // Vertex + Geometry + Fragment
326 void compileAndLinkShaders(const std::string& vertexShaderFilePath, const std::string& geometryShaderFilePath, const std::string& fragmentShaderFilePath) {
327 std::string vertSource = readShaderFile(vertexShaderFilePath);
328 std::string geomSource = readShaderFile(geometryShaderFilePath);
329 std::string fragSource = readShaderFile(fragmentShaderFilePath);
330
331 compileAndLinkShadersFromSource(vertSource.c_str(), geomSource.c_str(), fragSource.c_str());
332 }
333
334 void compileAndLinkShadersFromSource(const char* vertexSource, const char* fragmentSource) {
335
336 std::vector<GLuint> shaderIDs;
337
338 shaderIDs.push_back(createAndCompileShader(vertexSource, GL_VERTEX_SHADER, "Vertex"));
339 shaderIDs.push_back(createAndCompileShader(fragmentSource, GL_FRAGMENT_SHADER, "Fragment"));
340
341 linkShadersInternal(shaderIDs);
342 }
343
344 void compileAndLinkShadersFromSource(const char* vertexSource, const char* geometrySource, const char* fragmentSource) {
345
346 std::vector<GLuint> shaderIDs;
347
348 shaderIDs.push_back(createAndCompileShader(vertexSource, GL_VERTEX_SHADER, "Vertex"));
349 shaderIDs.push_back(createAndCompileShader(geometrySource, GL_GEOMETRY_SHADER, "Geometry"));
350 shaderIDs.push_back(createAndCompileShader(fragmentSource, GL_FRAGMENT_SHADER, "Fragment"));
351
352 linkShadersInternal(shaderIDs);
353 }
354
355
356 void addAttribute(const std::string& attributeName) {
357 glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
358 }
359
360 GLint getUniformLocation(const std::string& uniformName) {
361 GLint location = glGetUniformLocation(_programID, uniformName.c_str());
362
363 if (location == GL_INVALID_INDEX) {
364 TazGraphEngine::ConsoleLogger::error("Uniform " + uniformName + " not found in shader!");
365 }
366 return location;
367 }
368
369 void use() {
370 glUseProgram(_programID);
371 for (int i = 0; i < _numAttributes; i++) {
372 glEnableVertexAttribArray(i);
373 }
374 }
375
376 void unuse() {
377 glUseProgram(0);
378 for (int i = 0; i < _numAttributes; i++) {
379 glDisableVertexAttribArray(i);
380 }
381 }
382
383 void dispose() {
384 if(_programID != 0) glDeleteProgram(_programID);
385 }
386
387 GLuint getProgramID() {
388 return _programID;
389 }
390
391private:
392 GLuint _programID;
393
394 GLuint _vertexShaderID;
395 GLuint _geometryShaderID;
396 GLuint _fragmentShaderID;
397
398 int _numAttributes;
399
400 std::string readShaderFile(const std::string& filePath) {
401 std::vector<unsigned char> buffer;
402 TextureManager::readFileToBuffer(filePath.c_str(), buffer);
403 return std::string(buffer.begin(), buffer.end());
404 }
405
406 GLuint createAndCompileShader(const std::string& source, GLenum shaderType, const std::string& typeName) {
407 GLuint shaderID = glCreateShader(shaderType);
408 if (shaderID == 0) {
409 TazGraphEngine::ConsoleLogger::error(typeName + " Shader Failed to create!");
410 return 0;
411 }
412
413 compileShader(source.c_str(), typeName, shaderID);
414 return shaderID;
415 }
416
417 void compileShader(const char* source, const std::string& name, GLuint id) {
418
419 glShaderSource(id, 1, &source, nullptr); //1 for number of strings
420
421 glCompileShader(id);
422
423 GLint success = 0;
424 glGetShaderiv(id, GL_COMPILE_STATUS, &success);
425
426 if (success == GL_FALSE)
427 {
428 GLint maxLength = 0;
429 glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
430
431 // The maxLength includes the NULL character
432 std::vector<GLchar> errorLog(maxLength);
433 glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
434
435 // Provide the infolog in whatever manor you deem best.
436 // Exit with failure.
437 glDeleteShader(id); // Don't leak the shader.
438
439 std::printf("%s\n", &(errorLog[0]));
440 std::cout << "Shader " + name + " failed to compile" << std::endl;
441
442 }
443 }
444
445 void linkShadersInternal(const std::vector<GLuint>& shaderIDs) {
446 _programID = glCreateProgram();
447
448 // Attach all shaders
449 for (GLuint shaderID : shaderIDs) {
450 glAttachShader(_programID, shaderID);
451 }
452
453 // Link program
454 glLinkProgram(_programID);
455
456 // Check link status
457 GLint isLinked = 0;
458 glGetProgramiv(_programID, GL_LINK_STATUS, &isLinked);
459
460 if (isLinked == GL_FALSE) {
461 GLint maxLength = 0;
462 glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);
463
464 std::vector<GLchar> errorLog(maxLength);
465 glGetProgramInfoLog(_programID, maxLength, &maxLength, &errorLog[0]);
466
467 // Cleanup on failure
468 glDeleteProgram(_programID);
469 for (GLuint shaderID : shaderIDs) {
470 glDeleteShader(shaderID);
471 }
472
473 std::printf("%s\n", &errorLog[0]);
474 TazGraphEngine::ConsoleLogger::error("Shaders failed to link");
475 return;
476 }
477
478 // Cleanup shaders after successful link
479 for (GLuint shaderID : shaderIDs) {
480 glDetachShader(_programID, shaderID);
481 glDeleteShader(shaderID);
482 }
483 }
484
485};
Definition GLSLProgram.h:306
Definition GLSLProgram.h:284
Definition GLSLProgram.h:257
Definition GLSLProgram.h:298
Definition Vertex.h:47
Definition GLSLProgram.h:232
Definition Vertex.h:112
Definition GLSLProgram.h:294
Definition GLSLProgram.h:270
Definition GLSLProgram.h:302
Definition Vertex.h:117