mirror of
https://github.com/edubart/otclient.git
synced 2025-10-16 20:43:26 +02:00
experimental map shaders
This commit is contained in:
@@ -16,12 +16,17 @@ IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
ENDIF()
|
||||
|
||||
# setup compiler options
|
||||
SET(CXX_WARNS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNS} -std=gnu++0x -pipe")
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(ARCH_FLAGS "-m64 -march=x86-64 -mtune=generic")
|
||||
ELSE()
|
||||
SET(ARCH_FLAGS "-m32 -march=i686 -mtune=generic")
|
||||
ENDIF()
|
||||
SET(WARNS_FLAGS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable")
|
||||
SET(SECURE_FLAGS "-fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNS} ${SECURE_FLAGS} ${ARCH_FLAGS} -std=gnu++0x -pipe")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -ggdb -fno-omit-frame-pointer")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
|
||||
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libgcc -static-libstdc++ -Wl,--as-needed")
|
||||
|
||||
@@ -222,8 +227,6 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/painterogl2.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/painterogl2.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/painterogl2_shadersources.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershadermanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershadermanager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/particleaffector.cpp
|
||||
|
@@ -201,10 +201,8 @@ void Application::run()
|
||||
}
|
||||
|
||||
if(redraw) {
|
||||
g_graphics.beginRender();
|
||||
|
||||
if(cacheForeground) {
|
||||
Rect viewportRect(0, 0, g_graphics.getViewportSize());
|
||||
Rect viewportRect(0, 0, g_painter->getResolution());
|
||||
|
||||
// draw the foreground into a texture
|
||||
if(updateForeground) {
|
||||
@@ -236,8 +234,6 @@ void Application::run()
|
||||
g_ui.render(Fw::BothPanes);
|
||||
}
|
||||
|
||||
g_graphics.endRender();
|
||||
|
||||
// update screen pixels
|
||||
g_window.swapBuffers();
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ void Font::load(const OTMLNodePtr& fontNode)
|
||||
|
||||
void Font::drawText(const std::string& text, const Point& startPos)
|
||||
{
|
||||
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
||||
Size boxSize = g_painter->getResolution() - startPos.toSize();
|
||||
Rect screenCoords(startPos, boxSize);
|
||||
drawText(text, screenCoords, Fw::AlignTopLeft);
|
||||
}
|
||||
|
@@ -86,22 +86,13 @@ void FrameBuffer::resize(const Size& size)
|
||||
void FrameBuffer::bind()
|
||||
{
|
||||
g_painter->saveAndResetState();
|
||||
|
||||
internalBind();
|
||||
|
||||
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
|
||||
0.0f, -2.0f/m_texture->getHeight(), 0.0f,
|
||||
-1.0f, 1.0f, 1.0f };
|
||||
g_painter->setProjectionMatrix(projectionMatrix);
|
||||
|
||||
m_oldViewportSize = g_graphics.getViewportSize();
|
||||
g_graphics.setViewportSize(m_texture->getSize());
|
||||
g_painter->setResolution(m_texture->getSize());
|
||||
}
|
||||
|
||||
void FrameBuffer::release()
|
||||
{
|
||||
internalRelease();
|
||||
g_graphics.setViewportSize(m_oldViewportSize);
|
||||
g_painter->restoreSavedState();
|
||||
}
|
||||
|
||||
|
@@ -195,51 +195,18 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
|
||||
|
||||
void Graphics::resize(const Size& size)
|
||||
{
|
||||
setViewportSize(size);
|
||||
|
||||
// The projection matrix converts from Painter's coordinate system to GL's coordinate system
|
||||
// * GL's viewport is 2x2, Painter's is width x height
|
||||
// * GL has +y -> -y going from bottom -> top, Painter is the other way round
|
||||
// * GL has [0,0] in the center, Painter has it in the top-left
|
||||
//
|
||||
// This results in the Projection matrix below.
|
||||
//
|
||||
// Projection Matrix
|
||||
// Painter Coord ------------------------------------------------ GL Coord
|
||||
// ------------- | 2.0 / width | 0.0 | 0.0 | ---------------
|
||||
// | x y 1 | * | 0.0 | -2.0 / height | 0.0 | = | x' y' 1 |
|
||||
// ------------- | -1.0 | 1.0 | 1.0 | ---------------
|
||||
// ------------------------------------------------
|
||||
Matrix3 projectionMatrix = { 2.0f/size.width(), 0.0f, 0.0f,
|
||||
0.0f, -2.0f/size.height(), 0.0f,
|
||||
-1.0f, 1.0f, 1.0f };
|
||||
|
||||
m_viewportSize = size;
|
||||
#ifdef PAINTER_OGL1
|
||||
if(g_painterOGL1)
|
||||
g_painterOGL1->setProjectionMatrix(projectionMatrix);
|
||||
g_painterOGL1->setResolution(size);
|
||||
#endif
|
||||
|
||||
#ifdef PAINTER_OGL2
|
||||
if(g_painterOGL2)
|
||||
g_painterOGL2->setProjectionMatrix(projectionMatrix);
|
||||
g_painterOGL2->setResolution(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Graphics::beginRender()
|
||||
{
|
||||
//g_painter->clear(Color::black);
|
||||
}
|
||||
|
||||
void Graphics::endRender()
|
||||
{
|
||||
}
|
||||
|
||||
void Graphics::setViewportSize(const Size& size)
|
||||
{
|
||||
glViewport(0, 0, size.width(), size.height());
|
||||
m_viewportSize = size;
|
||||
}
|
||||
|
||||
bool Graphics::canUseDrawArrays()
|
||||
{
|
||||
#ifdef OPENGL_ES
|
||||
|
@@ -46,8 +46,6 @@ public:
|
||||
PainterEngine getPainterEngine() { return m_selectedPainterEngine; }
|
||||
|
||||
void resize(const Size& size);
|
||||
void beginRender();
|
||||
void endRender();
|
||||
|
||||
void setViewportSize(const Size& size);
|
||||
|
||||
|
@@ -54,6 +54,7 @@ void Painter::refreshState()
|
||||
updateGlClipRect();
|
||||
updateGlTexture();
|
||||
updateGlAlphaWriting();
|
||||
updateGlViewport();
|
||||
}
|
||||
|
||||
void Painter::saveState()
|
||||
@@ -68,6 +69,7 @@ void Painter::saveState()
|
||||
m_olderStates[m_oldStateIndex].shaderProgram = m_shaderProgram;
|
||||
m_olderStates[m_oldStateIndex].texture = m_texture;
|
||||
m_olderStates[m_oldStateIndex].alphaWriting = m_alphaWriting;
|
||||
m_olderStates[m_oldStateIndex].resolution = m_resolution;
|
||||
m_oldStateIndex++;
|
||||
}
|
||||
|
||||
@@ -88,6 +90,7 @@ void Painter::restoreSavedState()
|
||||
setClipRect(m_olderStates[m_oldStateIndex].clipRect);
|
||||
setShaderProgram(m_olderStates[m_oldStateIndex].shaderProgram);
|
||||
setTexture(m_olderStates[m_oldStateIndex].texture);
|
||||
setResolution(m_olderStates[m_oldStateIndex].resolution);
|
||||
}
|
||||
|
||||
void Painter::clear(const Color& color)
|
||||
@@ -150,6 +153,36 @@ void Painter::setAlphaWriting(bool enable)
|
||||
updateGlAlphaWriting();
|
||||
}
|
||||
|
||||
void Painter::setResolution(const Size& resolution)
|
||||
{
|
||||
if(m_resolution == resolution)
|
||||
return;
|
||||
|
||||
|
||||
// The projection matrix converts from Painter's coordinate system to GL's coordinate system
|
||||
// * GL's viewport is 2x2, Painter's is width x height
|
||||
// * GL has +y -> -y going from bottom -> top, Painter is the other way round
|
||||
// * GL has [0,0] in the center, Painter has it in the top-left
|
||||
//
|
||||
// This results in the Projection matrix below.
|
||||
//
|
||||
// Projection Matrix
|
||||
// Painter Coord ------------------------------------------------ GL Coord
|
||||
// ------------- | 2.0 / width | 0.0 | 0.0 | ---------------
|
||||
// | x y 1 | * | 0.0 | -2.0 / height | 0.0 | = | x' y' 1 |
|
||||
// ------------- | -1.0 | 1.0 | 1.0 | ---------------
|
||||
|
||||
Matrix3 projectionMatrix = { 2.0f/resolution.width(), 0.0f, 0.0f,
|
||||
0.0f, -2.0f/resolution.height(), 0.0f,
|
||||
-1.0f, 1.0f, 1.0f };
|
||||
|
||||
m_resolution = resolution;
|
||||
|
||||
setProjectionMatrix(projectionMatrix);
|
||||
if(g_painter == this)
|
||||
updateGlViewport();
|
||||
}
|
||||
|
||||
void Painter::updateGlTexture()
|
||||
{
|
||||
if(m_glTextureId != 0)
|
||||
@@ -184,7 +217,7 @@ void Painter::updateGlClipRect()
|
||||
{
|
||||
if(m_clipRect.isValid()) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(m_clipRect.left(), g_graphics.getViewportSize().height() - m_clipRect.bottom() - 1, m_clipRect.width(), m_clipRect.height());
|
||||
glScissor(m_clipRect.left(), m_resolution.height() - m_clipRect.bottom() - 1, m_clipRect.width(), m_clipRect.height());
|
||||
} else {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
@@ -197,3 +230,8 @@ void Painter::updateGlAlphaWriting()
|
||||
else
|
||||
glColorMask(1,1,1,0);
|
||||
}
|
||||
|
||||
void Painter::updateGlViewport()
|
||||
{
|
||||
glViewport(0, 0, m_resolution.width(), m_resolution.height());
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ public:
|
||||
Texture *texture;
|
||||
PainterShaderProgram *shaderProgram;
|
||||
bool alphaWriting;
|
||||
Size resolution;
|
||||
};
|
||||
|
||||
Painter();
|
||||
@@ -91,6 +92,7 @@ public:
|
||||
|
||||
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram) { setShaderProgram(shaderProgram.get()); }
|
||||
void setTexture(const TexturePtr& texture) { setTexture(texture.get()); }
|
||||
void setResolution(const Size& resolution);
|
||||
|
||||
Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
|
||||
Matrix3 getTextureMatrix() { return m_textureMatrix; }
|
||||
@@ -100,6 +102,7 @@ public:
|
||||
Rect getClipRect() { return m_clipRect; }
|
||||
PainterShaderProgram *getShaderProgram() { return m_shaderProgram; }
|
||||
bool getAlphaWriting() { return m_alphaWriting; }
|
||||
Size getResolution() { return m_resolution; };
|
||||
|
||||
void resetColor() { setColor(Color::white); }
|
||||
void resetOpacity() { setOpacity(1.0f); }
|
||||
@@ -109,11 +112,14 @@ public:
|
||||
void resetTexture() { setTexture(nullptr); }
|
||||
void resetAlphaWriting() { setAlphaWriting(false); }
|
||||
|
||||
virtual bool hasShaders() = 0;
|
||||
|
||||
protected:
|
||||
void updateGlTexture();
|
||||
void updateGlCompositionMode();
|
||||
void updateGlClipRect();
|
||||
void updateGlAlphaWriting();
|
||||
void updateGlViewport();
|
||||
|
||||
CoordsBuffer m_coordsBuffer;
|
||||
|
||||
@@ -126,6 +132,7 @@ protected:
|
||||
Texture *m_texture;
|
||||
PainterShaderProgram *m_shaderProgram;
|
||||
bool m_alphaWriting;
|
||||
Size m_resolution;
|
||||
|
||||
PainterState m_olderStates[10];
|
||||
int m_oldStateIndex;
|
||||
|
@@ -62,6 +62,8 @@ public:
|
||||
void setColor(const Color& color);
|
||||
void setOpacity(float opacity);
|
||||
|
||||
bool hasShaders() { return false; }
|
||||
|
||||
private:
|
||||
void updateGlColor();
|
||||
void updateGlMatrixMode();
|
||||
|
@@ -22,7 +22,9 @@
|
||||
|
||||
#include "painterogl2.h"
|
||||
#include "texture.h"
|
||||
#include "paintershadermanager.h"
|
||||
#include "graphics.h"
|
||||
#include "painterogl2_shadersources.h"
|
||||
#include <framework/platform/platformwindow.h>
|
||||
|
||||
PainterOGL2 *g_painterOGL2 = nullptr;
|
||||
|
||||
@@ -31,12 +33,25 @@ PainterOGL2::PainterOGL2()
|
||||
m_drawProgram = nullptr;
|
||||
resetState();
|
||||
|
||||
g_shaders.init();
|
||||
m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
assert(m_drawTexturedProgram);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
|
||||
m_drawTexturedProgram->link();
|
||||
|
||||
m_drawSolidColorProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
assert(m_drawSolidColorProgram);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
|
||||
m_drawSolidColorProgram->link();
|
||||
|
||||
PainterShaderProgram::release();
|
||||
}
|
||||
|
||||
PainterOGL2::~PainterOGL2()
|
||||
{
|
||||
g_shaders.terminate();
|
||||
m_drawTexturedProgram = nullptr;
|
||||
m_drawSolidColorProgram = nullptr;
|
||||
}
|
||||
|
||||
void PainterOGL2::bind()
|
||||
@@ -71,10 +86,13 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||
// update shader with the current painter state
|
||||
m_drawProgram->bind();
|
||||
m_drawProgram->setProjectionMatrix(m_projectionMatrix);
|
||||
if(textured)
|
||||
if(textured) {
|
||||
m_drawProgram->setTextureMatrix(m_textureMatrix);
|
||||
m_drawProgram->bindMultiTextures();
|
||||
}
|
||||
m_drawProgram->setOpacity(m_opacity);
|
||||
m_drawProgram->setColor(m_color);
|
||||
m_drawProgram->setResolution(m_resolution);
|
||||
m_drawProgram->updateTime();
|
||||
|
||||
// update coords buffer hardware caches if enabled
|
||||
@@ -107,7 +125,7 @@ void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr
|
||||
if(texture->isEmpty())
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawTexturedProgram.get());
|
||||
setTexture(texture);
|
||||
drawCoords(coordsBuffer);
|
||||
}
|
||||
@@ -117,7 +135,7 @@ void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture,
|
||||
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawTexturedProgram.get());
|
||||
setTexture(texture);
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
@@ -130,7 +148,7 @@ void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& t
|
||||
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawTexturedProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawTexturedProgram.get());
|
||||
setTexture(texture);
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
@@ -143,7 +161,7 @@ void PainterOGL2::drawFilledRect(const Rect& dest)
|
||||
if(dest.isEmpty())
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawSolidColorProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get());
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addRect(dest);
|
||||
@@ -155,7 +173,7 @@ void PainterOGL2::drawFilledTriangle(const Point& a, const Point& b, const Point
|
||||
if(a == b || a == c || b == c)
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawSolidColorProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get());
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addTriangle(a, b, c);
|
||||
@@ -167,7 +185,7 @@ void PainterOGL2::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
||||
if(dest.isEmpty() || innerLineWidth == 0)
|
||||
return;
|
||||
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : g_shaders.getDrawSolidColorProgram().get());
|
||||
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get());
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
|
||||
|
@@ -51,8 +51,12 @@ public:
|
||||
|
||||
void setDrawProgram(PainterShaderProgram *drawProgram) { m_drawProgram = drawProgram; }
|
||||
|
||||
bool hasShaders() { return true; }
|
||||
|
||||
private:
|
||||
PainterShaderProgram *m_drawProgram;
|
||||
PainterShaderProgramPtr m_drawTexturedProgram;
|
||||
PainterShaderProgramPtr m_drawSolidColorProgram;
|
||||
};
|
||||
|
||||
extern PainterOGL2 *g_painterOGL2;
|
||||
|
@@ -27,42 +27,42 @@ static const std::string glslMainVertexShader = "\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslMainWithTexCoordsVertexShader = "\n\
|
||||
attribute highp vec2 a_texCoord;\n\
|
||||
uniform highp mat3 textureMatrix;\n\
|
||||
varying highp vec2 texCoord;\n\
|
||||
attribute highp vec2 a_TexCoord;\n\
|
||||
uniform highp mat3 u_TextureMatrix;\n\
|
||||
varying highp vec2 v_TexCoord;\n\
|
||||
highp vec4 calculatePosition();\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_Position = calculatePosition();\n\
|
||||
texCoord = (textureMatrix * vec3(a_texCoord,1)).xy;\n\
|
||||
v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1)).xy;\n\
|
||||
}\n";
|
||||
|
||||
static std::string glslPositionOnlyVertexShader = "\n\
|
||||
attribute highp vec2 a_vertex;\n\
|
||||
uniform highp mat3 projectionMatrix;\n\
|
||||
attribute highp vec2 a_Vertex;\n\
|
||||
uniform highp mat3 u_ProjectionMatrix;\n\
|
||||
highp vec4 calculatePosition() {\n\
|
||||
return vec4(projectionMatrix * vec3(a_vertex.xy, 1), 1);\n\
|
||||
return vec4(u_ProjectionMatrix * vec3(a_Vertex.xy, 1), 1);\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslMainFragmentShader = "\n\
|
||||
uniform lowp float opacity;\n\
|
||||
uniform lowp float u_Opacity;\n\
|
||||
lowp vec4 calculatePixel();\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_FragColor = calculatePixel();\n\
|
||||
gl_FragColor.a *= opacity;\n\
|
||||
gl_FragColor.a *= u_Opacity;\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslTextureSrcFragmentShader = "\n\
|
||||
varying mediump vec2 texCoord;\n\
|
||||
uniform lowp vec4 color;\n\
|
||||
uniform sampler2D tex0;\n\
|
||||
varying mediump vec2 v_TexCoord;\n\
|
||||
uniform lowp vec4 u_Color;\n\
|
||||
uniform sampler2D u_Tex0;\n\
|
||||
lowp vec4 calculatePixel() {\n\
|
||||
return texture2D(tex0, texCoord) * color;\n\
|
||||
return texture2D(u_Tex0, v_TexCoord) * u_Color;\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslSolidColorFragmentShader = "\n\
|
||||
uniform lowp vec4 color;\n\
|
||||
uniform lowp vec4 u_Color;\n\
|
||||
lowp vec4 calculatePixel() {\n\
|
||||
return color;\n\
|
||||
return u_Color;\n\
|
||||
}\n";
|
||||
|
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paintershadermanager.h"
|
||||
#include "painterogl2.h"
|
||||
#include "texture.h"
|
||||
#include "painterogl2_shadersources.h"
|
||||
#include "paintershaderprogram.h"
|
||||
#include "shaderprogram.h"
|
||||
#include "graphics.h"
|
||||
|
||||
PainterShaderManager g_shaders;
|
||||
|
||||
void PainterShaderManager::init()
|
||||
{
|
||||
m_drawTexturedProgram = createShader();
|
||||
assert(m_drawTexturedProgram);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
|
||||
m_drawTexturedProgram->link();
|
||||
|
||||
m_drawSolidColorProgram = createShader();
|
||||
assert(m_drawSolidColorProgram);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
|
||||
m_drawSolidColorProgram->link();
|
||||
|
||||
PainterShaderProgram::release();
|
||||
}
|
||||
|
||||
void PainterShaderManager::terminate()
|
||||
{
|
||||
m_drawTexturedProgram = nullptr;
|
||||
m_drawSolidColorProgram = nullptr;
|
||||
}
|
||||
|
||||
PainterShaderProgramPtr PainterShaderManager::createShader()
|
||||
{
|
||||
if(!g_graphics.canUseShaders())
|
||||
return nullptr;
|
||||
return PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
}
|
||||
|
||||
PainterShaderProgramPtr PainterShaderManager::createTexturedFragmentShader(const std::string& shaderFile)
|
||||
{
|
||||
PainterShaderProgramPtr shader = createShader();
|
||||
if(!shader)
|
||||
return nullptr;
|
||||
|
||||
shader->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
shader->addShaderFromSourceFile(Shader::Fragment, shaderFile);
|
||||
|
||||
if(!shader->link())
|
||||
return nullptr;
|
||||
|
||||
return shader;
|
||||
}
|
@@ -24,7 +24,9 @@
|
||||
#include "painter.h"
|
||||
#include "texture.h"
|
||||
#include "texturemanager.h"
|
||||
#include "graphics.h"
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/platform/platformwindow.h>
|
||||
|
||||
PainterShaderProgram::PainterShaderProgram()
|
||||
{
|
||||
@@ -34,28 +36,35 @@ PainterShaderProgram::PainterShaderProgram()
|
||||
m_time = 0;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setupUniforms()
|
||||
{
|
||||
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "u_ProjectionMatrix");
|
||||
bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "u_TextureMatrix");
|
||||
bindUniformLocation(COLOR_UNIFORM, "u_Color");
|
||||
bindUniformLocation(OPACITY_UNIFORM, "u_Opacity");
|
||||
bindUniformLocation(TIME_UNIFORM, "u_Time");
|
||||
bindUniformLocation(TEX0_UNIFORM, "u_Tex0");
|
||||
bindUniformLocation(TEX1_UNIFORM, "u_Tex1");
|
||||
bindUniformLocation(RESOLUTION_UNIFORM, "u_Resolution");
|
||||
|
||||
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
||||
setUniformValue(TEXTURE_MATRIX_UNIFORM, m_textureMatrix);
|
||||
setUniformValue(COLOR_UNIFORM, m_color);
|
||||
setUniformValue(OPACITY_UNIFORM, m_opacity);
|
||||
setUniformValue(TIME_UNIFORM, m_time);
|
||||
setUniformValue(TEX0_UNIFORM, 0);
|
||||
setUniformValue(TEX1_UNIFORM, 1);
|
||||
setUniformValue(RESOLUTION_UNIFORM, (float)m_resolution.width(), (float)m_resolution.height());
|
||||
}
|
||||
|
||||
bool PainterShaderProgram::link()
|
||||
{
|
||||
m_startTime = g_clock.seconds();
|
||||
bindAttributeLocation(VERTEX_ATTR, "a_vertex");
|
||||
bindAttributeLocation(TEXCOORD_ATTR, "a_texCoord");
|
||||
bindAttributeLocation(VERTEX_ATTR, "a_Vertex");
|
||||
bindAttributeLocation(TEXCOORD_ATTR, "a_TexCoord");
|
||||
if(ShaderProgram::link()) {
|
||||
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||
bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "textureMatrix");
|
||||
bindUniformLocation(COLOR_UNIFORM, "color");
|
||||
bindUniformLocation(OPACITY_UNIFORM, "opacity");
|
||||
bindUniformLocation(TIME_UNIFORM, "time");
|
||||
bindUniformLocation(TEX0_UNIFORM, "tex0");
|
||||
bindUniformLocation(TEX1_UNIFORM, "tex1");
|
||||
|
||||
bind();
|
||||
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
||||
setUniformValue(TEXTURE_MATRIX_UNIFORM, m_textureMatrix);
|
||||
setUniformValue(COLOR_UNIFORM, m_color);
|
||||
setUniformValue(OPACITY_UNIFORM, m_opacity);
|
||||
setUniformValue(TIME_UNIFORM, m_time);
|
||||
setUniformValue(TEX0_UNIFORM, 0);
|
||||
setUniformValue(TEX1_UNIFORM, 1);
|
||||
setupUniforms();
|
||||
release();
|
||||
return true;
|
||||
}
|
||||
@@ -102,6 +111,16 @@ void PainterShaderProgram::setOpacity(float opacity)
|
||||
m_opacity = opacity;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setResolution(const Size& resolution)
|
||||
{
|
||||
if(m_resolution == resolution)
|
||||
return;
|
||||
|
||||
bind();
|
||||
setUniformValue(RESOLUTION_UNIFORM, (float)resolution.width(), (float)resolution.height());
|
||||
m_resolution = resolution;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::updateTime()
|
||||
{
|
||||
float time = g_clock.seconds() - m_startTime;
|
||||
@@ -112,3 +131,32 @@ void PainterShaderProgram::updateTime()
|
||||
setUniformValue(TIME_UNIFORM, time);
|
||||
m_time = time;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::addMultiTexture(const std::string& file)
|
||||
{
|
||||
if(m_multiTextures.size() > 3)
|
||||
g_logger.error("cannot add more multi textures to shader, the max is 3");
|
||||
|
||||
TexturePtr texture = g_textures.getTexture(file);
|
||||
if(!texture)
|
||||
return;
|
||||
|
||||
texture->setSmooth(true);
|
||||
texture->setRepeat(true);
|
||||
|
||||
m_multiTextures.push_back(texture);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::bindMultiTextures()
|
||||
{
|
||||
if(m_multiTextures.size() == 0)
|
||||
return;
|
||||
|
||||
int i=1;
|
||||
for(const TexturePtr& tex : m_multiTextures) {
|
||||
glActiveTexture(GL_TEXTURE0 + 1);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->getId());
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
@@ -40,12 +40,13 @@ protected:
|
||||
TIME_UNIFORM = 4,
|
||||
TEX0_UNIFORM = 5,
|
||||
TEX1_UNIFORM = 6,
|
||||
//TEX2_UNIFORM = 7,
|
||||
//TEX3_UNIFORM = 8,
|
||||
RESOLUTION_UNIFORM = 7,
|
||||
};
|
||||
|
||||
friend class PainterOGL2;
|
||||
|
||||
virtual void setupUniforms();
|
||||
|
||||
public:
|
||||
PainterShaderProgram();
|
||||
|
||||
@@ -55,8 +56,12 @@ public:
|
||||
void setTextureMatrix(const Matrix3& textureMatrix);
|
||||
void setColor(const Color& color);
|
||||
void setOpacity(float opacity);
|
||||
void setResolution(const Size& resolution);
|
||||
void updateTime();
|
||||
|
||||
void addMultiTexture(const std::string& file);
|
||||
void bindMultiTextures();
|
||||
|
||||
private:
|
||||
float m_startTime;
|
||||
|
||||
@@ -64,7 +69,9 @@ private:
|
||||
float m_opacity;
|
||||
Matrix3 m_projectionMatrix;
|
||||
Matrix3 m_textureMatrix;
|
||||
Size m_resolution;
|
||||
float m_time;
|
||||
std::vector<TexturePtr> m_multiTextures;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -72,8 +72,12 @@ bool Shader::compileSourceCode(const std::string& sourceCode)
|
||||
|
||||
bool Shader::compileSourceFile(const std::string& sourceFile)
|
||||
{
|
||||
std::string sourceCode = g_resources.loadFile(sourceFile);
|
||||
return compileSourceCode(sourceCode);
|
||||
try {
|
||||
std::string sourceCode = g_resources.loadFile(sourceFile);
|
||||
return compileSourceCode(sourceCode);
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("unable to load shader source form file: %s", sourceFile));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Shader::log()
|
||||
|
@@ -24,12 +24,14 @@
|
||||
#define SHADERPROGRAM_H
|
||||
|
||||
#include "shader.h"
|
||||
#include <framework/luascript/luaobject.h>
|
||||
|
||||
class ShaderProgram
|
||||
class ShaderProgram : public LuaObject
|
||||
{
|
||||
enum {
|
||||
MAX_UNIFORM_LOCATIONS = 30
|
||||
};
|
||||
|
||||
public:
|
||||
ShaderProgram();
|
||||
~ShaderProgram();
|
||||
|
@@ -124,6 +124,16 @@ void Texture::setSmooth(bool smooth)
|
||||
setupFilters();
|
||||
}
|
||||
|
||||
void Texture::setRepeat(bool repeat)
|
||||
{
|
||||
if(m_repeat == repeat)
|
||||
return;
|
||||
|
||||
m_repeat = repeat;
|
||||
bind();
|
||||
setupWrap();
|
||||
}
|
||||
|
||||
void Texture::setUpsideDown(bool upsideDown)
|
||||
{
|
||||
if(m_upsideDown == upsideDown)
|
||||
@@ -163,9 +173,11 @@ bool Texture::setupSize(const Size& size, bool forcePowerOfTwo)
|
||||
|
||||
void Texture::setupWrap()
|
||||
{
|
||||
GLint texParam = GL_REPEAT;
|
||||
if(g_graphics.canUseClampToEdge())
|
||||
texParam = GL_CLAMP_TO_EDGE; // disable texture borders by default
|
||||
GLint texParam;
|
||||
if(!m_repeat && g_graphics.canUseClampToEdge())
|
||||
texParam = GL_CLAMP_TO_EDGE;
|
||||
else
|
||||
texParam = GL_REPEAT;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
|
||||
|
@@ -38,6 +38,7 @@ public:
|
||||
bool buildHardwareMipmaps();
|
||||
|
||||
void setSmooth(bool smooth);
|
||||
void setRepeat(bool repeat);
|
||||
void setUpsideDown(bool upsideDown);
|
||||
|
||||
GLuint getId() { return m_id; }
|
||||
@@ -47,6 +48,7 @@ public:
|
||||
const Size& getGlSize() { return m_glSize; }
|
||||
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
|
||||
bool isEmpty() { return m_id == 0; }
|
||||
bool hasRepeat() { return m_repeat; }
|
||||
bool hasMipmaps() { return m_hasMipmaps; }
|
||||
|
||||
protected:
|
||||
@@ -64,6 +66,7 @@ protected:
|
||||
Boolean<false> m_hasMipmaps;
|
||||
Boolean<false> m_smooth;
|
||||
Boolean<false> m_upsideDown;
|
||||
Boolean<false> m_repeat;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -473,6 +473,10 @@ void Application::registerLuaFunctions()
|
||||
g_lua.bindClassMemberFunction<OutputMessage>("encryptRSA", &OutputMessage::encryptRSA);
|
||||
g_lua.bindClassMemberFunction<OutputMessage>("getMessageSize", &OutputMessage::getMessageSize);
|
||||
|
||||
g_lua.registerClass<ShaderProgram>();
|
||||
g_lua.registerClass<PainterShaderProgram>();
|
||||
g_lua.bindClassMemberFunction<PainterShaderProgram>("addMultiTexture", &PainterShaderProgram::addMultiTexture);
|
||||
|
||||
// Application
|
||||
g_lua.registerStaticClass("g_app");
|
||||
g_lua.bindClassStaticFunction("g_app", "exit", std::bind(&Application::exit, g_app));
|
||||
|
Reference in New Issue
Block a user