summaryrefslogtreecommitdiff
path: root/src/gl_calls.cpp
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-12-16 20:16:43 -0500
committerFox Caminiti <fox@foxcam.net>2022-12-16 20:16:43 -0500
commitbedd6906eabdd513042d6a178d4dc56a3a41d1d3 (patch)
tree2bcbd3e46ae61e583707a2ccc5b3f5cfeacb61a8 /src/gl_calls.cpp
parentcdb9e1f7240cb0716b7d99df5e1fd7c3fc3407a8 (diff)
v3, file/build organization
Diffstat (limited to 'src/gl_calls.cpp')
-rw-r--r--src/gl_calls.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
new file mode 100644
index 0000000..1cb408a
--- /dev/null
+++ b/src/gl_calls.cpp
@@ -0,0 +1,268 @@
+#include "gl_calls.h"
+
+const char *DefaultVertexShaderSource = "#version 330 core\n"
+"layout (location = 0) in vec3 aPos;\n"
+"layout (location = 1) in vec2 aTexCoord;\n"
+"out vec2 TexCoord;\n"
+"uniform int VertexMode;\n"
+"uniform vec3 CompDimensions;\n"
+"void main()\n"
+"{\n"
+" if (VertexMode == 0) {\n"
+" gl_Position = vec4(aPos, 1.0);\n"
+"} else {\n"
+" gl_Position = vec4(vec2(aPos.x / CompDimensions.x, aPos.y / CompDimensions.y) * 2 - 1.0f, 0.0f, 1.0);\n"
+"}\n"
+" TexCoord = aTexCoord;\n"
+"}\0";
+const char *DefaultFragmentShaderSource = "#version 330 core\n"
+"out vec4 FragColor;\n"
+"in vec2 TexCoord;\n"
+"uniform sampler2D Texture;\n"
+"uniform int FragmentMode;\n"
+"void main()\n"
+"{\n"
+"vec4 Col = texture(Texture, TexCoord);\n"
+" if (FragmentMode == 0) {\n"
+" FragColor = Col;\n"
+"} else {\n"
+" FragColor = vec4(vec3(1.0f), Col.a);\n"
+"}\n"
+"}\0";
+
+static void GL_InitDefaultShader() {
+ DefaultVertexShader = glCreateShader(GL_VERTEX_SHADER);
+
+ glShaderSource(DefaultVertexShader, 1, &DefaultVertexShaderSource, NULL);
+ glCompileShader(DefaultVertexShader);
+
+ int success;
+ char infoLog[512];
+ glGetShaderiv(DefaultVertexShader, GL_COMPILE_STATUS, &success);
+
+ if(!success)
+ {
+ glGetShaderInfoLog(DefaultVertexShader, 512, NULL, infoLog);
+ printf("Vertex shader fail:\n %s", infoLog);
+ }
+
+ uint32 DefaultFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ glShaderSource(DefaultFragmentShader, 1, &DefaultFragmentShaderSource, NULL);
+ glCompileShader(DefaultFragmentShader);
+
+ glGetShaderiv(DefaultFragmentShader, GL_COMPILE_STATUS, &success);
+
+ if(!success)
+ {
+ glGetShaderInfoLog(DefaultFragmentShader, 512, NULL, infoLog);
+ printf("Fragment shader fail:\n %s", infoLog);
+ }
+
+ // Shader programs link both types of shaders together.
+ DefaultShaderProgram = glCreateProgram();
+
+ glAttachShader(DefaultShaderProgram, DefaultVertexShader);
+ glAttachShader(DefaultShaderProgram, DefaultFragmentShader);
+ glLinkProgram(DefaultShaderProgram);
+
+ glGetProgramiv(DefaultShaderProgram, GL_LINK_STATUS, &success);
+ if(!success) {
+ glGetProgramInfoLog(DefaultShaderProgram, 512, NULL, infoLog);
+ printf("Shader linkage fail:\n %s", infoLog);
+ }
+
+ // Default vertex shader is still needed to link to other effects.
+ glDeleteShader(DefaultFragmentShader);
+}
+
+static void GL_InitDefaultVerts() {
+
+ unsigned int GLIndices[] = {
+ 0, 1, 3,
+ 1, 2, 3
+ };
+
+ // Indices!
+ glGenVertexArrays(1, &DefaultVerts.VertexArrayObject);
+
+ glGenBuffers(1, &DefaultVerts.ElementBufferObject);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, DefaultVerts.ElementBufferObject);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLIndices), GLIndices,
+ GL_STATIC_DRAW);
+ glGenBuffers(1, &DefaultVerts.VertexBufferObject);
+
+ // Our vertices need to be stored in this buffer.
+ glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ // texture coordinate (note the last parameter's offset)
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+}
+
+void
+GL_GenAndBindTexture(GLuint *GLTexture, int Width, int Height, int BytesPerPixel, void *BufferAddress)
+{
+ glGenTextures(1, GLTexture);
+ glBindTexture(GL_TEXTURE_2D, *GLTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16;
+ int ByteFlag2 = (BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ glTexImage2D(GL_TEXTURE_2D, 0, ByteFlag, Width, Height, 0, GL_RGBA, ByteFlag2, BufferAddress);
+}
+
+static void
+GL_BindDefaultVertexArrays()
+{
+ glBindVertexArray(DefaultVerts.VertexArrayObject);
+ // Switch to main buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, DefaultVerts.ElementBufferObject);
+ glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ // texture coordinate (note the last parameter's offset)
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+}
+
+void
+GL_InitHWBuffer(gl_effect_layer *Test)
+{
+ glGenFramebuffers(1, &Test->FramebufferObject);
+ glGenTextures(1, &Test->Texture);
+ glGenRenderbuffers(1, &Test->Color_Renderbuffer);
+ glGenRenderbuffers(1, &Test->Stencil_Renderbuffer);
+ Test->Initialized = true;
+}
+
+void
+GL_DeleteHWBuffer(gl_effect_layer *Test)
+{
+ glDeleteFramebuffers(1, &Test->FramebufferObject);
+ glDeleteTextures(1, &Test->Texture);
+ glDeleteRenderbuffers(1, &Test->Color_Renderbuffer);
+ glDeleteRenderbuffers(1, &Test->Stencil_Renderbuffer);
+ Test->Initialized = true;
+}
+
+void
+GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample)
+{
+ glViewport(0, 0, Width, Height);
+
+ if (!Test->Initialized) {
+ GL_InitHWBuffer(Test);
+ }
+
+ GLenum Target = GL_TEXTURE_2D;
+ if (Multisample)
+ Target = GL_TEXTURE_2D_MULTISAMPLE;
+
+ glBindTexture(Target, Test->Texture);
+
+ int Depth = 0, StencilDepth = 0;
+ if (BytesPerPixel == 4) {
+ Depth = GL_RGBA8;
+ StencilDepth = GL_STENCIL_INDEX8;
+ } else if (BytesPerPixel == 8) {
+ Depth = GL_RGBA16;
+ StencilDepth = GL_STENCIL_INDEX16;
+ }
+
+ if (Multisample) {
+ // glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, Width, Height, GL_TRUE);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, Test->Color_Renderbuffer);
+
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, Depth, Width, Height);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)Test->Stencil_Renderbuffer );
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, StencilDepth, Width, Height );
+ } else {
+ glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA,
+ // GL_UNSIGNED_BYTE, Data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, Test->Color_Renderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, Depth, Width, Height);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)Test->Stencil_Renderbuffer );
+ glRenderbufferStorage(GL_RENDERBUFFER, StencilDepth, Width, Height );
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Test->Color_Renderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, Test->Stencil_Renderbuffer);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("incomplete framebuffer");
+ Assert(0);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+static uint16
+Effect_GL_InitShader(const char *FragmentShaderEffectSource)
+{
+ glShaderSource(DefaultVertexShader, 1, &DefaultVertexShaderSource, NULL);
+ glCompileShader(DefaultVertexShader);
+
+ int success;
+ char infoLog[512];
+ glGetShaderiv(DefaultVertexShader, GL_COMPILE_STATUS, &success);
+
+ if(!success)
+ {
+ glGetShaderInfoLog(DefaultVertexShader, 512, NULL, infoLog);
+ printf("Vertex shader fail:\n %s", infoLog);
+ }
+
+ uint32 FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ glShaderSource(FragmentShader, 1, &FragmentShaderEffectSource, NULL);
+ glCompileShader(FragmentShader);
+
+ glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &success);
+
+ if(!success)
+ {
+ glGetShaderInfoLog(FragmentShader, 512, NULL, infoLog);
+ printf("Fragment shader fail:\n %s", infoLog);
+ }
+
+ uint16 ShaderProgram = glCreateProgram();
+
+ glAttachShader(ShaderProgram, DefaultVertexShader);
+ glAttachShader(ShaderProgram, FragmentShader);
+ glLinkProgram(ShaderProgram);
+
+ glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &success);
+ if(!success) {
+ glGetProgramInfoLog(ShaderProgram, 512, NULL, infoLog);
+ printf("Shader linkage fail:\n %s", infoLog);
+ }
+
+ glDeleteShader(FragmentShader);
+
+ glUseProgram(ShaderProgram);
+
+ return ShaderProgram;
+}