diff options
Diffstat (limited to 'src/gl_calls.cpp')
-rw-r--r-- | src/gl_calls.cpp | 287 |
1 files changed, 253 insertions, 34 deletions
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp index 5d65100..39dba50 100644 --- a/src/gl_calls.cpp +++ b/src/gl_calls.cpp @@ -40,6 +40,7 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec2 TexCoord;\n" "uniform sampler2D Texture;\n" +"uniform sampler2D Texture1;\n" "uniform int FragmentMode;\n" "uniform vec3 InputCol;\n" "void main()\n" @@ -47,55 +48,137 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n" "vec4 Col = texture(Texture, TexCoord);\n" " if (FragmentMode == 0) {\n" " FragColor = Col;\n" -"} else {\n" +"} else if (FragmentMode == 1) {\n" " FragColor = vec4(InputCol, Col.a);\n" +"} else if (FragmentMode == 2) {\n" +" FragColor = Col;\n" +"} else {\n" +" vec4 Dest = texture(Texture1, TexCoord);\n" +" FragColor = Dest + Col;\n" +" FragColor = ((1.0f - Dest * 2) * Col * Col) + (Dest * 2 * Col);\n" +" FragColor.a = Col.a;\n" "}\n" "}\0"; -static void GL_InitDefaultShader() { - DefaultVertexShader = glCreateShader(GL_VERTEX_SHADER); +#if 1 +const char *BlendVertexShaderSource = "#version 330 core\n" +"layout (location = 0) in vec2 Point;\n" +"layout (location = 1) in vec2 aTexCoord;\n" +"layout (location = 2) in vec2 aTexCoordBlend;\n" +"out vec2 TexCoord;\n" +"out vec2 TexCoordBlend;\n" +"uniform vec2 CompDimensions;\n" +"uniform vec2 ScreenDimensions;\n" +"uniform vec2 UIOffset;\n" +"uniform vec2 UIZoom;\n" +"void main()\n" +"{\n" +" vec2 GL_Space = Point * 2 - vec2(1.0f, 1.0f);\n" +" gl_Position = vec4(vec2(GL_Space.x, -GL_Space.y), 0.0f, 1.0);\n" +" TexCoord = aTexCoord;\n" +" TexCoordBlend = aTexCoordBlend;\n" +"}\0"; +#else +const char *BlendVertexShaderSource = "#version 330 core\n" +"layout (location = 0) in vec2 Point;\n" +"layout (location = 1) in vec2 aTexCoord;\n" +"layout (location = 2) in vec2 aTexCoordBlend;\n" +"out vec2 TexCoord;\n" +"out vec2 TexCoordBlend;\n" +"uniform vec2 CompDimensions;\n" +"uniform vec2 LayerDimensions;\n" +"uniform vec2 ScreenDimensions;\n" +"uniform vec2 Pos;\n" +"uniform vec2 UIOffset;\n" +"uniform vec2 UIZoom;\n" +"uniform vec2 Anchor;\n" +"uniform float Rad;\n" +"uniform float Scale;\n" +"void main()\n" +"{\n" +" vec2 XRotation = vec2(cos(Rad), sin(Rad));\n" +" vec2 YRotation = vec2(sin(Rad), -cos(Rad));\n" +" vec2 XAxis = (Point.x - (Anchor.x * LayerDimensions.x)) * Scale * XRotation;\n" +" vec2 YAxis = (Point.y - (Anchor.y * LayerDimensions.y)) * -Scale * YRotation;\n" +" vec2 CompPoint = Pos + vec2(XAxis + YAxis);\n" +" vec2 CompUV = CompPoint / CompDimensions;\n" +" vec2 ScreenPoint = UIOffset + (CompUV * UIZoom);\n" +" vec2 ScreenUV = ScreenPoint / ScreenDimensions;\n" +" vec2 GL_Space = ScreenUV * 2 - vec2(1.0f, 1.0f);\n" +" gl_Position = vec4(vec2(GL_Space.x, -GL_Space.y), 0.0f, 1.0);\n" +" TexCoord = aTexCoord;\n" +" TexCoordBlend = aTexCoordBlend;\n" +"}\0"; +#endif - glShaderSource(DefaultVertexShader, 1, &DefaultVertexShaderSource, NULL); - glCompileShader(DefaultVertexShader); +const char *BlendFragmentShaderSource = "#version 330 core\n" +"out vec4 FragColor;\n" +"in vec2 TexCoord;\n" +"in vec2 TexCoordBlend;\n" +"uniform sampler2D Texture;\n" +"uniform sampler2D Texture1;\n" +"uniform vec3 InputCol;\n" +"uniform float Rad;\n" +"void main()\n" +"{\n" +" float Rada = Rad;\n" +" vec2 XRotation = vec2(cos(Rada), sin(Rada));\n" +" vec2 YRotation = vec2(sin(Rada), -cos(Rada));\n" +" vec2 XAxis = (TexCoord.x - 0.5) * XRotation;\n" +" vec2 YAxis = (TexCoord.y - 0.5) * YRotation;\n" +" vec2 NewCoord = vec2(0.5, 0.5) + vec2(XAxis + YAxis);\n" +" vec4 Col = texture(Texture, TexCoord);\n" +" vec4 Dest = texture(Texture1, NewCoord);\n" +" FragColor = Dest + Col;\n" +" FragColor = ((1.0f - Dest * 2) * Col * Col) + (Dest * 2 * Col);\n" +" FragColor.a = Col.a;\n" +" FragColor = Col + Dest;\n" +"}\0"; + +static void GL_InitDefaultShader(uint32 *VertexShader, const char *VertexShaderSource, + uint32 *FragmentShader, const char *FragmentShaderSource, + uint32 *ShaderProgram) +{ + *VertexShader = glCreateShader(GL_VERTEX_SHADER); + + glShaderSource(*VertexShader, 1, &VertexShaderSource, NULL); + glCompileShader(*VertexShader); int success; char infoLog[512]; - glGetShaderiv(DefaultVertexShader, GL_COMPILE_STATUS, &success); + glGetShaderiv(*VertexShader, GL_COMPILE_STATUS, &success); if(!success) { - glGetShaderInfoLog(DefaultVertexShader, 512, NULL, infoLog); + glGetShaderInfoLog(*VertexShader, 512, NULL, infoLog); printf("Vertex shader fail:\n %s", infoLog); } - uint32 DefaultFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + *FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(DefaultFragmentShader, 1, &DefaultFragmentShaderSource, NULL); - glCompileShader(DefaultFragmentShader); + glShaderSource(*FragmentShader, 1, &FragmentShaderSource, NULL); + glCompileShader(*FragmentShader); - glGetShaderiv(DefaultFragmentShader, GL_COMPILE_STATUS, &success); + glGetShaderiv(*FragmentShader, GL_COMPILE_STATUS, &success); if(!success) { - glGetShaderInfoLog(DefaultFragmentShader, 512, NULL, infoLog); + glGetShaderInfoLog(*FragmentShader, 512, NULL, infoLog); printf("Fragment shader fail:\n %s", infoLog); } // Shader programs link both types of shaders together. - DefaultShaderProgram = glCreateProgram(); + *ShaderProgram = glCreateProgram(); - glAttachShader(DefaultShaderProgram, DefaultVertexShader); - glAttachShader(DefaultShaderProgram, DefaultFragmentShader); - glLinkProgram(DefaultShaderProgram); + glAttachShader(*ShaderProgram, *VertexShader); + glAttachShader(*ShaderProgram, *FragmentShader); + glLinkProgram(*ShaderProgram); - glGetProgramiv(DefaultShaderProgram, GL_LINK_STATUS, &success); + glGetProgramiv(*ShaderProgram, GL_LINK_STATUS, &success); if(!success) { - glGetProgramInfoLog(DefaultShaderProgram, 512, NULL, infoLog); + glGetProgramInfoLog(*ShaderProgram, 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() { @@ -225,31 +308,36 @@ GL_BlitStencil(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 } static void -GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, - layer_transforms T, int Width, int Height, int BytesPerPixel, +GL_RasterizeShape2(gl_effect_layer *TestM, gl_effect_layer *TestM2, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, + layer_transforms T, int Width, int Height, int BytesPerPixel, void *Bitmap, int L_Width, int L_Height,v4 StrokeCol, v4 FillCol, int RenderMode, int Vector, - ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom, int StencilLayer) + ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom, v2 BlendMin, v2 BlendMax, int StencilLayer) { int Uniform = 0; - Uniform = glGetUniformLocation(DefaultShaderProgram, "CompDimensions"); + uint32 ShaderProgram = DefaultShaderProgram; + if (RenderMode & gl_renderflag_blend) { + ShaderProgram = BlendShaderProgram; + glUseProgram(BlendShaderProgram); + } + Uniform = glGetUniformLocation(ShaderProgram, "CompDimensions"); glUniform2f(Uniform, Width, Height); - Uniform = glGetUniformLocation(DefaultShaderProgram, "LayerDimensions"); - glUniform2f(Uniform, L_Width, L_Height); - Uniform = glGetUniformLocation(DefaultShaderProgram, "ScreenDimensions"); + Uniform = glGetUniformLocation(ShaderProgram, "ScreenDimensions"); glUniform2f(Uniform, ViewportSize.x, ViewportSize.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "UIOffset"); + Uniform = glGetUniformLocation(ShaderProgram, "UIOffset"); glUniform2f(Uniform, UIPos.x, UIPos.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "UIZoom"); + Uniform = glGetUniformLocation(ShaderProgram, "UIZoom"); glUniform2f(Uniform, UIZoom.x, UIZoom.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "Pos"); + Uniform = glGetUniformLocation(ShaderProgram, "LayerDimensions"); + glUniform2f(Uniform, L_Width, L_Height); + Uniform = glGetUniformLocation(ShaderProgram, "Pos"); glUniform2f(Uniform, T.x, T.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "Anchor"); + Uniform = glGetUniformLocation(ShaderProgram, "Anchor"); glUniform2f(Uniform, T.ax, T.ay); real32 Rad = (T.rotation * (PI / 180)); - Uniform = glGetUniformLocation(DefaultShaderProgram, "Rad"); + Uniform = glGetUniformLocation(ShaderProgram, "Rad"); glUniform1f(Uniform, Rad); - Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale"); + Uniform = glGetUniformLocation(ShaderProgram, "Scale"); glUniform1f(Uniform, T.scale); // Concave shapes are fairly more costly than convex: we have to write to @@ -334,6 +422,80 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } + else if (RenderMode & gl_renderflag_texture) + { + GLuint Texture; + int InitialTex1 = 0; + if (RenderMode & gl_renderflag_blend) { + + glGenTextures(1, &Texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, Texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, Bitmap); + 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); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TestM2->FramebufferObject); + glBlitFramebuffer(0, 0, 2000, 2000, + 0, 0, 2000, 2000, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebuffer(GL_FRAMEBUFFER, TestM->FramebufferObject); + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &InitialTex1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, TestM2->Texture); + glUniform1i(glGetUniformLocation(BlendShaderProgram, "Texture"), 0); + glUniform1i(glGetUniformLocation(BlendShaderProgram, "Texture1"), 1); + } else { + glGenTextures(1, &Texture); + glBindTexture(GL_TEXTURE_2D, Texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, Bitmap); + 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); + } + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glBindVertexArray(ShapeVerts.VertexArrayObject); + glStencilFunc(GL_EQUAL, StencilLayer, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + int VertRowSize = 4; + if (!(RenderMode & gl_renderflag_blend)) { + Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode"); + glUniform1i(Uniform, 1); + Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode"); + glUniform1i(Uniform, 2); + } else { + VertRowSize = 6; + } + + glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject); + glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * VertRowSize * FillCount, FillData, GL_STATIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)(2 * sizeof(float))); + glEnableVertexAttribArray(1); + if (RenderMode & gl_renderflag_blend) { + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)(4 * sizeof(float))); + glEnableVertexAttribArray(2); + } + + glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount); + + if (RenderMode & gl_renderflag_blend) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, InitialTex1); + glUseProgram(DefaultShaderProgram); + } + glActiveTexture(GL_TEXTURE0); + glDeleteTextures(1, &Texture); + } else if (RenderMode & gl_renderflag_fill) { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -386,6 +548,57 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin } void +GL_UpdateTexture2(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample) +{ + glViewport(0, 0, Width, Height); + + // int err; + // err = glGetError(); Assert(err == 0); + + if (!Test->Initialized) { + GL_InitHWBuffer(Test); + } + + GLenum Target = GL_TEXTURE_2D; + if (Multisample) + Target = GL_TEXTURE_2D_MULTISAMPLE; + + + 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; + } + + glBindTexture(Target, Test->Texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); + 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); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)Test->Stencil_Renderbuffer ); + glRenderbufferStorage(GL_RENDERBUFFER, StencilDepth, Width, Height); + + glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Test->Texture, 0); + 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); +} + +void GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample) { glViewport(0, 0, Width, Height); @@ -438,9 +651,15 @@ GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, glRenderbufferStorage(GL_RENDERBUFFER, StencilDepth, Width, Height ); } + // glBindTexture(GL_TEXTURE_2D, Test->Texture); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, + // GL_UNSIGNED_BYTE, Data); + // glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Test->Color_Renderbuffer); + // glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RGBA, Test->Texture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, Test->Stencil_Renderbuffer); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |