TazGraph Project v0.1.0
Loading...
Searching...
No Matches
GLSLProgram.h
1#pragma once
2
3#include "../pch.h"
4
5#include "./Vertex.h"
6
7#include "TextureManager/TextureManager.h"
8#include "ConsoleLogger.h"
9
10#define LINE_OFFSET 2
11#define SQUARE_OFFSET 4
12
13#define TRIANGLE_VERTICES 3
14#define QUAD_INDICES 6
15#define BOX_OFFSET 8
16
17#define TOTAL_MESHES 4
18
19#define TRIANGLE_MESH_IDX 0
20#define RECTANGLE_MESH_IDX 1
21#define BOX_MESH_IDX 2
22#define SPHERE_MESH_IDX 3
23
24#define TOTAL_LINE_MESHES 4
25
26#define LINE_MESH_IDX 0
27#define LINE_RECTANGLE_MESH_IDX 1
28#define LINE_BOX_MESH_IDX 2
29#define LINE_SPHERE_MESH_IDX 3
30
31
32constexpr int INDICES_LINE_OFFSET = LINE_OFFSET;
33constexpr int INDICES_SQUARE_OFFSET = 2 * SQUARE_OFFSET;
34constexpr int INDICES_BOX_OFFSET = 3 * BOX_OFFSET;
35
36constexpr int ARRAY_BOX_OFFSET = 36;
37
38static TazPosition triangleVertices[3] = {
39 { 0.0f, 0.5f, 0.0f }, // Top
40 { -0.5f, -0.5f, 0.0f }, // Bottom Left
41 { 0.5f, -0.5f, 0.0f } // Bottom Right
42};
43
44static GLuint triangleIndices[3] = {
45 0, 1, 2
46};
47
48static TazPosition quadVertices[4] = {
49 { -0.5f, 0.5f, 0.0f },
50 { -0.5f, -0.5f, 0.0f },
51 { 0.5f, -0.5f, 0.0f },
52 { 0.5f, 0.5f, 0.0f }
53};
54
55static TazUV uv_quadVertices[4] = {
56 {0.0f, 0.0f},
57 {1.0f, 0.0f},
58 {1.0f, 1.0f},
59 {0.0f, 1.0f}
60};
61
62static TazTexVertex tex_quadVertices[4] = {
63 { glm::vec3(-0.5f, 0.5f, 0.0f), glm::vec2(0.0f, 1.0f) }, // top-left
64 { glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec2(0.0f, 0.0f) }, // bottom-left
65 { glm::vec3(0.5f, -0.5f, 0.0f), glm::vec2(1.0f, 0.0f) }, // bottom-right
66 { glm::vec3(0.5f, 0.5f, 0.0f), glm::vec2(1.0f, 1.0f) } // top-right
67};
68
69static GLuint quadIndices[6] = {
70 0, 1, 2,
71 2, 3, 0
72};
73
74
75static GLuint quadWireframeIndices[] = {
76 0, 1, // bottom edge
77 1, 2, // right edge
78 2, 3, // top edge
79 3, 0 // left edge
80};
81
82static TazPosition cubeVertices[8] = {
83 { -0.5f, -0.5f, -0.5f },
84 { 0.5f, -0.5f, -0.5f },
85 { 0.5f, 0.5f, -0.5f },
86 { -0.5f, 0.5f, -0.5f },
87 { -0.5f, -0.5f, 0.5f },
88 { 0.5f, -0.5f, 0.5f },
89 { 0.5f, 0.5f, 0.5f },
90 { -0.5f, 0.5f, 0.5f }
91};
92
93static TazLightVertex light_cubeVertices[24] = {
94 // Front face
95 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
96 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
97 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
98 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f) },
99
100 // Back face
101 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
102 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
103 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
104 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f) },
105
106 // Left face
107 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
108 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
109 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
110 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f) },
111
112 // Right face
113 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
114 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
115 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
116 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f) },
117
118 // Bottom face
119 { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
120 { glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
121 { glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
122 { glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f) },
123
124 // Top face
125 { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
126 { glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
127 { glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f) },
128 { glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f) }
129};
130
131static GLuint cubeIndices[36] = {
132 0, 1, 2,
133 2, 3, 0,
134
135 // Back face (vertices 4-7)
136 4, 5, 6,
137 6, 7, 4,
138
139 // Left face (vertices 8-11)
140 8, 9,10,
141 10,11,8,
142
143 // Right face (vertices 12-15)
144 12,13,14,
145 14,15,12,
146
147 // Bottom face (vertices 16-19)
148 16,17,18,
149 18,19,16,
150
151 // Top face (vertices 20-23)
152 20,21,22,
153 22,23,20
154};
155
156static GLuint cubeWireframeIndices[] = {
157 // back face
158 0, 1, 1, 2, 2, 3, 3, 0,
159 // front face
160 4, 5, 5, 6, 6, 7, 7, 4,
161 // connecting edges
162 0, 4, 1, 5, 2, 6, 3, 7
163};
164
165
166static void generateSphereMesh(std::vector<TazPosition>& vertices, std::vector<GLuint>& indices,
167 float radius = 1.0f, unsigned int sectorCount = 36, unsigned int stackCount = 18) {
168 const float PI = 3.14159265359f;
169
170 vertices.clear();
171 indices.clear();
172
173 for (unsigned int i = 0; i <= stackCount; ++i) {
174 float stackAngle = PI / 2.0f - i * PI / stackCount; // from pi/2 to -pi/2
175 float xy = radius * cosf(stackAngle);
176 float z = radius * sinf(stackAngle);
177
178 for (unsigned int j = 0; j <= sectorCount; ++j) {
179 float sectorAngle = j * 2.0f * PI / sectorCount;
180
181 float x = xy * cosf(sectorAngle);
182 float y = xy * sinf(sectorAngle);
183 glm::vec3 pos(x, y, z);
184
185 vertices.push_back(pos);
186 }
187 }
188
189 for (unsigned int i = 0; i < stackCount; ++i) {
190 unsigned int k1 = i * (sectorCount + 1);
191 unsigned int k2 = k1 + sectorCount + 1;
192
193 for (unsigned int j = 0; j < sectorCount; ++j, ++k1, ++k2) {
194 if (i != 0) {
195 indices.push_back(k1);
196 indices.push_back(k2);
197 indices.push_back(k1 + 1);
198 }
199 if (i != (stackCount - 1)) {
200 indices.push_back(k1 + 1);
201 indices.push_back(k2);
202 indices.push_back(k2 + 1);
203 }
204 }
205 }
206}
207
208static void generateSphereMesh(std::vector<TazLightVertex>& vertices, std::vector<GLuint>& indices,
209 float radius = 1.0f, unsigned int sectorCount = 36, unsigned int stackCount = 18) {
210 const float PI = 3.14159265359f;
211
212 vertices.clear();
213 indices.clear();
214
215 for (unsigned int i = 0; i <= stackCount; ++i) {
216 float stackAngle = PI / 2.0f - i * PI / stackCount; // from pi/2 to -pi/2
217 float xy = radius * cosf(stackAngle);
218 float z = radius * sinf(stackAngle);
219
220 for (unsigned int j = 0; j <= sectorCount; ++j) {
221 float sectorAngle = j * 2.0f * PI / sectorCount;
222
223 float x = xy * cosf(sectorAngle);
224 float y = xy * sinf(sectorAngle);
225 glm::vec3 pos(x, y, z);
226
227 glm::vec3 normal = glm::normalize(pos);
228 vertices.push_back({ pos, normal });
229 }
230 }
231
232 for (unsigned int i = 0; i < stackCount; ++i) {
233 unsigned int k1 = i * (sectorCount + 1);
234 unsigned int k2 = k1 + sectorCount + 1;
235
236 for (unsigned int j = 0; j < sectorCount; ++j, ++k1, ++k2) {
237 if (i != 0) {
238 indices.push_back(k1);
239 indices.push_back(k2);
240 indices.push_back(k1 + 1);
241 }
242 if (i != (stackCount - 1)) {
243 indices.push_back(k1 + 1);
244 indices.push_back(k2);
245 indices.push_back(k2 + 1);
246 }
247 }
248 }
249}
250
251static void generateSphereMeshWireframe(
252 std::vector<TazPosition>& vertices,
253 std::vector<GLuint>& lineIndices,
254 float radius = 1.0f,
255 unsigned int sectorCount = 36,
256 unsigned int stackCount = 18)
257{
258 const float PI = 3.14159265359f;
259
260 vertices.clear();
261 lineIndices.clear();
262
263 for (unsigned int i = 0; i <= stackCount; ++i)
264 {
265 float stackAngle = PI / 2.0f - i * PI / stackCount;
266 float xy = radius * cosf(stackAngle);
267 float z = radius * sinf(stackAngle);
268
269 for (unsigned int j = 0; j <= sectorCount; ++j)
270 {
271 float sectorAngle = j * 2.0f * PI / sectorCount;
272
273 float x = xy * cosf(sectorAngle);
274 float y = xy * sinf(sectorAngle);
275
276 glm::vec3 pos(x, y, z);
277
278 vertices.push_back(pos);
279 }
280 }
281
282 for (unsigned int i = 0; i < stackCount; ++i)
283 {
284 unsigned int k1 = i * (sectorCount + 1);
285 unsigned int k2 = k1 + sectorCount + 1;
286
287 for (unsigned int j = 0; j < sectorCount; ++j, ++k1, ++k2)
288 {
289 if (i != 0)
290 {
291 // Wireframe lines for triangle 1
292 lineIndices.push_back(k1);
293 lineIndices.push_back(k2);
294
295 lineIndices.push_back(k2);
296 lineIndices.push_back(k1 + 1);
297
298 lineIndices.push_back(k1 + 1);
299 lineIndices.push_back(k1);
300 }
301
302 if (i != (stackCount - 1))
303 {
304 // Wireframe lines for triangle 2
305 lineIndices.push_back(k1 + 1);
306 lineIndices.push_back(k2);
307
308 lineIndices.push_back(k2);
309 lineIndices.push_back(k2 + 1);
310
311 lineIndices.push_back(k2 + 1);
312 lineIndices.push_back(k1 + 1);
313 }
314 }
315 }
316}
317
319
320 InstanceData() {}
321 InstanceData(glm::vec3 mSize, TazPosition mBodyCenter, TazRotation mRotation) :
322 size(mSize),
323 position(mBodyCenter),
324 rotation(mRotation)
325 {
326 }
327
328 InstanceData(glm::vec2 mSize, TazPosition mBodyCenter, TazRotation mRotation) :
329 size(glm::vec3(mSize, 0.0f)),
330 position(mBodyCenter),
331 rotation(mRotation)
332 {
333 }
334
335 ~InstanceData() {}
336
337 TazSize size = glm::vec3(0.0f);
338 TazPosition position = glm::vec3(0.0f);
339 TazRotation rotation = glm::vec3(0.0f);
340};
341
342
344
346 ColorInstanceData(glm::vec3 mSize, TazPosition mBodyCenter, TazRotation mRotation, TazColor mColor) : InstanceData(mSize, mBodyCenter, mRotation), color(mColor) {
347 }
348 ColorInstanceData(glm::vec2 mSize, TazPosition mBodyCenter, TazRotation mRotation, TazColor mColor) : InstanceData(mSize, mBodyCenter, mRotation), color(mColor) {
349 }
350
352
353 TazColor color = TazColor(255, 255, 255, 255);
354};
355
357
359 TextureInstanceData(glm::vec3 mSize, TazPosition mBodyCenter, TazRotation mRotation, GLuint Texture) : InstanceData(mSize, mBodyCenter, mRotation), texture(Texture) {
360 }
361 TextureInstanceData(glm::vec2 mSize, TazPosition mBodyCenter, TazRotation mRotation, GLuint Texture) : InstanceData(mSize, mBodyCenter, mRotation), texture(Texture) {
362 }
363
365
366 GLuint texture = 0;
367 TazUV uv = glm::vec2(0.0f);
368};
369
372 LineInstanceData(TazPosition mfromPos, TazPosition mtoPos, TazColor mfromcolor, TazColor mtocolor, float mwidth)
373 :
374 fromPos(mfromPos),
375 toPos(mtoPos),
376 fromColor(mfromcolor),
377 toColor(mtocolor),
378 width(mwidth)
379 {
380 }
381
383
384 TazPosition fromPos = glm::vec3(0.0f);
385 TazPosition toPos = glm::vec3(0.0f);
386 TazColor fromColor = TazColor(255, 255, 255, 255);
387 TazColor toColor = TazColor(255, 255, 255, 255);
388
389 float width = 10.0f;
390};
391
394 WireframeInstanceData(glm::vec3 mSize, TazPosition mBodyCenter, TazRotation mRotation, TazColor mColor, float mwidth)
395 : ColorInstanceData(mSize, mBodyCenter, mRotation, mColor), width(mwidth)
396 {
397
398 }
399 WireframeInstanceData(glm::vec2 mSize, TazPosition mBodyCenter, TazRotation mRotation, TazColor mColor, float mwidth)
400 : ColorInstanceData(mSize, mBodyCenter, mRotation, mColor), width(mwidth)
401 {
402
403 }
404
406
407 float width = 10.0f;
408};
409
411 size_t meshIndices = 0;
412
413 GLuint vao = 0;
414
415 //for static draws
416 GLuint vbo = 0;
417 GLuint ibo = 0;
418};
419
422 std::string shaderName; //todo: integrate it with renderers
423 std::string batchName; //todo: integrate it with renderers
424
425 std::vector<InstanceData> instances;
426};
427
429 std::string shaderName;
430 std::string batchName;
431
432 std::vector<ColorInstanceData> instances;
433};
434
435struct LineBatch {
436 std::string shaderName;
437 std::string batchName;
438
439 std::vector<LineInstanceData> instances;
440};
441
443 std::string shaderName;
444 std::string batchName;
445
446 std::vector<WireframeInstanceData> instances;
447};
448
450 std::string shaderName;
451 std::string batchName;
452
453 std::vector<TextureInstanceData> instances;
454};
455
459 std::vector< SimpleBatch> batches;
460};
461
463 std::vector< ColorBatch> batches;
464};
465
467 std::vector< LineBatch> batches;
468};
469
471 std::vector< WireFrameBatch> batches;
472};
473
475 std::vector< TextureBatch> batches;
476};
477
478
480public:
481 GLSLProgram() : _programID(0), _vertexShaderID(0), _geometryShaderID(0), _fragmentShaderID(0), _numAttributes(0)
482 {
483
484 }
485
486 ~GLSLProgram() {
487
488 }
489
490 // Vertex + Fragment
491 void compileAndLinkShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath) {
492 std::string vertSource = readShaderFile(vertexShaderFilePath);
493 std::string fragSource = readShaderFile(fragmentShaderFilePath);
494
495 compileAndLinkShadersFromSource(vertSource.c_str(), fragSource.c_str());
496 }
497
498 // Vertex + Geometry + Fragment
499 void compileAndLinkShaders(const std::string& vertexShaderFilePath, const std::string& geometryShaderFilePath, const std::string& fragmentShaderFilePath) {
500 std::string vertSource = readShaderFile(vertexShaderFilePath);
501 std::string geomSource = readShaderFile(geometryShaderFilePath);
502 std::string fragSource = readShaderFile(fragmentShaderFilePath);
503
504 compileAndLinkShadersFromSource(vertSource.c_str(), geomSource.c_str(), fragSource.c_str());
505 }
506
507 void compileAndLinkShadersFromSource(const char* vertexSource, const char* fragmentSource) {
508
509 std::vector<GLuint> shaderIDs;
510
511 shaderIDs.push_back(createAndCompileShader(vertexSource, GL_VERTEX_SHADER, "Vertex"));
512 shaderIDs.push_back(createAndCompileShader(fragmentSource, GL_FRAGMENT_SHADER, "Fragment"));
513
514 linkShadersInternal(shaderIDs);
515 }
516
517 void compileAndLinkShadersFromSource(const char* vertexSource, const char* geometrySource, const char* fragmentSource) {
518
519 std::vector<GLuint> shaderIDs;
520
521 shaderIDs.push_back(createAndCompileShader(vertexSource, GL_VERTEX_SHADER, "Vertex"));
522 shaderIDs.push_back(createAndCompileShader(geometrySource, GL_GEOMETRY_SHADER, "Geometry"));
523 shaderIDs.push_back(createAndCompileShader(fragmentSource, GL_FRAGMENT_SHADER, "Fragment"));
524
525 linkShadersInternal(shaderIDs);
526 }
527
528
529 void addAttribute(const std::string& attributeName) {
530 glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
531 }
532
533 GLint getUniformLocation(const std::string& uniformName) {
534 GLint location = glGetUniformLocation(_programID, uniformName.c_str());
535
536 if (location == GL_INVALID_INDEX) {
537 TAZ_ERROR("Uniform " + uniformName + " not found in shader!");
538 }
539 return location;
540 }
541
542 void use() {
543 glUseProgram(_programID);
544 for (int i = 0; i < _numAttributes; i++) {
545 glEnableVertexAttribArray(i);
546 }
547 }
548
549 void unuse() {
550 glUseProgram(0);
551 for (int i = 0; i < _numAttributes; i++) {
552 glDisableVertexAttribArray(i);
553 }
554 }
555
556 void dispose() {
557 if (_programID != 0) glDeleteProgram(_programID);
558 }
559
560 GLuint getProgramID() {
561 return _programID;
562 }
563
564private:
565 GLuint _programID;
566
567 GLuint _vertexShaderID;
568 GLuint _geometryShaderID;
569 GLuint _fragmentShaderID;
570
571 int _numAttributes;
572
573 std::string readShaderFile(const std::string& filePath) {
574 std::vector<unsigned char> buffer;
575 TextureManager::readFileToBuffer(filePath.c_str(), buffer);
576 return std::string(buffer.begin(), buffer.end());
577 }
578
579 GLuint createAndCompileShader(const std::string& source, GLenum shaderType, const std::string& typeName) {
580 GLuint shaderID = glCreateShader(shaderType);
581 if (shaderID == 0) {
582 TAZ_ERROR(typeName + " Shader Failed to create!");
583 return 0;
584 }
585
586 compileShader(source.c_str(), typeName, shaderID);
587 return shaderID;
588 }
589
590 void compileShader(const char* source, const std::string& name, GLuint id) {
591
592 glShaderSource(id, 1, &source, nullptr); //1 for number of strings
593
594 glCompileShader(id);
595
596 GLint success = 0;
597 glGetShaderiv(id, GL_COMPILE_STATUS, &success);
598
599 if (success == GL_FALSE)
600 {
601 GLint maxLength = 0;
602 glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
603
604 // The maxLength includes the NULL character
605 std::vector<GLchar> errorLog(maxLength);
606 glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
607
608 // Provide the infolog in whatever manor you deem best.
609 // Exit with failure.
610 glDeleteShader(id); // Don't leak the shader.
611
612 std::printf("%s\n", &(errorLog[0]));
613 TAZ_ERROR("Shader " + name + " failed to compile");
614
615 }
616 }
617
618 void linkShadersInternal(const std::vector<GLuint>& shaderIDs) {
619 _programID = glCreateProgram();
620
621 // Attach all shaders
622 for (GLuint shaderID : shaderIDs) {
623 glAttachShader(_programID, shaderID);
624 }
625
626 // Link program
627 glLinkProgram(_programID);
628
629 // Check link status
630 GLint isLinked = 0;
631 glGetProgramiv(_programID, GL_LINK_STATUS, &isLinked);
632
633 if (isLinked == GL_FALSE) {
634 GLint maxLength = 0;
635 glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);
636
637 std::vector<GLchar> errorLog(maxLength);
638 glGetProgramInfoLog(_programID, maxLength, &maxLength, &errorLog[0]);
639
640 // Cleanup on failure
641 glDeleteProgram(_programID);
642 for (GLuint shaderID : shaderIDs) {
643 glDeleteShader(shaderID);
644 }
645
646 std::printf("%s\n", &errorLog[0]);
647 TAZ_ERROR("Shaders failed to link");
648 return;
649 }
650
651 // Cleanup shaders after successful link
652 for (GLuint shaderID : shaderIDs) {
653 glDetachShader(_programID, shaderID);
654 glDeleteShader(shaderID);
655 }
656 }
657
658};
Definition GLSLProgram.h:479
Definition GLSLProgram.h:410
Definition GLSLProgram.h:428
Definition GLSLProgram.h:343
Definition GLSLProgram.h:462
Definition GLSLProgram.h:318
Definition GLSLProgram.h:435
Definition GLSLProgram.h:370
Definition GLSLProgram.h:466
Meshes.
Definition GLSLProgram.h:457
std::vector< SimpleBatch > batches
Batches.
Definition GLSLProgram.h:459
Batches.
Definition GLSLProgram.h:421
Definition Vertex.h:44
Definition Vertex.h:109
Definition Vertex.h:114
Definition GLSLProgram.h:449
Definition GLSLProgram.h:356
Definition GLSLProgram.h:474
Definition GLSLProgram.h:442
Definition GLSLProgram.h:392
Definition GLSLProgram.h:470