diff --git a/rainbow/CoreGl/CoreGl.h b/rainbow/CoreGl/CoreGl.h index 1339acb15..a14803bcd 100644 --- a/rainbow/CoreGl/CoreGl.h +++ b/rainbow/CoreGl/CoreGl.h @@ -16,45 +16,12 @@ 2 - Stencil clip 3 - Manual clip */ - -#ifdef flagLINUXGL -#define Time XTime -#define Font XFont -#define Display XDisplay -#define Picture XPicture -#define Screen XScreen -#define Window XWindow -#define Complex XComplex -#include -#include -#include -#include -#endif - -#include - -#ifdef flagWINGL -#include -#endif - -#include -#include -#ifdef flagLINUXGL -#include -#endif - -#ifdef flagLINUXGL -#undef Picture -#undef Time -#undef Font -#undef Display -#undef Screen -#undef Window -#undef Complex -#endif - +#include "Gl.h" #include +#include "Shaders.h" +#include "Fbo.h" + NAMESPACE_UPP struct FrameInfo { @@ -74,35 +41,11 @@ float GetFps(); #define IMAGEFILE #include -#include "Shaders.h" #include "Resources.brc" typedef Rect_ RectF; typedef Point_ PointF; -struct Fbo : Moveable -{ - GLuint texId; - GLuint fbId; - GLuint rbId; - GLenum status; - int width; - int height; - bool ready; - - bool Create(int width, int height, bool resize = false); - void Resize(int width, int height); - void Bind(); - void Unbind(); - void Clear(); - void BlitToScreen(); - void BlitTo(const Fbo& fbo); - String GetError(); - - Fbo() : width(0), height(0), ready(false) - {} -}; - #include "FontGl.h" #include "ResGl.h" diff --git a/rainbow/CoreGl/CoreGl.upp b/rainbow/CoreGl/CoreGl.upp index 0d03c2222..2f0c4ecd8 100644 --- a/rainbow/CoreGl/CoreGl.upp +++ b/rainbow/CoreGl/CoreGl.upp @@ -4,6 +4,7 @@ uses options(WIN32) "-D_WIN32 -DGLEW_STATIC"; file + Gl.h, CoreGl.h, FontGl.h, ResGl.h, @@ -40,6 +41,8 @@ file Resources readonly separator, Resources.cpp, Resources.brc, + Fbo.h, + Fbo.cpp, Shaders.h, Shaders.cpp, AlphaMag.vert, diff --git a/rainbow/CoreGl/Ctrl.cpp b/rainbow/CoreGl/Ctrl.cpp index a81e1d549..713c3b682 100644 --- a/rainbow/CoreGl/Ctrl.cpp +++ b/rainbow/CoreGl/Ctrl.cpp @@ -10,7 +10,6 @@ int Ctrl::Xbuttons; int Ctrl::Xbuttontime; Point Ctrl::Xbuttonpos; - void Ctrl::GuiPlatformConstruct() { cliptobounds = true; diff --git a/rainbow/CoreGl/Ctrl.h b/rainbow/CoreGl/Ctrl.h index f6db6f328..46372de06 100644 --- a/rainbow/CoreGl/Ctrl.h +++ b/rainbow/CoreGl/Ctrl.h @@ -46,7 +46,8 @@ public: static Console console; static Rect screenRect; - + static bool screenReady; + static void InitGl(); static void ExitGl(); static void EndSession(); diff --git a/rainbow/CoreGl/DrawOp.cpp b/rainbow/CoreGl/DrawOp.cpp index 2f948c84e..a5d1642e1 100644 --- a/rainbow/CoreGl/DrawOp.cpp +++ b/rainbow/CoreGl/DrawOp.cpp @@ -364,8 +364,8 @@ void SystemDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, con #endif } } - - glColor4ub(255, 255, 255, 255); + else + glColor4ub(255, 255, 255, 255); float vtx[12]; SetVtx(vtx, sx, sy, dx, dy); diff --git a/rainbow/CoreGl/DrawText.cpp b/rainbow/CoreGl/DrawText.cpp index 8f06ca7a8..ef2e03b0a 100644 --- a/rainbow/CoreGl/DrawText.cpp +++ b/rainbow/CoreGl/DrawText.cpp @@ -167,14 +167,14 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col int glowA = 1; #endif - alphaMagProg.Set("GlyphColor", ink.GetR() * ic, ink.GetG() * ic, ink.GetB() * ic, inkA * ic * ac); - alphaMagProg.Set("OutlineColor", outlineColor.GetR() * ic, outlineColor.GetG() * ic, outlineColor.GetB() * ic, outlineA * ic * ac); - alphaMagProg.Set("GlowColor", glowColor.GetR() * ic, glowColor.GetG() * ic, glowColor.GetB() * ic, glowA * ic * ac); - alphaMagProg.Set("Outline", outlineStrength > 0); //0.1 - 0.45 - alphaMagProg.Set("Glow", glowStrength > 0); //0.55 - 0.095 - alphaMagProg.Set("Shadow", false); - alphaMagProg.Set("OutlineCenter", outlineCenter); - alphaMagProg.Set("GlowCenter", glowCenter); + alphaMagProg.SetUniform("GlyphColor", ink.GetR() * ic, ink.GetG() * ic, ink.GetB() * ic, inkA * ic * ac); + alphaMagProg.SetUniform("OutlineColor", outlineColor.GetR() * ic, outlineColor.GetG() * ic, outlineColor.GetB() * ic, outlineA * ic * ac); + alphaMagProg.SetUniform("GlowColor", glowColor.GetR() * ic, glowColor.GetG() * ic, glowColor.GetB() * ic, glowA * ic * ac); + alphaMagProg.SetUniform("Outline", outlineStrength > 0); //0.1 - 0.45 + alphaMagProg.SetUniform("Glow", glowStrength > 0); //0.55 - 0.095 + alphaMagProg.SetUniform("Shadow", false); + alphaMagProg.SetUniform("OutlineCenter", outlineCenter); + alphaMagProg.SetUniform("GlowCenter", glowCenter); float xp = (float) x; float yp = (float) y; @@ -201,7 +201,7 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col { resources.Bind(fi.pages[ci.page], Resources::LINEAR_FILTERING); glActiveTexture(GL_TEXTURE0); - alphaMagProg.Set("Texture", 0); + alphaMagProg.SetUniform("Texture", 0); page = ci.page; } diff --git a/rainbow/CoreGl/Fbo.cpp b/rainbow/CoreGl/Fbo.cpp new file mode 100644 index 000000000..5febfa2bf --- /dev/null +++ b/rainbow/CoreGl/Fbo.cpp @@ -0,0 +1,103 @@ +#include "Fbo.h" + +NAMESPACE_UPP + +bool Fbo::Create(int width, int height, bool resize) +{ + this->width = width; + this->height = height; + + if(!resize) + { + glGenFramebuffers(1, &fbId); + glGenRenderbuffers(1, &rbId); + glGenTextures(1, &texId); + } + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId); + glBindTexture(GL_TEXTURE_2D, texId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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_GENERATE_MIPMAP, GL_FALSE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0); + + glBindRenderbuffer(GL_RENDERBUFFER, rbId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbId, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbId); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbId); + status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + ready = true; + + return status == GL_FRAMEBUFFER_COMPLETE; +} + +void Fbo::Resize(int width, int height) +{ + if(ready) + Create(width, height, true); +} + +void Fbo::Bind() +{ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId); +} + +void Fbo::Unbind() +{ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} + +void Fbo::Clear() +{ + glClearColor(0.f, 0.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +} + +void Fbo::BlitToScreen() +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); +} + +void Fbo::BlitTo(const Fbo& fbo) +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo.fbId); + glBlitFramebuffer(0, 0, width, height, 0, 0, fbo.width, fbo.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); +} + +void Fbo::Remove() +{ + glDeleteTextures(1, &texId); + glDeleteRenderbuffers(1, &rbId); + glDeleteFramebuffers(1, &fbId); +} + +String Fbo::GetError() +{ + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE: + return "Framebuffer complete"; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + return "Framebuffer incomplete attachment"; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + return "Framebuffer incomplete missing attachment"; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + return "Framebuffer incomplete draw buffer"; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + return "Framebuffer incomplete read buffer"; + case GL_FRAMEBUFFER_UNSUPPORTED: + return "Framebuffer unsupported"; + default: + return "Unknown error"; + } +} + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/rainbow/CoreGl/Fbo.h b/rainbow/CoreGl/Fbo.h new file mode 100644 index 000000000..97f341c9a --- /dev/null +++ b/rainbow/CoreGl/Fbo.h @@ -0,0 +1,36 @@ +#ifndef _CoreGl_Fbo_h_ +#define _CoreGl_Fbo_h_ + +#include +#include +#include "Gl.h" + +NAMESPACE_UPP + +struct Fbo : Moveable +{ + GLuint texId; + GLuint fbId; + GLuint rbId; + GLenum status; + int width; + int height; + bool ready; + + bool Create(int width, int height, bool resize = false); + void Resize(int width, int height); + void Bind(); + void Unbind(); + void Clear(); + void BlitToScreen(); + void BlitTo(const Fbo& fbo); + void Remove(); + String GetError(); + + Fbo() : width(0), height(0), ready(false) + {} +}; + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/CoreGl/Gl.h b/rainbow/CoreGl/Gl.h new file mode 100644 index 000000000..594db3c9e --- /dev/null +++ b/rainbow/CoreGl/Gl.h @@ -0,0 +1,40 @@ +#ifndef _CoreGl_Gl_h_ +#define _CoreGl_Gl_h_ + +#ifdef flagLINUXGL +#define Time XTime +#define Font XFont +#define Display XDisplay +#define Picture XPicture +#define Screen XScreen +#define Window XWindow +#define Complex XComplex +#include +#include +#include +#include +#endif + +#include + +#ifdef flagWINGL +#include +#endif + +#include +#include +#ifdef flagLINUXGL +#include +#endif + +#ifdef flagLINUXGL +#undef Picture +#undef Time +#undef Font +#undef Display +#undef Screen +#undef Window +#undef Complex +#endif + +#endif diff --git a/rainbow/CoreGl/Resources.cpp b/rainbow/CoreGl/Resources.cpp index 3a134bd0b..a07a9ab50 100644 --- a/rainbow/CoreGl/Resources.cpp +++ b/rainbow/CoreGl/Resources.cpp @@ -295,97 +295,6 @@ OpenGLFont& Resources::GetFont(const Font& font, bool preload) tahomaNFontDef, (const byte**) tahomaNFontImg, tahomaNFontImg_length, tahomaNFontImg_count); } -bool Fbo::Create(int width, int height, bool resize) -{ - this->width = width; - this->height = height; - - if(!resize) - { - glGenFramebuffers(1, &fbId); - glGenRenderbuffers(1, &rbId); - glGenTextures(1, &texId); - } - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId); - glBindTexture(GL_TEXTURE_2D, texId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - 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_GENERATE_MIPMAP, GL_FALSE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0); - - glBindRenderbuffer(GL_RENDERBUFFER, rbId); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbId, 0); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbId); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbId); - status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - ready = true; - - return status == GL_FRAMEBUFFER_COMPLETE; -} - -void Fbo::Resize(int width, int height) -{ - if(ready) - Create(width, height, true); -} - -void Fbo::Bind() -{ - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbId); -} - -void Fbo::Unbind() -{ - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void Fbo::Clear() -{ - glClearColor(0.f, 0.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -} - -void Fbo::BlitToScreen() -{ - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); -} - -void Fbo::BlitTo(const Fbo& fbo) -{ - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbId); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo.fbId); - glBlitFramebuffer(0, 0, width, height, 0, 0, fbo.width, fbo.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); -} - -String Fbo::GetError() -{ - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE: - return "Framebuffer complete"; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - return "Framebuffer incomplete attachment"; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - return "Framebuffer incomplete missing attachment"; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - return "Framebuffer incomplete draw buffer"; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - return "Framebuffer incomplete read buffer"; - case GL_FRAMEBUFFER_UNSUPPORTED: - return "Framebuffer unsupported"; - default: - return "Unknown error"; - } -} - int64 GetHighTickCount() { #ifdef PLATFORM_WIN32 diff --git a/rainbow/CoreGl/Shaders.cpp b/rainbow/CoreGl/Shaders.cpp index 4ef315faa..210b3443c 100644 --- a/rainbow/CoreGl/Shaders.cpp +++ b/rainbow/CoreGl/Shaders.cpp @@ -1,7 +1,5 @@ #if defined(flagWINGL) || defined(flagLINUXGL) -#include - #include "Shaders.h" NAMESPACE_UPP @@ -13,7 +11,7 @@ void Shader::PrintShaderInfoLog(GLuint obj, const char* fileName) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infoLength); - if(infoLength > 1) + if(infoLength > 0) { char* info = new char[infoLength]; glGetShaderInfoLog(obj, infoLength, &charsWritten, info); @@ -34,7 +32,7 @@ void Shader::PrintProgramInfoLog(GLuint obj, const char* fileName) glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infoLength); - if(infoLength > 1) + if(infoLength > 0) { char* info = new char[infoLength]; glGetShaderInfoLog(obj, infoLength, &charsWritten, info); @@ -85,49 +83,82 @@ bool Shader::IsProgramLinked(int program) return result == GL_TRUE; } -int Shader::CompileProgram(const char* vs, const char* fs) +int Shader::CompileProgram(const char* vs, const char* fs, const char* gs) { vertSrc = vs; fragSrc = fs; + geomSrc = gs; const GLchar* vertexShaderSrc = (const GLchar*) vertSrc; const GLchar* fragmentShaderSrc = (const GLchar*) fragSrc; + const GLchar* geometryShaderSrc = (const GLchar*) geomSrc; DeleteFile("shader_vertex.log"); DeleteFile("shader_fragment.log"); + DeleteFile("shader_geometry.log"); DeleteFile("shader_link.log"); DeleteFile("shader_validation.log"); - GLenum vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL); - glCompileShader(vertexShader); + GLenum vertexShader = 0; + GLenum fragmentShader = 0; + GLenum geometryShader = 0; - if(!IsProgramCompiled(vertexShader)) + if(!vertSrc.IsEmpty()) { - PrintShaderInfoLog(vertexShader, "shader_vertex.log"); - error = "Vertex shader compilation error:\n\n" + compileError; - glDeleteShader(vertexShader); - return -1; + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL); + glCompileShader(vertexShader); + + if(!IsProgramCompiled(vertexShader)) + { + PrintShaderInfoLog(vertexShader, "shader_vertex.log"); + error = "Vertex shader compilation error:\n\n" + compileError; + glDeleteShader(vertexShader); + return -1; + } } - - GLenum fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL); - glCompileShader(fragmentShader); - - if(!IsProgramCompiled(fragmentShader)) + + if(!fragSrc.IsEmpty()) { - PrintShaderInfoLog(fragmentShader, "shader_fragment.log"); - error = "Fragment shader compilation error:\n\n" + compileError; - glDeleteShader(fragmentShader); - return -1; + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL); + glCompileShader(fragmentShader); + + if(!IsProgramCompiled(fragmentShader)) + { + PrintShaderInfoLog(fragmentShader, "shader_fragment.log"); + error = "Fragment shader compilation error:\n\n" + compileError; + glDeleteShader(fragmentShader); + return -1; + } + } + + if(!geomSrc.IsEmpty()) + { + geometryShader = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(geometryShader, 1, &geometryShaderSrc, NULL); + glCompileShader(geometryShader); + + if(!IsProgramCompiled(geometryShader)) + { + PrintShaderInfoLog(geometryShader, "shader_geometry.log"); + error = "Geometry shader compilation error:\n\n" + compileError; + glDeleteShader(geometryShader); + return -1; + } } program = glCreateProgram(); if(program > 0) { - glAttachShader(program, vertexShader); - glAttachShader(program, fragmentShader); + if(vertexShader > 0) + glAttachShader(program, vertexShader); + if(fragmentShader > 0) + glAttachShader(program, fragmentShader); + if(geometryShader > 0) + glAttachShader(program, geometryShader); + glLinkProgram(program); if(!IsProgramLinked(program)) { @@ -143,9 +174,9 @@ int Shader::CompileProgram(const char* vs, const char* fs) return program; } -int Shader::CompileProgram(const byte* vs, const byte* fs) +int Shader::CompileProgram(const byte* vs, const byte* fs, const byte* gs) { - return CompileProgram((const char*) vs, (const char*) fs); + return CompileProgram((const char*) vs, (const char*) fs, (const char*) gs); } int Shader::GetProgram() @@ -173,49 +204,64 @@ int Shader::GetUniformId(const char* var) return uniforms[n]; } -void Shader::Set(const char* var, float v) +int Shader::GetAttributeId(const char* var) +{ + int n = attributes.Find(var); + if(n < 0) + { + int id = glGetAttribLocation(program, var); + CheckGLError(); + if(id >= 0) + attributes.Add(var, id); + return id; + } + else + return attributes[n]; +} + +void Shader::SetUniform(const char* var, float v) { int id = GetUniformId(var); if(id >= 0) glUniform1f(id, v); } -void Shader::Set(const char* var, bool v) +void Shader::SetUniform(const char* var, bool v) { int id = GetUniformId(var); if(id >= 0) glUniform1i(id, int(v)); } -void Shader::Set(const char* var, int v) +void Shader::SetUniform(const char* var, int v) { int id = GetUniformId(var); if(id >= 0) glUniform1i(id, v); } -void Shader::Set(const char* var, float v0, float v1) +void Shader::SetUniform(const char* var, float v0, float v1) { int id = GetUniformId(var); if(id >= 0) glUniform2f(id, v0, v1); } -void Shader::Set(const char* var, float v0, float v1, float v2) +void Shader::SetUniform(const char* var, float v0, float v1, float v2) { int id = GetUniformId(var); if(id >= 0) glUniform3f(id, v0, v1, v2); } -void Shader::Set(const char* var, float v0, float v1, float v2, float v3) +void Shader::SetUniform(const char* var, float v0, float v1, float v2, float v3) { int id = GetUniformId(var); if(id >= 0) glUniform4f(id, v0, v1, v2, v3); } -void Shader::Set(const char* var, float* v, int size, int count) +void Shader::SetUniform(const char* var, float* v, int size, int count) { int id = GetUniformId(var); if(id >= 0) @@ -225,7 +271,94 @@ void Shader::Set(const char* var, float* v, int size, int count) else if(size == 3) glUniform3fv(id, count, v); else if(size == 4) - glUniform4fv(id, count, v); + glUniform4fv(id, count, v); + else if(size == 16) + glUniformMatrix4fv(id, count, GL_FALSE, v); + } +} + +void Shader::SetMatrixUniform(const char* var, float* v, int size, int count) +{ + int id = GetUniformId(var); + if(id >= 0) + { + if(size == 2) + glUniform2fv(id, count, v); + else if(size == 3) + glUniform3fv(id, count, v); + else if(size == 4) + glUniform4fv(id, count, v); + else if(size == 16) + glUniformMatrix4fv(id, count, GL_FALSE, v); + } +} + +void Shader::EnableAttribute(const char* var, bool b) +{ + int id = GetAttributeId(var); + if(id >= 0) + { + if(b) + glEnableVertexAttribArray(id); + else + glDisableVertexAttribArray(id); + } +} + +void Shader::DisableAttribute(const char* var) +{ + EnableAttribute(var, false); +} + +void Shader::DisableAllAtrributes() +{ + for(int i = 0; i < attributes.GetCount(); i++) + { + int id = attributes[i]; + if(id >= 0) + glDisableVertexAttribArray(id); + } +} + +void Shader::SetAttribute(const char* var, float v) +{ + int id = GetAttributeId(var); + if(id >= 0) + glVertexAttrib1f(id, v); +} + +void Shader::SetAttribute(const char* var, float v0, float v1) +{ + int id = GetAttributeId(var); + if(id >= 0) + glVertexAttrib2f(id, v0, v1); +} + +void Shader::SetAttribute(const char* var, float v0, float v1, float v2) +{ + int id = GetAttributeId(var); + if(id >= 0) + glVertexAttrib3f(id, v0, v1, v2); +} + +void Shader::SetAttribute(const char* var, float v0, float v1, float v2, float v3) +{ + int id = GetAttributeId(var); + if(id >= 0) + glVertexAttrib4f(id, v0, v1, v2, v3); +} + +void Shader::SetAttribute(const char* var, float* v, int size) +{ + int id = GetAttributeId(var); + if(id >= 0) + { + if(size == 2) + glVertexAttrib2fv(id, v); + else if(size == 3) + glVertexAttrib3fv(id, v); + else if(size == 4) + glVertexAttrib4fv(id, v); } } @@ -240,6 +373,12 @@ void Shader::Stop() glUseProgram(0); } +void Shader::Release() +{ + if(program >= 0) + glDeleteProgram(program); +} + Shader::Shader() : program(-1) {} diff --git a/rainbow/CoreGl/Shaders.h b/rainbow/CoreGl/Shaders.h index 3f6ca0990..b76230cae 100644 --- a/rainbow/CoreGl/Shaders.h +++ b/rainbow/CoreGl/Shaders.h @@ -1,6 +1,12 @@ #ifndef _CoreGl_Shaders_h_ #define _CoreGl_Shaders_h_ +#include +#include +#include "Gl.h" + +NAMESPACE_UPP + class Shader { private: @@ -9,7 +15,9 @@ private: String compileError; String fragSrc; String vertSrc; + String geomSrc; VectorMap uniforms; + VectorMap attributes; void PrintShaderInfoLog(GLuint obj, const char* fileName); void PrintProgramInfoLog(GLuint obj, const char* fileName); @@ -17,25 +25,41 @@ private: bool CheckGLError(); bool IsProgramCompiled(int program); bool IsProgramLinked(int program); - int GetUniformId(const char* var); public: + int GetUniformId(const char* var); + int GetAttributeId(const char* var); - int CompileProgram(const char* vs, const char* fs); - int CompileProgram(const byte* vs, const byte* fs); + int CompileProgram(const char* vs, const char* fs, const char* gs = NULL); + int CompileProgram(const byte* vs, const byte* fs, const byte* gs = NULL); int GetProgram(); - void Set(const char* var, float v); - void Set(const char* var, bool v); - void Set(const char* var, int v); - void Set(const char* var, float v0, float v1); - void Set(const char* var, float v0, float v1, float v2); - void Set(const char* var, float v0, float v1, float v2, float v3); - void Set(const char* var, float* v, int size, int count); + + void SetUniform(const char* var, float v); + void SetUniform(const char* var, bool v); + void SetUniform(const char* var, int v); + void SetUniform(const char* var, float v0, float v1); + void SetUniform(const char* var, float v0, float v1, float v2); + void SetUniform(const char* var, float v0, float v1, float v2, float v3); + void SetUniform(const char* var, float* v, int size, int count = 1); + void SetMatrixUniform(const char* var, float* v, int size, int count = 1); + + void EnableAttribute(const char* var, bool b = true); + void DisableAttribute(const char* var); + void DisableAllAtrributes(); + + void SetAttribute(const char* var, float v); + void SetAttribute(const char* var, float v0, float v1); + void SetAttribute(const char* var, float v0, float v1, float v2); + void SetAttribute(const char* var, float v0, float v1, float v2, float v3); + void SetAttribute(const char* var, float* v, int size); + void Start(); void Stop(); String GetError(); + void Release(); Shader(); }; +END_UPP_NAMESPACE #endif diff --git a/rainbow/CoreGl/Wnd.cpp b/rainbow/CoreGl/Wnd.cpp index 4de0b10c7..615bd1b46 100644 --- a/rainbow/CoreGl/Wnd.cpp +++ b/rainbow/CoreGl/Wnd.cpp @@ -18,6 +18,7 @@ float Ctrl::angle = 0.f; float Ctrl::scale = 1.f; float Ctrl::alpha = 255.f; Rect Ctrl::screenRect; +bool Ctrl::screenReady = false; Point Ctrl::glCursorPos = Null; Image Ctrl::glCursorImage; Rect Ctrl::glCaretRect; @@ -222,6 +223,7 @@ void Ctrl::DrawScreen() if(hRC) #endif if(desktop && !painting) { + screenReady = true; painting = true; resources.BindStatic(); int64 t0 = GetHighTickCount(); @@ -263,19 +265,19 @@ void Ctrl::DrawScreen() float blurSizeHorz = 1.f / (float) screenFbo0.width; float blurSizeVert = 1.f / (float) screenFbo0.height; blurProg.Start(); - blurProg.Set("blurSize", blurSizeHorz); - blurProg.Set("gaussian", gx, gy, gz); - blurProg.Set("blurMultiplyVec", 1, 0); - blurProg.Set("blurStrength", blur); - blurProg.Set("grayStrength", gray); + blurProg.SetUniform("blurSize", blurSizeHorz); + blurProg.SetUniform("gaussian", gx, gy, gz); + blurProg.SetUniform("blurMultiplyVec", 1, 0); + blurProg.SetUniform("blurStrength", blur); + blurProg.SetUniform("grayStrength", gray); screenFbo1.Bind(); draw.DrawTextureOp(drawRect, screenFbo0.texId, screenFbo0.width, screenFbo0.height, drawRect); screenFbo1.Unbind(); - blurProg.Set("blurSize", blurSizeVert); - blurProg.Set("blurMultiplyVec", 0, 1); - blurProg.Set("blurStrength", blur); - blurProg.Set("grayStrength", gray); + blurProg.SetUniform("blurSize", blurSizeVert); + blurProg.SetUniform("blurMultiplyVec", 0, 1); + blurProg.SetUniform("blurStrength", blur); + blurProg.SetUniform("grayStrength", gray); draw.ApplyTransforms(); draw.DrawTextureOp(drawRect, screenFbo1.texId, screenFbo1.width, screenFbo1.height, drawRect); blurProg.Stop();