diff options
author | Fox Caminiti <fox@foxcam.net> | 2022-12-16 20:16:43 -0500 |
---|---|---|
committer | Fox Caminiti <fox@foxcam.net> | 2022-12-16 20:16:43 -0500 |
commit | bedd6906eabdd513042d6a178d4dc56a3a41d1d3 (patch) | |
tree | 2bcbd3e46ae61e583707a2ccc5b3f5cfeacb61a8 /src/gl_calls.cpp | |
parent | cdb9e1f7240cb0716b7d99df5e1fd7c3fc3407a8 (diff) |
v3, file/build organization
Diffstat (limited to 'src/gl_calls.cpp')
-rw-r--r-- | src/gl_calls.cpp | 268 |
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; +} |