more graphics optimizations

* avoid buffers clears
* use scisors testing instead of stencil testing for clipping
* remove stencil buffers
This commit is contained in:
Eduardo Bart 2012-04-04 17:18:24 -03:00
parent 53d56259c7
commit b5a4d31fa7
9 changed files with 35 additions and 45 deletions

View File

@ -30,13 +30,11 @@ std::vector<bool> auxBuffers;
FrameBuffer::FrameBuffer()
{
m_clearColor = Color::alpha;
internalCreate();
}
FrameBuffer::FrameBuffer(const Size& size)
{
m_clearColor = Color::alpha;
internalCreate();
resize(size);
}
@ -101,10 +99,22 @@ void FrameBuffer::resize(const Size& size)
logFatal("Unable to setup framebuffer object");
internalRelease();
}
}
void FrameBuffer::bind(bool clear)
void FrameBuffer::clear(const Color& color, const Rect& rect)
{
bool clip = rect.isValid();
if(clip)
g_graphics.beginClipping(Rect(0, 0, m_texture->getSize()));
glClearColor(color.rF(), color.gF(), color.bF(), color.aF());
glClear(GL_COLOR_BUFFER_BIT);
if(clip)
g_graphics.endClipping();
}
void FrameBuffer::bind()
{
internalBind();
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
@ -115,11 +125,6 @@ void FrameBuffer::bind(bool clear)
m_oldViewportSize = g_graphics.getViewportSize();
g_painter.setProjectionMatrix(projectionMatrix);
g_graphics.setViewportSize(m_texture->getSize());
if(clear) {
glClearColor(m_clearColor.rF(), m_clearColor.gF(), m_clearColor.bF(), m_clearColor.aF());
glClear(GL_COLOR_BUFFER_BIT);
}
}
void FrameBuffer::release()

View File

@ -34,13 +34,12 @@ public:
virtual ~FrameBuffer();
void resize(const Size& size);
void bind(bool clear = true);
void bind();
void clear(const Color& color = Color::black, const Rect& rect = Rect());
void release();
void draw(const Rect& dest);
void draw(const Rect& dest, const Rect& src);
void setClearColor(const Color& color) { m_clearColor = color; }
TexturePtr getTexture() { return m_texture; }
Size getSize();
@ -55,7 +54,6 @@ private:
Size m_oldViewportSize;
uint m_fbo;
uint m_prevBoundFbo;
Color m_clearColor;
static uint boundFbo;
};

View File

@ -73,10 +73,11 @@ void Graphics::init()
m_useFBO = m_useFBO && (GLEW_ARB_framebuffer_object || GLEW_EXT_framebuffer_object);
m_generateHardwareMipmaps = m_generateHardwareMipmaps; // glGenerateMipmap is supported when framebuffers are
#endif
glEnable(GL_BLEND);
//glClear(GL_ACCUM_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
m_emptyTexture = TexturePtr(new Texture);
@ -110,7 +111,6 @@ bool Graphics::parseOption(const std::string& option)
void Graphics::resize(const Size& size)
{
setViewportSize(size);
//glClear(GL_ACCUM_BUFFER_BIT);
// 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
@ -134,8 +134,8 @@ void Graphics::resize(const Size& size)
void Graphics::beginRender()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//glClearColor(0, 0, 0, 1);
//glClear(GL_COLOR_BUFFER_BIT);
}
void Graphics::endRender()
@ -154,32 +154,13 @@ void Graphics::endRender()
void Graphics::beginClipping(const Rect& clipRect)
{
static uint8 depth = 0;
depth++;
if(depth == 0) {
glClear(GL_STENCIL_BUFFER_BIT);
depth = 1;
}
// setup stencil buffer for writing
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, depth, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
// draw the clipping area into the stencil buffer
glColorMask(0, 0, 0, 0);
g_painter.drawFilledRect(clipRect);
// set stencil buffer for clipping
glColorMask(1, 1, 1, 1);
glStencilFunc(GL_EQUAL, depth, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glEnable(GL_SCISSOR_TEST);
glScissor(clipRect.left(), m_viewportSize.height() - clipRect.bottom() - 1, clipRect.width(), clipRect.height());
}
void Graphics::endClipping()
{
glDisable(GL_STENCIL_TEST);
glDisable(GL_SCISSOR_TEST);
}
void Graphics::setViewportSize(const Size& size)

View File

@ -145,6 +145,7 @@ std::vector<uint8> Texture::getPixels()
// NOTE: this can be slow, but its the only way to get pixels from a texture in OpenGL ES
FrameBufferPtr fb(new FrameBuffer(m_size));
fb->bind();
fb->clear(Fw::alpha);
g_painter.saveAndResetState();
g_painter.drawTexturedRect(Rect(0,0,m_size), shared_from_this());
glReadPixels(0, 0, m_size.width(), m_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);

View File

@ -310,7 +310,7 @@ void WIN32Window::internalChooseGLVisual()
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
8, // 8Bit Stencil Buffer
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved

View File

@ -369,7 +369,7 @@ void X11Window::internalChooseGLVisual()
GLX_USE_GL,
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_STENCIL_SIZE, 8,
//GLX_STENCIL_SIZE, 8,
/*
GLX_ACCUM_RED_SIZE, 8,
GLX_ACCUM_GREEN_SIZE, 8,
@ -388,7 +388,7 @@ void X11Window::internalChooseGLVisual()
static int attrList[] = {
//EGL_BUFFER_SIZE, 24,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_STENCIL_SIZE, 1,
//EGL_STENCIL_SIZE, 8,
EGL_NONE
};

View File

@ -184,6 +184,7 @@ void Creature::drawOutfit(const Rect& destRect, bool resize)
outfitBuffer = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
outfitBuffer->bind();
outfitBuffer->clear();
internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
outfitBuffer->release();

View File

@ -316,7 +316,7 @@ void Game::processOpenNpcTrade(const std::vector<std::tuple<ItemPtr, std::string
void Game::processPlayerGoods(int money, const std::vector<std::tuple<ItemPtr, int>>& goods)
{
g_lua.callGlobalField("g_game", "onPlayerGoods", goods);
g_lua.callGlobalField("g_game", "onPlayerGoods", money, goods);
}
void Game::processCloseNpcTrade()

View File

@ -45,7 +45,6 @@ MapView::MapView()
std::min(g_graphics.getMaxTextureSize(), (int)DEFAULT_FRAMBUFFER_HEIGHT));
m_framebuffer = FrameBufferPtr(new FrameBuffer(frameBufferSize));
m_framebuffer->setClearColor(Color::black);
setVisibleDimension(Size(15, 11));
m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
@ -77,7 +76,12 @@ void MapView::draw(const Rect& rect)
drawFlags = Otc::DrawGround;
if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
m_framebuffer->bind(m_mustCleanFramebuffer);
m_framebuffer->bind();
if(m_mustCleanFramebuffer) {
Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize);
m_framebuffer->clear(Color::black, clearRect);
}
auto it = m_cachedVisibleTiles.begin();
auto end = m_cachedVisibleTiles.end();