diff --git a/modules/game_shaders/item.frag b/modules/game_shaders/item.frag index ade31f15..8aaeed95 100644 --- a/modules/game_shaders/item.frag +++ b/modules/game_shaders/item.frag @@ -1,11 +1,11 @@ uniform float opacity; // painter opacity uniform vec4 color; // painter color uniform float time; // time in seconds since shader linkage -uniform sampler2D texture; // map texture +uniform sampler2D tex0; // map texture +varying vec2 texCoord; // map texture coords //uniform int itemId; // item id -varying vec2 textureCoords; // map texture coords void main() { - gl_FragColor = texture2D(texture, textureCoords); + gl_FragColor = texture2D(tex0, texCoord); } diff --git a/modules/game_shaders/map.frag b/modules/game_shaders/map.frag index 3dd5d822..ba9d5045 100644 --- a/modules/game_shaders/map.frag +++ b/modules/game_shaders/map.frag @@ -1,13 +1,13 @@ uniform float opacity; // painter opacity uniform vec4 color; // painter color uniform float time; // time in seconds since shader linkage -uniform sampler2D texture; // map texture -varying vec2 textureCoords; // map texture coords +uniform sampler2D tex0; // map texture +varying vec2 texCoord; // map texture coords //uniform vec4 awareArea; void main() { - gl_FragColor = texture2D(texture, textureCoords); + gl_FragColor = texture2D(tex0, texCoord); } /* diff --git a/modules/game_shaders/outfit.frag b/modules/game_shaders/outfit.frag index 31033ce5..869c69ec 100644 --- a/modules/game_shaders/outfit.frag +++ b/modules/game_shaders/outfit.frag @@ -2,9 +2,9 @@ uniform float opacity; // painter opacity uniform vec4 color; // painter color uniform float time; // time in seconds since shader linkage -uniform sampler2D texture; // outfit texture -varying vec2 textureCoords; // outfit texture coords -uniform sampler2D maskTexture; // outfit color mask +uniform sampler2D tex0; // outfit texture +uniform sampler2D tex1; // outfit color mask +varying vec2 texCoord; // outfit texture coords uniform vec4 headColor; uniform vec4 bodyColor; @@ -14,8 +14,8 @@ uniform vec4 feetColor; vec4 calcOutfitPixel() { - vec4 pixel = texture2D(texture, textureCoords); - vec4 maskColor = texture2D(maskTexture, textureCoords); + vec4 pixel = texture2D(tex0, texCoord); + vec4 maskColor = texture2D(tex1, texCoord); vec4 outColor = vec4(1.0, 1.0, 1.0, 1.0); if(maskColor.r > 0.1 && maskColor.g > 0.1) diff --git a/src/framework/graphics/coordsbuffer.h b/src/framework/graphics/coordsbuffer.h index 599891ef..442cac14 100644 --- a/src/framework/graphics/coordsbuffer.h +++ b/src/framework/graphics/coordsbuffer.h @@ -47,6 +47,11 @@ public: m_textureVertexBuffer.addRect(src); m_hardwareCached = false; } + void addQuad(const Rect& dest, const Rect& src) { + m_vertexBuffer.addQuad(dest); + m_textureVertexBuffer.addQuad(src); + m_hardwareCached = false; + } void addBoudingRect(const Rect& dest, int innerLineWidth); void addRepeatedRects(const Rect& dest, const Rect& src); diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index b5d19710..54a2a007 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -77,8 +77,10 @@ void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture, cons return; m_coordsBuffer.clear(); - m_coordsBuffer.addRect(dest, src); - drawTextureCoords(m_coordsBuffer, texture); + m_coordsBuffer.addQuad(dest, src); + PainterShaderProgramPtr& program = m_customProgram ? m_customProgram : m_drawTexturedProgram; + program->setTexture(texture); + drawProgram(program, m_coordsBuffer, PainterShaderProgram::TriangleStrip); } void Painter::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) diff --git a/src/framework/graphics/paintershaderprogram.cpp b/src/framework/graphics/paintershaderprogram.cpp index 3f53343e..f870a380 100644 --- a/src/framework/graphics/paintershaderprogram.cpp +++ b/src/framework/graphics/paintershaderprogram.cpp @@ -28,69 +28,99 @@ PainterShaderProgram::PainterShaderProgram() { - m_textures.fill(std::make_tuple(-1, 0)); m_startTime = g_clock.time(); + m_opacity = 1; + m_color = Color::white; + m_time = 0; m_lastTexture = -1; } bool PainterShaderProgram::link() { - bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord"); - bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord"); + m_startTime = g_clock.time(); + bindAttributeLocation(VERTEX_ATTR, "a_vertex"); + bindAttributeLocation(TEXCOORD_ATTR, "a_texCoord"); if(ShaderProgram::link()) { bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix"); - bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix"); + bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "texTransformMatrix"); bindUniformLocation(COLOR_UNIFORM, "color"); bindUniformLocation(OPACITY_UNIFORM, "opacity"); - bindUniformLocation(TEXTURE_UNIFORM, "texture"); bindUniformLocation(TIME_UNIFORM, "time"); + bindUniformLocation(TEX0_UNIFORM, "tex0"); + bindUniformLocation(TEX1_UNIFORM, "tex1"); + + bind(); + setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix); + setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, m_textureTransformMatrix); + setUniformValue(COLOR_UNIFORM, m_color); + setUniformValue(OPACITY_UNIFORM, m_opacity); + setUniformValue(TIME_UNIFORM, m_time); + setUniformValue(TEX0_UNIFORM, 0); + setUniformValue(TEX1_UNIFORM, 1); return true; } - m_startTime = g_clock.time(); return false; } void PainterShaderProgram::setProjectionMatrix(const Matrix3& projectionMatrix) { + if(projectionMatrix == m_projectionMatrix) + return; + bind(); setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix); + m_projectionMatrix = projectionMatrix; } void PainterShaderProgram::setColor(const Color& color) { + if(color == m_color) + return; + bind(); setUniformValue(COLOR_UNIFORM, color); + m_color = color; } void PainterShaderProgram::setOpacity(float opacity) { - bind(); - setUniformValue(OPACITY_UNIFORM, opacity); -} - -void PainterShaderProgram::setUniformTexture(int location, const TexturePtr& texture, int index) -{ - assert(index >= 0 && index <= 1); - - m_textures[index] = std::make_tuple(location, texture ? texture->getId() : 0); - m_lastTexture = std::max(m_lastTexture, index); -} - -void PainterShaderProgram::setTexture(const TexturePtr& texture) -{ - if(!texture) + if(m_opacity == opacity) return; bind(); - setUniformTexture(TEXTURE_UNIFORM, texture, 0); - setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, texture->getTransformMatrix()); + setUniformValue(OPACITY_UNIFORM, opacity); + m_opacity = opacity; +} + +void PainterShaderProgram::setTexture(const TexturePtr& texture, int index) +{ + assert(index >= 0 && index <= 1); + + if(m_textures[index] == texture) + return; + + m_textures[index] = texture; + m_lastTexture = std::max(m_lastTexture, index); + + if(texture && index == 0) { + const Matrix2& textureTransformMatrix = texture->getTransformMatrix(); + if(m_textureTransformMatrix != textureTransformMatrix) { + bind(); + setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix); + m_textureTransformMatrix = textureTransformMatrix; + } + } } void PainterShaderProgram::draw(CoordsBuffer& coordsBuffer, DrawMode drawMode) { bind(); - setUniformValue(TIME_UNIFORM, g_clock.timeElapsed(m_startTime)); + float time = g_clock.timeElapsed(m_startTime); + if(m_time != time) { + setUniformValue(TIME_UNIFORM, time); + m_time = time; + } int vertexCount = coordsBuffer.getVertexCount(); if(vertexCount == 0) @@ -99,37 +129,36 @@ void PainterShaderProgram::draw(CoordsBuffer& coordsBuffer, DrawMode drawMode) coordsBuffer.updateCaches(); bool hardwareCached = coordsBuffer.isHardwareCached(); - enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR); + enableAttributeArray(PainterShaderProgram::VERTEX_ATTR); if(hardwareCached) coordsBuffer.getHardwareVertexBuffer()->bind(); - setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, hardwareCached ? 0 : coordsBuffer.getVertexBuffer(), 2); + setAttributeArray(PainterShaderProgram::VERTEX_ATTR, hardwareCached ? 0 : coordsBuffer.getVertexBuffer(), 2); bool hasTexture = coordsBuffer.getTextureVertexCount() != 0; if(hasTexture) { - enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); + enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR); if(hardwareCached) coordsBuffer.getHardwareTextureVertexBuffer()->bind(); - setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, hardwareCached ? 0 : coordsBuffer.getTextureVertexBuffer(), 2); + setAttributeArray(PainterShaderProgram::TEXCOORD_ATTR, hardwareCached ? 0 : coordsBuffer.getTextureVertexBuffer(), 2); } if(hardwareCached) HardwareBuffer::unbind(HardwareBuffer::VertexBuffer); - for(int i=m_lastTexture;i>=0;--i) { - int location = std::get<0>(m_textures[i]); - uint id = std::get<1>(m_textures[i]); - setUniformValue(location, i); - - if(m_lastTexture > 0) - glActiveTexture(GL_TEXTURE0+i); - glBindTexture(GL_TEXTURE_2D, id); + if(m_lastTexture == 0) { + glBindTexture(GL_TEXTURE_2D, m_textures[0] ? m_textures[0]->getId() : 0); + } else { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_textures[1] ? m_textures[1]->getId() : 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_textures[0] ? m_textures[0]->getId() : 0); } glDrawArrays(drawMode, 0, vertexCount); - disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR); + disableAttributeArray(PainterShaderProgram::VERTEX_ATTR); if(hasTexture) - disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR); + disableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR); } diff --git a/src/framework/graphics/paintershaderprogram.h b/src/framework/graphics/paintershaderprogram.h index 14423932..d6d69db5 100644 --- a/src/framework/graphics/paintershaderprogram.h +++ b/src/framework/graphics/paintershaderprogram.h @@ -30,14 +30,17 @@ class PainterShaderProgram : public ShaderProgram { enum { - VERTEX_COORDS_ATTR = 0, - TEXTURE_COORDS_ATTR = 1, + VERTEX_ATTR = 0, + TEXCOORD_ATTR = 1, PROJECTION_MATRIX_UNIFORM = 0, TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1, COLOR_UNIFORM = 2, OPACITY_UNIFORM = 3, - TEXTURE_UNIFORM = 4, - TIME_UNIFORM = 5 + TIME_UNIFORM = 4, + TEX0_UNIFORM = 5, + TEX1_UNIFORM = 6, + //TEX2_UNIFORM = 7, + //TEX3_UNIFORM = 8, }; public: enum DrawMode { @@ -52,14 +55,20 @@ public: void setProjectionMatrix(const Matrix3& projectionMatrix); void setColor(const Color& color); void setOpacity(float opacity); - void setTexture(const TexturePtr& texture); + void setTexture(const TexturePtr& texture, int index = 0); void setUniformTexture(int location, const TexturePtr& texture, int index); void draw(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); private: DrawMode m_drawMode; float m_startTime; - std::array, 4> m_textures; + TexturePtr m_textures[2]; + + Color m_color; + float m_opacity; + Matrix3 m_projectionMatrix; + Matrix2 m_textureTransformMatrix; + float m_time; int m_lastTexture; }; diff --git a/src/framework/graphics/paintershadersources.h b/src/framework/graphics/paintershadersources.h index cbc74415..f313fd8e 100644 --- a/src/framework/graphics/paintershadersources.h +++ b/src/framework/graphics/paintershadersources.h @@ -20,15 +20,6 @@ * THE SOFTWARE. */ -const static int VERTEX_COORDS_ATTR = 0; -const static int TEXTURE_COORDS_ATTR = 1; - -const static int PROJECTION_MATRIX_UNIFORM = 0; -const static int TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1; -const static int COLOR_UNIFORM = 2; -const static int OPACITY_UNIFORM = 3; -const static int TEXTURE_UNIFORM = 4; - static const std::string glslMainVertexShader = "\n\ highp vec4 calculatePosition();\n\ void main() {\n\ @@ -36,21 +27,21 @@ static const std::string glslMainVertexShader = "\n\ }\n"; static const std::string glslMainWithTexCoordsVertexShader = "\n\ - attribute highp vec2 textureCoord;\n\ - uniform highp mat2 textureTransformMatrix;\n\ - varying highp vec2 textureCoords;\n\ + attribute highp vec2 a_texCoord;\n\ + uniform highp mat2 texTransformMatrix;\n\ + varying highp vec2 texCoord;\n\ highp vec4 calculatePosition();\n\ void main()\n\ {\n\ gl_Position = calculatePosition();\n\ - textureCoords = textureTransformMatrix * textureCoord;\n\ + texCoord = texTransformMatrix * a_texCoord;\n\ }\n"; static std::string glslPositionOnlyVertexShader = "\n\ - attribute highp vec2 vertexCoord;\n\ + attribute highp vec2 a_vertex;\n\ uniform highp mat3 projectionMatrix;\n\ highp vec4 calculatePosition() {\n\ - return vec4(projectionMatrix * vec3(vertexCoord.xy, 1), 1);\n\ + return vec4(projectionMatrix * vec3(a_vertex.xy, 1), 1);\n\ }\n"; static const std::string glslMainFragmentShader = "\n\ @@ -62,11 +53,11 @@ static const std::string glslMainFragmentShader = "\n\ }\n"; static const std::string glslTextureSrcFragmentShader = "\n\ - varying mediump vec2 textureCoords;\n\ + varying mediump vec2 texCoord;\n\ uniform lowp vec4 color;\n\ - uniform sampler2D texture;\n\ + uniform sampler2D tex0;\n\ lowp vec4 calculatePixel() {\n\ - return texture2D(texture, textureCoords) * color;\n\ + return texture2D(tex0, texCoord) * color;\n\ }\n"; static const std::string glslSolidColorFragmentShader = "\n\ diff --git a/src/framework/graphics/shaderprogram.cpp b/src/framework/graphics/shaderprogram.cpp index 515d69c3..abb1269a 100644 --- a/src/framework/graphics/shaderprogram.cpp +++ b/src/framework/graphics/shaderprogram.cpp @@ -109,8 +109,10 @@ bool ShaderProgram::bind() void ShaderProgram::release() { - m_currentProgram = 0; - glUseProgram(0); + if(m_currentProgram != 0) { + m_currentProgram = 0; + glUseProgram(0); + } } std::string ShaderProgram::log() diff --git a/src/framework/graphics/shaderprogram.h b/src/framework/graphics/shaderprogram.h index 2d3e1ed1..7a991caa 100644 --- a/src/framework/graphics/shaderprogram.h +++ b/src/framework/graphics/shaderprogram.h @@ -41,7 +41,7 @@ public: void removeAllShaders(); virtual bool link(); bool bind(); - void release(); + static void release(); std::string log(); void disableAttributeArray(int location) { glDisableVertexAttribArray(location); } diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index 7629ad2b..602fc0ec 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -46,7 +46,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int { m_size.resize(width, height); m_transformMatrix = { 1.0f/width, 0.0f, - 0.0f, 1.0f/height }; + 0.0f, 1.0f/height }; // gets max texture size supported by the driver static GLint maxTexSize = -1; diff --git a/src/framework/ui/uiframecounter.cpp b/src/framework/ui/uiframecounter.cpp index 390008a3..4d5f5c0b 100644 --- a/src/framework/ui/uiframecounter.cpp +++ b/src/framework/ui/uiframecounter.cpp @@ -44,6 +44,7 @@ void UIFrameCounter::drawSelf() m_fpsText = Fw::formatString("FPS: %d", m_frameCount); m_lastFrameTicks = g_clock.ticks(); m_frameCount = 0; + dump << m_fpsText; } m_frameCount++; diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index e6a69e34..9a433f1b 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -96,7 +96,6 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani outfitProgram->bindUniformLocation(BODY_COLOR_UNIFORM, "bodyColor"); outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor"); outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor"); - outfitProgram->bindUniformLocation(MASK_TEXTURE_UNIFORM, "maskTexture"); } int xPattern = 0, yPattern = 0, zPattern = 0; @@ -141,7 +140,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani int maskId = getSpriteId(w, h, 1, xPattern, yPattern, zPattern, animationPhase); maskTex = g_sprites.getSpriteTexture(maskId); } - outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1); + outfitProgram->setTexture(maskTex, 1); internalDraw(dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase); diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index 157f0950..f8a215b9 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -170,8 +170,8 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) itemProgram->bindUniformLocation(ITEM_ID_UNIFORM, "itemId"); } g_painter.setCustomProgram(itemProgram); - itemProgram->bind(); - itemProgram->setUniformValue(ITEM_ID_UNIFORM, (int)m_id); + //itemProgram->bind(); + //itemProgram->setUniformValue(ITEM_ID_UNIFORM, (int)m_id); // now we can draw the item internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase);