mirror of
https://github.com/edubart/otclient.git
synced 2025-10-17 21:13:26 +02:00
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:
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user