From 5ec386b35f5a561ab388b40abe2aa920ec1a8611 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 7 Dec 2011 21:43:12 -0200 Subject: [PATCH] bloom shader --- modules/shadertest.frag | 37 ++++++++- src/framework/graphics/coordsbuffer.cpp | 6 +- src/framework/graphics/coordsbuffer.h | 9 ++- src/framework/graphics/painter.cpp | 73 ++++++----------- src/framework/graphics/painter.h | 7 +- .../graphics/paintershaderprogram.cpp | 79 +++++++++++-------- src/framework/graphics/paintershaderprogram.h | 20 ++--- src/framework/graphics/shaderprogram.h | 2 +- src/framework/graphics/vertexarray.h | 2 +- src/otclient/core/map.cpp | 27 +------ 10 files changed, 136 insertions(+), 126 deletions(-) diff --git a/modules/shadertest.frag b/modules/shadertest.frag index 1a4f6e3e..fe3e74c6 100644 --- a/modules/shadertest.frag +++ b/modules/shadertest.frag @@ -1,5 +1,40 @@ uniform sampler2D texture; varying vec2 textureCoords; + +void main() +{ + vec4 sum = vec4(0); + vec2 texcoord = textureCoords; + int j; + int i; + + for( i= -4 ;i < 4; i++) + { + for (j = -3; j < 3; j++) + { + sum += texture2D(texture, texcoord + vec2(j, i)*0.004) * 0.25; + } + } + if (texture2D(texture, texcoord).r < 0.3) + { + gl_FragColor = sum*sum*0.012 + texture2D(texture, texcoord); + } + else + { + if (texture2D(texture, texcoord).r < 0.5) + { + gl_FragColor = sum*sum*0.009 + texture2D(texture, texcoord); + } + else + { + gl_FragColor = sum*sum*0.0075 + texture2D(texture, texcoord); + } + } +} + +/* +uniform sampler2D texture; +varying vec2 textureCoords; uniform vec4 color; uniform float opacity; @@ -35,7 +70,7 @@ void main (void) vec2 uv = textureCoords.st; gl_FragColor = PostFX(texture, uv, ticks) * opacity; } - +*/ /* uniform float opacity; vec4 calculatePixel(); diff --git a/src/framework/graphics/coordsbuffer.cpp b/src/framework/graphics/coordsbuffer.cpp index a3068aa9..1f59c682 100644 --- a/src/framework/graphics/coordsbuffer.cpp +++ b/src/framework/graphics/coordsbuffer.cpp @@ -27,7 +27,7 @@ void CoordsBuffer::clear() m_destRects.reset(); m_srcRects.reset(); m_textureCoords.clear(); - m_vertexCoords.clear(); + m_vertices.clear(); m_updateCache = true; } @@ -97,11 +97,11 @@ void CoordsBuffer::cacheVertexArrays() int numDestRects = m_destRects.size(); int numSrcRects = m_srcRects.size(); - m_vertexCoords.clear(); + m_vertices.clear(); m_textureCoords.clear(); for(int i=0;i m_destRects; DataBuffer m_srcRects; - VertexArray m_vertexCoords; + VertexArray m_vertices; VertexArray m_textureCoords; Boolean m_updateCache; }; diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index 313c58c9..c08eebb4 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -36,30 +36,15 @@ void Painter::init() setOpacity(255); setCompositionMode(CompositionMode_SourceOver); - PainterShaderProgramPtr program = PainterShaderProgramPtr(new PainterShaderProgram); - program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); - program->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader); - program->bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord"); - program->bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord"); - assert(program->link()); - program->bindUniformLocation(PainterShaderProgram::PROJECTION_MATRIX_UNIFORM, "projectionMatrix"); - program->bindUniformLocation(PainterShaderProgram::TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix"); - program->bindUniformLocation(PainterShaderProgram::COLOR_UNIFORM, "color"); - program->bindUniformLocation(PainterShaderProgram::OPACITY_UNIFORM, "opacity"); - program->bindUniformLocation(PainterShaderProgram::TEXTURE_UNIFORM, "texture"); - program->bindUniformLocation(PainterShaderProgram::TICKS_UNIFORM, "ticks"); - m_drawTexturedProgram = program; + m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram); + m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); + m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader); + assert(m_drawTexturedProgram->link()); - program = PainterShaderProgramPtr(new PainterShaderProgram); - program->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader); - program->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader); - program->bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord"); - assert(program->link()); - program->bindUniformLocation(PainterShaderProgram::PROJECTION_MATRIX_UNIFORM, "projectionMatrix"); - program->bindUniformLocation(PainterShaderProgram::COLOR_UNIFORM, "color"); - program->bindUniformLocation(PainterShaderProgram::OPACITY_UNIFORM, "opacity"); - program->bindUniformLocation(PainterShaderProgram::TICKS_UNIFORM, "ticks"); - m_drawSolidColorProgram = program; + m_drawSolidColorProgram = PainterShaderProgramPtr(new PainterShaderProgram); + m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader); + m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader); + assert(m_drawSolidColorProgram->link()); } void Painter::terminate() @@ -97,38 +82,23 @@ void Painter::updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis } } -void Painter::drawCoords(CoordsBuffer& coordsBuffer) +void Painter::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode) { coordsBuffer.cacheVertexArrays(); - - if(coordsBuffer.getVertexCount() < 3) + if(coordsBuffer.getVertexCount() == 0) return; - m_drawSolidColorProgram->prepareForDraw(); - m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix); - m_drawSolidColorProgram->setOpacity(m_currentOpacity); - m_drawSolidColorProgram->setColor(m_currentColor); - m_drawSolidColorProgram->setVertexCoords(coordsBuffer.getVertexCoords()); - m_drawSolidColorProgram->drawTriangles(coordsBuffer.getVertexCount()); - m_drawSolidColorProgram->releaseFromDraw(); + program->setProjectionMatrix(m_projectionMatrix); + program->setOpacity(m_currentOpacity); + program->setColor(m_currentColor); + program->draw(coordsBuffer, drawMode); } void Painter::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) { - coordsBuffer.cacheVertexArrays(); - - if(coordsBuffer.getVertexCount() < 3) - return; - - m_drawTexturedProgram->prepareForDraw(); - m_drawTexturedProgram->setProjectionMatrix(m_projectionMatrix); - m_drawTexturedProgram->setOpacity(m_currentOpacity); - m_drawTexturedProgram->setColor(m_currentColor); - m_drawTexturedProgram->setTexture(texture); - m_drawTexturedProgram->setVertexCoords(coordsBuffer.getVertexCoords()); - m_drawTexturedProgram->setTextureCoords(coordsBuffer.getTextureCoords()); - m_drawTexturedProgram->drawTriangles(coordsBuffer.getVertexCount()); - m_drawTexturedProgram->releaseFromDraw(); + PainterShaderProgramPtr program = m_customProgram ? m_customProgram : m_drawTexturedProgram; + program->setTexture(texture); + drawProgram(program, coordsBuffer); } void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture) @@ -163,7 +133,7 @@ void Painter::drawFilledRect(const Rect& dest) m_coordsBuffer.clear(); m_coordsBuffer.addRect(dest); - drawCoords(m_coordsBuffer); + drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram, m_coordsBuffer); } void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth) @@ -173,7 +143,12 @@ void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth) m_coordsBuffer.clear(); m_coordsBuffer.addBoudingRect(dest, innerLineWidth); - drawCoords(m_coordsBuffer); + drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram, m_coordsBuffer); +} + +void Painter::setCustomProgram(PainterShaderProgramPtr program) +{ + m_customProgram = program; } void Painter::setCompositionMode(Painter::CompositionMode compositionMode) diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index 73f75a67..87b570b4 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -26,6 +26,7 @@ #include "declarations.h" #include #include "coordsbuffer.h" +#include "paintershaderprogram.h" class Painter { @@ -40,9 +41,8 @@ public: void updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis = false); - void drawCoords(CoordsBuffer& coordsBuffer); + void drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode = PainterShaderProgram::Triangles); void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); - void drawTexturedRect(const Rect& dest, const TexturePtr& texture); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); @@ -55,6 +55,8 @@ public: void setOpacity(int opacity) { m_currentOpacity = opacity / 255.0f; } int getOpacity() { return m_currentOpacity * 255.0f; } + void setCustomProgram(PainterShaderProgramPtr program); + void releaseCustomProgram() { m_customProgram = nullptr; } void setCompositionMode(CompositionMode compositionMode); GLfloat *getProjectionMatrix() { return (GLfloat*)m_projectionMatrix; } @@ -62,6 +64,7 @@ public: private: PainterShaderProgramPtr m_drawTexturedProgram; PainterShaderProgramPtr m_drawSolidColorProgram; + PainterShaderProgramPtr m_customProgram; GLfloat m_projectionMatrix[3][3]; Color m_currentColor; GLfloat m_currentOpacity; diff --git a/src/framework/graphics/paintershaderprogram.cpp b/src/framework/graphics/paintershaderprogram.cpp index 99f50c1c..0d10f47e 100644 --- a/src/framework/graphics/paintershaderprogram.cpp +++ b/src/framework/graphics/paintershaderprogram.cpp @@ -26,13 +26,31 @@ #include "texturemanager.h" #include +bool PainterShaderProgram::link() +{ + bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord"); + bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord"); + if(ShaderProgram::link()) { + bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix"); + bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix"); + bindUniformLocation(COLOR_UNIFORM, "color"); + bindUniformLocation(OPACITY_UNIFORM, "opacity"); + bindUniformLocation(TEXTURE_UNIFORM, "texture"); + bindUniformLocation(TICKS_UNIFORM, "ticks"); + return true; + } + return false; +} + void PainterShaderProgram::setProjectionMatrix(float projectionMatrix[3][3]) { + bind(); setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix, true); } void PainterShaderProgram::setColor(const Color& color) { + bind(); setUniformValue(COLOR_UNIFORM, color.r() / 255.0f, color.g() / 255.0f, @@ -42,11 +60,15 @@ void PainterShaderProgram::setColor(const Color& color) void PainterShaderProgram::setOpacity(GLfloat opacity) { + bind(); setUniformValue(OPACITY_UNIFORM, opacity); } void PainterShaderProgram::setTexture(const TexturePtr& texture) { + if(!texture) + return; + float w = texture->getGlSize().width(); float h = texture->getGlSize().height(); @@ -55,52 +77,45 @@ void PainterShaderProgram::setTexture(const TexturePtr& texture) { 0.0f, 1.0f/h } }; + bind(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture->getId()); setUniformValue(TEXTURE_UNIFORM, 0); setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix, true); } -void PainterShaderProgram::setVertexCoords(const GLfloat *vertices) -{ - enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR); - setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, vertices, 2); -} - -void PainterShaderProgram::setTextureCoords(const GLfloat *textureCoords) -{ - enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); - setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, textureCoords, 2); - m_mustDisableTexCoordsArray = true; -} - -void PainterShaderProgram::prepareForDraw() +void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode) { assert(bind()); + setUniformValue(TICKS_UNIFORM, (GLfloat)g_clock.ticks()); -} -void PainterShaderProgram::drawTriangleStrip(int numVertices) -{ - glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices); -} + int numVertices = coordsBuffer.getVertexCount(); + if(numVertices == 0) + return; -void PainterShaderProgram::drawTriangles(int numVertices) -{ - glDrawArrays(GL_TRIANGLES, 0, numVertices); -} - -void PainterShaderProgram::releaseFromDraw() -{ - if(m_mustDisableTexCoordsArray) { - disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); - m_mustDisableTexCoordsArray = false; + bool mustDisableVertexArray = false; + if(coordsBuffer.getVertexCount() > 0) { + enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR); + setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, coordsBuffer.getVertices(), 2); + mustDisableVertexArray = true; } - if(m_mustDisableVertexArray) { + bool mustDisableTexCoordsArray = false; + if(coordsBuffer.getTextureCoords() > 0) { + enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); + setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, coordsBuffer.getTextureCoords(), 2); + mustDisableTexCoordsArray = true; + } + + glDrawArrays(drawMode, 0, numVertices); + + if(mustDisableVertexArray) disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR); - m_mustDisableVertexArray = false; - } + + if(mustDisableTexCoordsArray) + disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); //release(); } + diff --git a/src/framework/graphics/paintershaderprogram.h b/src/framework/graphics/paintershaderprogram.h index 89393961..9abdeb4d 100644 --- a/src/framework/graphics/paintershaderprogram.h +++ b/src/framework/graphics/paintershaderprogram.h @@ -24,10 +24,10 @@ #define PAINTERSHADER_H #include "shaderprogram.h" +#include "coordsbuffer.h" class PainterShaderProgram : public ShaderProgram { -public: enum { VERTEX_COORDS_ATTR = 0, TEXTURE_COORDS_ATTR = 1, @@ -38,22 +38,22 @@ public: TEXTURE_UNIFORM = 4, TICKS_UNIFORM = 5 }; +public: + enum DrawMode { + Triangles = GL_TRIANGLES, + TriangleStrip = GL_TRIANGLE_STRIP + }; + + bool link(); void setProjectionMatrix(GLfloat projectionMatrix[3][3]); void setColor(const Color& color); void setOpacity(GLfloat opacity); void setTexture(const TexturePtr& texture); - void setVertexCoords(const GLfloat *vertices); - void setTextureCoords(const GLfloat *textureCoords); - - void prepareForDraw(); - void drawTriangleStrip(int numVertices); - void drawTriangles(int numVertices); - void releaseFromDraw(); + void draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); private: - Boolean m_mustDisableVertexArray; - Boolean m_mustDisableTexCoordsArray; + DrawMode m_drawMode; }; #endif diff --git a/src/framework/graphics/shaderprogram.h b/src/framework/graphics/shaderprogram.h index b1096415..c09c0894 100644 --- a/src/framework/graphics/shaderprogram.h +++ b/src/framework/graphics/shaderprogram.h @@ -39,7 +39,7 @@ public: bool addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile); void removeShader(const ShaderPtr& shader); void removeAllShaders(); - bool link(); + virtual bool link(); bool bind(); void release(); std::string log(); diff --git a/src/framework/graphics/vertexarray.h b/src/framework/graphics/vertexarray.h index ce31ff34..b21cdf82 100644 --- a/src/framework/graphics/vertexarray.h +++ b/src/framework/graphics/vertexarray.h @@ -57,7 +57,7 @@ public: } void clear() { m_buffer.reset(); } - GLfloat *vertexArray() const { return m_buffer.data(); } + GLfloat *vertices() const { return m_buffer.data(); } int vertexCount() const { return m_buffer.size() / 2; } private: diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index 7ea70ccb..ea63e35e 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -48,15 +48,7 @@ void Map::draw(const Rect& rect) program = PainterShaderProgramPtr(new PainterShaderProgram); program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); program->addShaderFromSourceFile(Shader::Fragment, "/shadertest.frag"); - program->bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord"); - program->bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord"); assert(program->link()); - program->bindUniformLocation(PainterShaderProgram::PROJECTION_MATRIX_UNIFORM, "projectionMatrix"); - program->bindUniformLocation(PainterShaderProgram::TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix"); - program->bindUniformLocation(PainterShaderProgram::COLOR_UNIFORM, "color"); - program->bindUniformLocation(PainterShaderProgram::OPACITY_UNIFORM, "opacity"); - program->bindUniformLocation(PainterShaderProgram::TEXTURE_UNIFORM, "texture"); - program->bindUniformLocation(PainterShaderProgram::TICKS_UNIFORM, "ticks"); } g_painter.setColor(Fw::white); @@ -100,22 +92,11 @@ void Map::draw(const Rect& rect) m_framebuffer->release(); - //g_painter.setColor(Fw::white); - //m_framebuffer->draw(rect); - - CoordsBuffer coordsBuffer; - coordsBuffer.addRect(rect, Rect(0,0,m_framebuffer->getTexture()->getSize())); - coordsBuffer.cacheVertexArrays(); - program->prepareForDraw(); - program->setProjectionMatrix((GLfloat (*)[3])g_painter.getProjectionMatrix()); - program->setOpacity(1.0f); - program->setColor(Fw::white); - program->setTexture(m_framebuffer->getTexture()); - program->setVertexCoords(coordsBuffer.getVertexCoords()); - program->setTextureCoords(coordsBuffer.getTextureCoords()); - program->drawTriangles(coordsBuffer.getVertexCount()); - program->releaseFromDraw(); + g_painter.setCustomProgram(program); + g_painter.setColor(Fw::white); + m_framebuffer->draw(rect); + g_painter.releaseCustomProgram(); // calculate stretch factor float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS);