#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; }