summaryrefslogtreecommitdiff
path: root/code/gl_graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'code/gl_graphics.cpp')
-rw-r--r--code/gl_graphics.cpp458
1 files changed, 458 insertions, 0 deletions
diff --git a/code/gl_graphics.cpp b/code/gl_graphics.cpp
new file mode 100644
index 0000000..91730ec
--- /dev/null
+++ b/code/gl_graphics.cpp
@@ -0,0 +1,458 @@
+#include "gl_graphics.h"
+
+#define ATTR_COLOR 0x1 // 0001
+#define ATTR_TEX 0x2 // 0010
+
+// ============== Loading functions are not subject to change =================
+void LoadUniformInt(u32 SP, const char *Uniform, i32 Val)
+{
+ glUniform1i(glGetUniformLocation(SP, Uniform), Val);
+}
+
+void LoadUniformFloat(u32 SP, const char *Uniform, r32 Val)
+{
+ glUniform1f(glGetUniformLocation(SP, Uniform), Val);
+}
+
+void LoadUniformVec3(u32 SP, const char *Uniform, Vec3 Val)
+{
+ glUniform3f(glGetUniformLocation(SP, Uniform), Val.x, Val.y, Val.z);
+}
+
+void LoadUniformMat4(u32 SP, const char *Uniform, const r32 *Val)
+{
+ glUniformMatrix4fv(glGetUniformLocation(SP, Uniform), 1, GL_TRUE, Val);
+}
+
+u32 CreateVertexShader(const char *VertexShaderSource)
+{
+ u32 VertexShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
+ glCompileShader(VertexShader);
+
+ i32 Success;
+ char InfoLog[512];
+ glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &Success);
+ if (!Success)
+ {
+ glGetShaderInfoLog(VertexShader, 512, NULL, InfoLog);
+ // todo(talha): error logging
+ // vertex shader compilation failed
+ printf("================================\n");
+ printf("vertex shader compilation failed:\n%s\n", InfoLog);
+ }
+
+ return VertexShader;
+}
+
+u32 CreateFragmentShader(const char *FragmentShaderSource)
+{
+ u32 FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
+ glCompileShader(FragmentShader);
+
+ i32 Success;
+ char InfoLog[512];
+ glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Success);
+ if (!Success)
+ {
+ glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
+ // todo(talha): error logging
+ // fragment shader compilation failed
+ printf("================================\n");
+ printf("fragment shader compilation failed:\n%s\n", InfoLog);
+ }
+
+ return FragmentShader;
+}
+
+u32 CreateShaderProgram(unsigned int VertexShader, unsigned int FragmentShader)
+{
+ u32 ShaderProgram = glCreateProgram();
+
+ glAttachShader(ShaderProgram, VertexShader);
+ glAttachShader(ShaderProgram, FragmentShader);
+ glLinkProgram(ShaderProgram);
+
+ i32 Success;
+ char InfoLog[512];
+ glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
+ if (!Success)
+ {
+ glGetProgramInfoLog(ShaderProgram, 512, NULL, InfoLog);
+ // todo(talha): error logging
+ // program linking failed
+ printf("================================\n");
+ printf("program linking failed:\n%s\n", InfoLog);
+ }
+
+ glDeleteShader(VertexShader);
+ glDeleteShader(FragmentShader);
+
+ return ShaderProgram;
+}
+// ---------------------------------------------------------------------------
+
+
+u32 CreateTriangle(r32 vertices[], i32 sz)
+{
+ u32 VAO;
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+ // bind to setup triangle attributes
+
+ u32 VBO;
+ glGenBuffers(1, &VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, sz, vertices, GL_STATIC_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ // color attribute
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)(3*sizeof(r32)));
+ glEnableVertexAttribArray(1);
+
+ // unbind post setup
+ glBindVertexArray(0);
+
+ return VAO;
+}
+
+void DrawTriangle(u32 VAO)
+{
+ glBindVertexArray(VAO);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+}
+
+u32 CreateRectangle(r32 vertices[], i32 v_sz, u32 indices[], i32 i_sz)
+{
+ u32 VAO;
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+ // bind to setup triangle attributes
+
+ u32 VBO;
+ glGenBuffers(1, &VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, v_sz, vertices, GL_STATIC_DRAW);
+
+ u32 EBO;
+ glGenBuffers(1, &EBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, i_sz, indices, GL_STATIC_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ // color attribute
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)(3*sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+ // unbind post setup
+ glBindVertexArray(0);
+
+ return VAO;
+
+}
+
+BufferO CreateRectangleTextured(r32 vertices[], i32 v_sz, u32 indices[], i32 i_sz, u32 attr)
+{
+ /*
+ * This will setup options and buffer objects to create a rectangle based on a texture
+ * The actual assigning of a texture will happen outside of this function
+ * Call BindGlTexture/GenAndBindGlTexture for assigning textures
+ */
+ u32 VAO;
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+ // bind to setup triangle attributes
+
+ u32 VBO;
+ glGenBuffers(1, &VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, v_sz, vertices, GL_STATIC_DRAW);
+
+ u32 EBO;
+ glGenBuffers(1, &EBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, i_sz, indices, GL_STATIC_DRAW);
+
+ // default is 3 for position
+ u32 stride = 3;
+ i32 color_offset = 3;
+ i32 tex_offset = 3;
+ if (attr & ATTR_COLOR)
+ {
+ stride += 3;
+ tex_offset += 3;
+ }
+ if (attr & ATTR_TEX)
+ {
+ stride += 2;
+ }
+
+ u8 attr_pos = 1;
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ if (attr & ATTR_COLOR)
+ {
+ // color attribute
+ glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)(color_offset*sizeof(r32)));
+ glEnableVertexAttribArray(attr_pos);
+ attr_pos += 1;
+ }
+
+ if (attr & ATTR_TEX)
+ {
+ // texture attribute
+ glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)(tex_offset*sizeof(r32)));
+ glEnableVertexAttribArray(attr_pos);
+ }
+
+ // unbind post setup
+ glBindVertexArray(0);
+
+ BufferO BO = {0};
+ BO.VAO=VAO;
+ BO.VBO=VBO;
+ BO.EBO=EBO;
+
+ return BO;
+}
+
+void MakeRectangleTextured(BufferO *bo, r32 vertices[], i32 v_sz, u32 indices[], i32 i_sz, u32 attr)
+{
+ /*
+ * This will setup options and buffer objects to create a rectangle based on a texture
+ * The actual assigning of a texture will happen outside of this function
+ */
+ glGenVertexArrays(1, &bo->VAO);
+ glBindVertexArray(bo->VAO);
+ // bind to setup triangle attributes
+
+ glGenBuffers(1, &bo->VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, bo->VBO);
+ glBufferData(GL_ARRAY_BUFFER, v_sz, vertices, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &bo->EBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo->EBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, i_sz, indices, GL_STATIC_DRAW);
+
+ // default is 3 for position
+ u32 stride = 3;
+ i32 color_offset = 3;
+ i32 tex_offset = 3;
+ if (attr & ATTR_COLOR)
+ {
+ stride += 3;
+ tex_offset += 3;
+ }
+ if (attr & ATTR_TEX)
+ {
+ stride += 2;
+ }
+
+ u8 attr_pos = 1;
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ if (attr & ATTR_COLOR)
+ {
+ // color attribute
+ glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)(color_offset*sizeof(r32)));
+ glEnableVertexAttribArray(attr_pos);
+ attr_pos += 1;
+ }
+
+ if (attr & ATTR_TEX)
+ {
+ // texture attribute
+ glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, stride*sizeof(r32), (void*)(tex_offset*sizeof(r32)));
+ glEnableVertexAttribArray(attr_pos);
+ }
+
+ // unbind post setup
+ glBindVertexArray(0);
+}
+
+void DrawRectangle(u32 VAO)
+{
+ glBindVertexArray(VAO);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glBindVertexArray(0);
+}
+
+void DrawRectangleTextured(u32 VAO, u32 TexO)
+{
+ glBindTexture(GL_TEXTURE_2D, TexO);
+ glBindVertexArray(VAO);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glBindVertexArray(0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+BufferO CreateCube(r32 vertices[], i32 v_sz)
+{
+ u32 VAO;
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+ // bind to setup triangle attributes
+
+ u32 VBO;
+ glGenBuffers(1, &VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, v_sz, vertices, GL_STATIC_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ // normal attribute
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(r32), (void*)(3*sizeof(r32)));
+ glEnableVertexAttribArray(1);
+
+ // unbind post setup
+ glBindVertexArray(0);
+
+ BufferO BO = {0};
+ BO.VAO=VAO;
+ BO.VBO=VBO;
+
+ return BO;
+}
+
+BufferO CreateCubeTextured(r32 vertices[], i32 v_sz)
+{
+ /*
+ * This will setup options and buffer objects to create a rectangle based on a texture
+ * The actual assigning of a texture will happen outside of this function
+ */
+ u32 VAO;
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+ // bind to setup triangle attributes
+
+ u32 VBO;
+ glGenBuffers(1, &VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, v_sz, vertices, GL_STATIC_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ // normal attribute
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(r32), (void*)(3*sizeof(r32)));
+ glEnableVertexAttribArray(1);
+
+ // texture attribute
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(r32), (void*)(6*sizeof(r32)));
+ glEnableVertexAttribArray(2);
+
+ // unbind post setup
+ glBindVertexArray(0);
+
+ BufferO BO = {0};
+ BO.VAO=VAO;
+ BO.VBO=VBO;
+
+ return BO;
+}
+
+void DrawCube(u32 VAO)
+{
+ glBindVertexArray(VAO);
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+}
+
+
+GLint GetColorAttrib(u32 nrChannels)
+{
+ GLint color_attrib;
+ switch (nrChannels) {
+ case 1:
+ {
+ color_attrib = GL_RED;
+ } break;
+ case 3:
+ {
+ color_attrib = GL_RGB;
+ } break;
+ case 4:
+ {
+ color_attrib = GL_RGBA;
+ } break;
+ default:
+ {
+ assert(1 == 0);
+ break;
+ }
+ }
+
+ return color_attrib;
+}
+
+/*
+ * Defines texture loaded from a Texture2D object into opengl.
+ * Texture wrapping and filtering options are defined. Should they need be altered
+ * define a new function or change them inside. It depends on the art style, but
+ * I think it should remain the same for everything
+ *
+ * Parameters:
+ * 1. Texture2D Tex: Contains information about the loaded texture
+ * 2. u32 VAO: Contains the VertexArrayObject index for the VAO to attach the texture to
+ * 3. u32 *TexO: Pointer to a TextureObject. This needs to be adtivated by glActiveTexture
+ * in order to define texture properties
+ */
+void GenAndBindGlTexture(Texture2D Tex, u32 VAO, u32 *TexO)
+{
+ glBindVertexArray(VAO);
+
+ glGenTextures(1, TexO);
+ glBindTexture(GL_TEXTURE_2D, *TexO);
+
+ // defining texture wrapping options
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ GLint color_attrib = GetColorAttrib(Tex.nrChannels);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, color_attrib, Tex.width, Tex.height, 0, color_attrib, GL_UNSIGNED_BYTE, Tex.data);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ glBindVertexArray(0);
+}
+
+/*
+ * Similar to GenAndBindGlTexture but it only binds a texture object
+ * must be passed a generated tex_obj
+ */
+void BindGlTexture(Texture2D Tex, u32 VAO, u32 TexO)
+{
+ glBindVertexArray(VAO);
+
+ glBindTexture(GL_TEXTURE_2D, TexO);
+ // defining texture wrapping options
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ GLint color_attrib = GetColorAttrib(Tex.nrChannels);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, color_attrib, Tex.width, Tex.height, 0, color_attrib, GL_UNSIGNED_BYTE, Tex.data);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ glBindVertexArray(0);
+}