graphics optimizations/fixes/features

* cache text vertex for StaticText, AnimatedText and Creature names
* improved outfit rendering
* fully compatible with OpenGL 1.1
* enable mipmaping for game sprites again
* Ctrl+W hotkey clean game texts
This commit is contained in:
Eduardo Bart
2012-06-08 21:40:22 -03:00
parent 1a7f2a44fc
commit 95cf7eb788
21 changed files with 180 additions and 155 deletions

View File

@@ -197,6 +197,7 @@ SET(framework_SOURCES ${framework_SOURCES}
# framework graphics
${CMAKE_CURRENT_LIST_DIR}/graphics/font.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/cachedtext.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/painter.cpp

View File

@@ -167,7 +167,6 @@ void Application::run()
if(!m_initialized)
return;
bool cacheForeground = true;
m_stopping = false;
m_running = true;
@@ -190,14 +189,7 @@ void Application::run()
bool redraw = false;
bool updateForeground = false;
bool canCacheForeground = g_graphics.canCacheBackbuffer() && m_foregroundFrameCounter.getMaxFps() != 0;
if(cacheForeground != canCacheForeground) {
cacheForeground = canCacheForeground;
if(cacheForeground)
glColorMask(1,1,1,1);
else
glColorMask(1,1,1,0);
}
bool cacheForeground = g_graphics.canCacheBackbuffer() && m_foregroundFrameCounter.getMaxFps() != 0;
if(m_backgroundFrameCounter.shouldProcessNextFrame()) {
redraw = true;
@@ -219,11 +211,15 @@ void Application::run()
m_foregroundFrameCounter.processNextFrame();
// draw foreground
g_painter->clear(Color::black);
g_painter->setAlphaWriting(true);
g_painter->clear(Color::alpha);
g_ui.render(Fw::ForegroundPane);
// copy the foreground to a texture
m_foreground->copyFromScreen(viewportRect);
g_painter->clear(Color::black);
g_painter->setAlphaWriting(false);
}
// draw background (animated stuff)

View File

@@ -30,6 +30,7 @@ class Texture;
class Image;
class AnimatedTexture;
class Font;
class CachedText;
class FrameBuffer;
class Shader;
class ShaderProgram;
@@ -46,6 +47,7 @@ typedef std::shared_ptr<Image> ImagePtr;
typedef std::shared_ptr<Texture> TexturePtr;
typedef std::shared_ptr<AnimatedTexture> AnimatedTexturePtr;
typedef std::shared_ptr<Font> FontPtr;
typedef std::shared_ptr<CachedText> CachedTextPtr;
typedef std::shared_ptr<FrameBuffer> FrameBufferPtr;
typedef std::shared_ptr<Shader> ShaderPtr;
typedef std::shared_ptr<ShaderProgram> ShaderProgramPtr;

View File

@@ -131,13 +131,57 @@ bool Image::nextMipmap()
assert(m_bpp == 4);
assert(stdext::is_power_of_two(m_size.width()) && stdext::is_power_of_two(m_size.height()));
if(m_size.width() == 1 || m_size.height() == 1)
int iw = m_size.width();
int ih = m_size.height();
if(iw == 1 && ih == 1)
return false;
Size size = m_size / 2;
std::vector<uint8> pixels(size.area()*4, 0xFF);
int ow = iw > 1 ? iw/2 : 1;
int oh = ih > 1 ? ih/2 : 1;
std::vector<uint8> pixels(ow*oh*4, 0xFF);
//FIXME: calculate mipmaps for 8x1, 4x1, 2x1 ...
if(iw != 1 && ih != 1) {
for(int x=0;x<ow;++x) {
for(int y=0;y<oh;++y) {
uint8 *inPixel[4];
inPixel[0] = &m_pixels[((y*2)*iw + (x*2))*4];
inPixel[1] = &m_pixels[((y*2)*iw + (x*2)+1)*4];
inPixel[2] = &m_pixels[((y*2+1)*iw + (x*2))*4];
inPixel[3] = &m_pixels[((y*2+1)*iw + (x*2)+1)*4];
uint8 *outPixel = &pixels[(y*ow + x)*4];
int pixelsSum[4];
for(int i=0;i<4;++i)
pixelsSum[i] = 0;
int usedPixels = 0;
for(int j=0;j<4;++j) {
// ignore colors of complete alpha pixels
if(inPixel[j][3] < 16)
continue;
for(int i=0;i<4;++i)
pixelsSum[i] += inPixel[j][i];
usedPixels++;
}
// try to guess the alpha pixel more accurately
for(int i=0;i<4;++i) {
if(usedPixels > 0)
outPixel[i] = pixelsSum[i] / usedPixels;
else
outPixel[i] = 0;
}
outPixel[3] = pixelsSum[3]/4;
}
}
}
m_pixels = pixels;
m_size = size;
m_size = Size(ow, oh);
return true;
}

View File

@@ -34,6 +34,7 @@ Painter::Painter()
m_compositionMode = CompositionMode_Normal;
m_shaderProgram = nullptr;
m_texture = nullptr;
m_alphaWriting = false;
}
void Painter::resetState()
@@ -44,6 +45,7 @@ void Painter::resetState()
resetClipRect();
resetShaderProgram();
resetTexture();
resetAlphaWriting();
}
void Painter::refreshState()
@@ -51,6 +53,7 @@ void Painter::refreshState()
updateGlCompositionMode();
updateGlClipRect();
updateGlTexture();
updateGlAlphaWriting();
}
void Painter::saveState()
@@ -64,6 +67,7 @@ void Painter::saveState()
m_olderStates[m_oldStateIndex].clipRect = m_clipRect;
m_olderStates[m_oldStateIndex].shaderProgram = m_shaderProgram;
m_olderStates[m_oldStateIndex].texture = m_texture;
m_olderStates[m_oldStateIndex].alphaWriting = m_alphaWriting;
m_oldStateIndex++;
}
@@ -137,6 +141,15 @@ void Painter::setTexture(Texture* texture)
}
}
void Painter::setAlphaWriting(bool enable)
{
if(m_alphaWriting == enable)
return;
m_alphaWriting = enable;
updateGlAlphaWriting();
}
void Painter::updateGlTexture()
{
if(m_glTextureId != 0)
@@ -177,3 +190,11 @@ void Painter::updateGlClipRect()
glDisable(GL_SCISSOR_TEST);
}
}
void Painter::updateGlAlphaWriting()
{
if(m_alphaWriting)
glColorMask(1,1,1,1);
else
glColorMask(1,1,1,0);
}

View File

@@ -52,6 +52,7 @@ public:
Rect clipRect;
Texture *texture;
PainterShaderProgram *shaderProgram;
bool alphaWriting;
};
Painter();
@@ -85,6 +86,7 @@ public:
virtual void setClipRect(const Rect& clipRect);
virtual void setShaderProgram(PainterShaderProgram *shaderProgram) { m_shaderProgram = shaderProgram; }
virtual void setTexture(Texture *texture);
void setAlphaWriting(bool enable);
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram) { setShaderProgram(shaderProgram.get()); }
void setTexture(const TexturePtr& texture) { setTexture(texture.get()); }
@@ -96,6 +98,7 @@ public:
CompositionMode getCompositionMode() { return m_compositionMode; }
Rect getClipRect() { return m_clipRect; }
PainterShaderProgram *getShaderProgram() { return m_shaderProgram; }
bool getAlphaWriting() { return m_alphaWriting; }
void resetColor() { setColor(Color::white); }
void resetOpacity() { setOpacity(1.0f); }
@@ -103,11 +106,13 @@ public:
void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); }
void resetShaderProgram() { setShaderProgram(nullptr); }
void resetTexture() { setTexture(nullptr); }
void resetAlphaWriting() { setAlphaWriting(false); }
protected:
void updateGlTexture();
void updateGlCompositionMode();
void updateGlClipRect();
void updateGlAlphaWriting();
CoordsBuffer m_coordsBuffer;
@@ -119,6 +124,7 @@ protected:
Rect m_clipRect;
Texture *m_texture;
PainterShaderProgram *m_shaderProgram;
bool m_alphaWriting;
PainterState m_olderStates[10];
int m_oldStateIndex;

View File

@@ -62,7 +62,6 @@ Texture::Texture(const ImagePtr& image, bool buildMipmaps)
bind();
/*
if(buildMipmaps) {
int level = 0;
do {
@@ -70,7 +69,6 @@ Texture::Texture(const ImagePtr& image, bool buildMipmaps)
} while(glImage->nextMipmap());
m_hasMipmaps = true;
} else
*/
setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp());
setupWrap();

View File

@@ -370,10 +370,10 @@ void X11Window::internalChooseGLVisual()
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_NONE
};