optimize graphics performance
This commit is contained in:
parent
c93732a44a
commit
92bd1aba54
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<std::tuple<int, uint>, 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue