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" "void main()\n" "{\n" " gl_Position = vec4(aPos, 1.0);\n" " TexCoord = aTexCoord;\n" "}\0"; const char *MaskVertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec2 aTexCoord;\n" "out vec2 TexCoord;\n" "uniform vec3 CompDimensions;\n" "void main()\n" "{\n" " gl_Position = vec4(vec2(aPos.x / CompDimensions.x, aPos.y / CompDimensions.y) * 2 - 1.0f, 0.0f, 1.0);\n" " TexCoord = aTexCoord;\n" "}\0"; const char *DefaultFragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec2 TexCoord;\n" "uniform sampler2D Texture;\n" "void main()\n" "{\n" "vec4 ColTest = texture(Texture, TexCoord);\n" "ColTest.r += 0.5f;\n" "FragColor = ColTest;\n" "}\0"; #if 0 const char *fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec2 TexCoord;\n" "uniform float Start;\n" "uniform float Mid;\n" "uniform float End;\n" "uniform vec4 StartCol;\n" "uniform vec4 MidCol;\n" "uniform vec4 EndCol;\n" "uniform sampler2D ourTexture;\n" "void main()\n" "{\n" "vec4 OutCol = texture(ourTexture, TexCoord);\n" // individual channels "vec4 ColorI = pow(OutCol, MidCol);\n" "vec4 ValI = 1.0f / (EndCol - StartCol) * (ColorI - StartCol);\n" // global channel "vec4 ColorG = pow(ValI, vec4(Mid));\n" "vec4 ValG = 1.0f / (End - Start) * (ColorG - Start);\n" "FragColor = clamp(ValG, 0.0f, 1.0f);\n" "}\0"; const char *fragmentShaderSource = "#version 330 core\n" "uniform float Radius;\n" "uniform vec2 Direction;\n" "uniform sampler2D ourTexture;\n" "out vec4 FragColor;\n" "in vec2 TexCoord;\n" "\n" "vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {\n" " vec4 color = vec4(0.0f);\n" " float Omega = Radius / 3;\n" " float Divisor = 2*Omega*Omega;\n" " float A2 = 1.0f / (Omega * sqrt(2*3.141592));\n" " for (float Span = -round(Radius); Span < round(Radius); Span++) {\n" " float Dividend = -Span * Span;\n" " float Multiplier = A2 * exp(Dividend/Divisor);\n" " vec2 Dir = Span*direction;\n" " color += texture2D(image, uv + (Dir / resolution)) * Multiplier;\n" " }\n" " return color;\n" "}\n" "void main(void) {\n" " gl_FragColor = blur(ourTexture, TexCoord, vec2(1280, 720), Direction);\n" "}\0"; #endif static void TestGL_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); } uint32 MaskVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(MaskVertexShader, 1, &MaskVertexShaderSource, NULL); glCompileShader(MaskVertexShader); glGetShaderiv(MaskVertexShader, GL_COMPILE_STATUS, &success); if(!success) { glGetProgramInfoLog(DefaultShaderProgram, 512, NULL, infoLog); printf("Shader linkage fail:\n %s", infoLog); } MaskShaderProgram = glCreateProgram(); glAttachShader(MaskShaderProgram, MaskVertexShader); glAttachShader(MaskShaderProgram, DefaultFragmentShader); glLinkProgram(MaskShaderProgram); glGetProgramiv(MaskShaderProgram, GL_LINK_STATUS, &success); if(!success) { glGetProgramInfoLog(MaskShaderProgram, 512, NULL, infoLog); printf("Shader linkage fail:\n %s", infoLog); } // Default vertex shader is still needed to link to other effects. glDeleteShader(DefaultFragmentShader); glDeleteShader(MaskVertexShader); } static void TestGL_InitDefaultVerts() { unsigned int GLIndices[] = { 0, 1, 3, 1, 2, 3 }; glEnable(GL_MULTISAMPLE); // 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(DefaultVertices), 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 TestGL_InitTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height) { glGenTextures(1, &Test->Texture); glBindTexture(GL_TEXTURE_2D, Test->Texture); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glViewport(0, 0, Width, Height); glGenFramebuffers(1, &Test->FramebufferObject); glGenRenderbuffers(1, &Test->Color_Renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, Test->Color_Renderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, Width, Height); GLuint Stencil_Renderbuffer = 0; glGenRenderbuffers(1, &Stencil_Renderbuffer); glBindRenderbuffer( GL_RENDERBUFFER, (GLuint)Stencil_Renderbuffer ); glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 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, Stencil_Renderbuffer); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { printf("incomplete framebuffer"); Assert(0); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); glBindFramebuffer(GL_FRAMEBUFFER, 0); }