From 2fcaf2cc4017230c818530f837b2549fea47f6e9 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sat, 19 Jan 2013 13:44:27 -0200 Subject: [PATCH] Fix rotate,translate,rotate in ogl painters --- src/client/localplayer.cpp | 29 ++--------- src/framework/graphics/painter.cpp | 51 ++++++++++++------- src/framework/graphics/painter.h | 11 ++-- src/framework/graphics/painterogl1.cpp | 23 ++++++++- src/framework/graphics/painterogl1.h | 3 ++ .../graphics/painterogl2_shadersources.h | 2 +- 6 files changed, 70 insertions(+), 49 deletions(-) diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 74b82cf2..fdb9fe90 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -63,32 +63,11 @@ void LocalPlayer::draw(const Point& dest, float scaleFactor, bool animate, Light // This is a test to rotation, translate and scale transformations. /* - g_painter->saveAndResetState(); - g_painter->rotate(dest.x, dest.y, Fw::pi / 4.); + Point rotateOffset = dest; + rotateOffset += ((animate ? m_walkOffset : Point(0,0)) + Point(16,16)) * scaleFactor; + g_painter->rotate(rotateOffset, Fw::pi * std::sin(g_clock.millis()/1000.0f)); Creature::draw(dest, scaleFactor, animate, lightView); - g_painter->restoreSavedState(); - */ - - // This depends on rotation to get done. - // Textured arrow pointing to desired position. - /* - Position pos = Position(1029, 997, 7); - - int radius = 8; - double angle = m_position.getAngleFromPosition(pos); - if(angle < 0) { - radius = 0; - angle = 0; - } - - Point animationOffset = animate ? m_walkOffset : Point(0,0); - Point center = Point(dest + (animationOffset - getDisplacement() -8 + Otc::TILE_PIXELS)*scaleFactor); - g_painter->setColor(Color::red); - g_painter->drawFilledRect(Rect(center, Size(3, 3)*scaleFactor)); - center.x += radius * cos(angle); - center.y -= radius * sin(angle); - g_painter->setColor(Color::white); - g_painter->drawFilledRect(Rect(center, Size(3, 3)*scaleFactor)); + g_painter->resetTransformMatrix(); */ } diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index 84780824..38dcd80c 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -49,6 +49,7 @@ void Painter::resetState() resetShaderProgram(); resetTexture(); resetAlphaWriting(); + resetTransformMatrix(); } void Painter::refreshState() @@ -185,32 +186,44 @@ void Painter::setResolution(const Size& resolution) updateGlViewport(); } -void Painter::scale(double x, double y) +void Painter::scale(float x, float y) { - m_transformMatrix.data()[0] *= x; - m_transformMatrix.data()[4] *= y; + Matrix3 scaleMatrix = { + x, 0.0f, 0.0f, + 0.0f, y, 0.0f, + 0.0f, 0.0f, 1.0f + }; + + setTransformMatrix(m_transformMatrix * scaleMatrix.transposed()); +} + +void Painter::translate(float x, float y) +{ + Matrix3 translateMatrix = { + 1.0f, 0.0f, x, + 0.0f, 1.0f, y, + 0.0f, 0.0f, 1.0f + }; + + setTransformMatrix(m_transformMatrix * translateMatrix.transposed()); } -void Painter::translate(double x, double y) +void Painter::rotate(float angle) { - m_transformMatrix.data()[6] += x / m_resolution.width(); - m_transformMatrix.data()[7] -= y / m_resolution.height(); + Matrix3 rotationMatrix = { + std::cos(angle), -std::sin(angle), 0.0f, + std::sin(angle), std::cos(angle), 0.0f, + 0.0f, 0.0f, 1.0f + }; + + setTransformMatrix(m_transformMatrix * rotationMatrix.transposed()); } -void Painter::rotate(double x, double y, double angle) +void Painter::rotate(float x, float y, float angle) { - // TODO: use x, y vectors to properly rotate. - if(m_transformMatrix.data()[1] == 0) - m_transformMatrix.data()[1] = 1; - if(m_transformMatrix.data()[3] == 0) - m_transformMatrix.data()[3] = 1; - - double s = sin(angle); - double c = cos(angle); - m_transformMatrix.data()[0] *= c; - m_transformMatrix.data()[1] *= s; - m_transformMatrix.data()[3] *= -s; - m_transformMatrix.data()[4] *= c; + translate(-x, -y); + rotate(angle); + translate(x, y); } void Painter::updateGlTexture() diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index 68e11f97..52f96917 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -98,9 +98,13 @@ public: void setTexture(const TexturePtr& texture) { setTexture(texture.get()); } void setResolution(const Size& resolution); - void scale(double x, double y); - void translate(double x, double y); - void rotate(double x, double y, double angle); + void scale(float x, float y); + void scale(float factor) { scale(factor, factor); } + void translate(float x, float y); + void translate(const Point& p) { translate(p.x, p.y); } + void rotate(float angle); + void rotate(float x, float y, float angle); + void rotate(const Point& p, float angle) { rotate(p.x, p.y, angle); } Matrix3 getTransformMatrix() { return m_transformMatrix; } Matrix3 getProjectionMatrix() { return m_projectionMatrix; } @@ -120,6 +124,7 @@ public: void resetShaderProgram() { setShaderProgram(nullptr); } void resetTexture() { setTexture(nullptr); } void resetAlphaWriting() { setAlphaWriting(false); } + void resetTransformMatrix() { setTransformMatrix(Matrix3()); } virtual bool hasShaders() = 0; diff --git a/src/framework/graphics/painterogl1.cpp b/src/framework/graphics/painterogl1.cpp index dfcdb018..362698a0 100644 --- a/src/framework/graphics/painterogl1.cpp +++ b/src/framework/graphics/painterogl1.cpp @@ -38,6 +38,7 @@ void PainterOGL1::refreshState() Painter::refreshState(); updateGlColor(); updateGlMatrixMode(); + updateGlTransformMatrix(); updateGlProjectionMatrix(); updateGlTextureMatrix(); updateGlTextureState(); @@ -217,6 +218,13 @@ void PainterOGL1::setMatrixMode(PainterOGL1::MatrixMode matrixMode) updateGlMatrixMode(); } +void PainterOGL1::setTransformMatrix(const Matrix3& transformMatrix) +{ + m_transformMatrix = transformMatrix; + if(g_painter == this) + updateGlTransformMatrix(); +} + void PainterOGL1::setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; @@ -259,12 +267,25 @@ void PainterOGL1::updateGlMatrixMode() glMatrixMode(m_matrixMode); } +void PainterOGL1::updateGlTransformMatrix() +{ + float glTransformMatrix[] = { + m_transformMatrix(1,1), m_transformMatrix(1,2), 0.0f, m_transformMatrix(1,3), + m_transformMatrix(2,1), m_transformMatrix(2,2), 0.0f, m_transformMatrix(2,3), + 0.0f, 0.0f, 1.0f, 0.0f, + m_transformMatrix(3,1), m_transformMatrix(3,2), 0.0f, m_transformMatrix(3,3), + }; + + setMatrixMode(MatrixTransform); + glLoadMatrixf(glTransformMatrix); +} + void PainterOGL1::updateGlProjectionMatrix() { float glProjectionMatrix[] = { m_projectionMatrix(1,1), m_projectionMatrix(1,2), 0.0f, m_projectionMatrix(1,3), m_projectionMatrix(2,1), m_projectionMatrix(2,2), 0.0f, m_projectionMatrix(2,3), - 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, m_projectionMatrix(3,1), m_projectionMatrix(3,2), 0.0f, m_projectionMatrix(3,3), }; diff --git a/src/framework/graphics/painterogl1.h b/src/framework/graphics/painterogl1.h index 80c69d11..c8a2e7d9 100644 --- a/src/framework/graphics/painterogl1.h +++ b/src/framework/graphics/painterogl1.h @@ -39,6 +39,7 @@ public: enum MatrixMode { MatrixProjection = 0x1701, //GL_PROJECTION MatrixTexture = 0x1702, //GL_TEXTURE + MatrixTransform = 0x1700 // GL_MODELVIEW }; PainterOGL1(); @@ -58,6 +59,7 @@ public: void drawBoundingRect(const Rect& dest, int innerLineWidth); void setMatrixMode(MatrixMode matrixMode); + void setTransformMatrix(const Matrix3& projectionMatrix); void setProjectionMatrix(const Matrix3& projectionMatrix); void setTextureMatrix(const Matrix3& textureMatrix); void setColor(const Color& color); @@ -69,6 +71,7 @@ private: void updateGlColor(); void updateGlMatrixMode(); void updateGlProjectionMatrix(); + void updateGlTransformMatrix(); void updateGlTextureMatrix(); void updateGlTextureState(); diff --git a/src/framework/graphics/painterogl2_shadersources.h b/src/framework/graphics/painterogl2_shadersources.h index a51e5499..207da35d 100644 --- a/src/framework/graphics/painterogl2_shadersources.h +++ b/src/framework/graphics/painterogl2_shadersources.h @@ -45,7 +45,7 @@ static std::string glslPositionOnlyVertexShader = "\n\ uniform highp mat3 u_TransformMatrix;\n\ uniform highp mat3 u_ProjectionMatrix;\n\ highp vec4 calculatePosition() {\n\ - return vec4(u_TransformMatrix * u_ProjectionMatrix * vec3(a_Vertex.xy, 1.0), 1.0);\n\ + return vec4(u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0), 1.0);\n\ }\n"; static const std::string glslMainFragmentShader = "\n\