more graphics optimizations
* avoid buffers clears * use scisors testing instead of stencil testing for clipping * remove stencil buffers
This commit is contained in:
		
							parent
							
								
									53d56259c7
								
							
						
					
					
						commit
						b5a4d31fa7
					
				| 
						 | 
					@ -30,13 +30,11 @@ std::vector<bool> auxBuffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FrameBuffer::FrameBuffer()
 | 
					FrameBuffer::FrameBuffer()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    m_clearColor = Color::alpha;
 | 
					 | 
				
			||||||
    internalCreate();
 | 
					    internalCreate();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FrameBuffer::FrameBuffer(const Size& size)
 | 
					FrameBuffer::FrameBuffer(const Size& size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    m_clearColor = Color::alpha;
 | 
					 | 
				
			||||||
    internalCreate();
 | 
					    internalCreate();
 | 
				
			||||||
    resize(size);
 | 
					    resize(size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -101,10 +99,22 @@ void FrameBuffer::resize(const Size& size)
 | 
				
			||||||
            logFatal("Unable to setup framebuffer object");
 | 
					            logFatal("Unable to setup framebuffer object");
 | 
				
			||||||
        internalRelease();
 | 
					        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();
 | 
					    internalBind();
 | 
				
			||||||
    Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(),  0.0f,                         0.0f,
 | 
					    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();
 | 
					    m_oldViewportSize = g_graphics.getViewportSize();
 | 
				
			||||||
    g_painter.setProjectionMatrix(projectionMatrix);
 | 
					    g_painter.setProjectionMatrix(projectionMatrix);
 | 
				
			||||||
    g_graphics.setViewportSize(m_texture->getSize());
 | 
					    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()
 | 
					void FrameBuffer::release()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,13 +34,12 @@ public:
 | 
				
			||||||
    virtual ~FrameBuffer();
 | 
					    virtual ~FrameBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void resize(const Size& size);
 | 
					    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 release();
 | 
				
			||||||
    void draw(const Rect& dest);
 | 
					    void draw(const Rect& dest);
 | 
				
			||||||
    void draw(const Rect& dest, const Rect& src);
 | 
					    void draw(const Rect& dest, const Rect& src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void setClearColor(const Color& color) { m_clearColor = color; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    TexturePtr getTexture() { return m_texture; }
 | 
					    TexturePtr getTexture() { return m_texture; }
 | 
				
			||||||
    Size getSize();
 | 
					    Size getSize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,6 @@ private:
 | 
				
			||||||
    Size m_oldViewportSize;
 | 
					    Size m_oldViewportSize;
 | 
				
			||||||
    uint m_fbo;
 | 
					    uint m_fbo;
 | 
				
			||||||
    uint m_prevBoundFbo;
 | 
					    uint m_prevBoundFbo;
 | 
				
			||||||
    Color m_clearColor;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static uint boundFbo;
 | 
					    static uint boundFbo;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,10 +73,11 @@ void Graphics::init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_useFBO = m_useFBO && (GLEW_ARB_framebuffer_object || GLEW_EXT_framebuffer_object);
 | 
					    m_useFBO = m_useFBO && (GLEW_ARB_framebuffer_object || GLEW_EXT_framebuffer_object);
 | 
				
			||||||
    m_generateHardwareMipmaps = m_generateHardwareMipmaps; // glGenerateMipmap is supported when framebuffers are
 | 
					    m_generateHardwareMipmaps = m_generateHardwareMipmaps; // glGenerateMipmap is supported when framebuffers are
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glEnable(GL_BLEND);
 | 
					    glEnable(GL_BLEND);
 | 
				
			||||||
    //glClear(GL_ACCUM_BUFFER_BIT);
 | 
					    glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_emptyTexture = TexturePtr(new Texture);
 | 
					    m_emptyTexture = TexturePtr(new Texture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,7 +111,6 @@ bool Graphics::parseOption(const std::string& option)
 | 
				
			||||||
void Graphics::resize(const Size& size)
 | 
					void Graphics::resize(const Size& size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    setViewportSize(size);
 | 
					    setViewportSize(size);
 | 
				
			||||||
    //glClear(GL_ACCUM_BUFFER_BIT);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The projection matrix converts from Painter's coordinate system to GL's coordinate system
 | 
					    // 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's viewport is 2x2, Painter's is width x height
 | 
				
			||||||
| 
						 | 
					@ -134,8 +134,8 @@ void Graphics::resize(const Size& size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::beginRender()
 | 
					void Graphics::beginRender()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    glClearColor(0, 0, 0, 1);
 | 
					    //glClearColor(0, 0, 0, 1);
 | 
				
			||||||
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 | 
					    //glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::endRender()
 | 
					void Graphics::endRender()
 | 
				
			||||||
| 
						 | 
					@ -154,32 +154,13 @@ void Graphics::endRender()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::beginClipping(const Rect& clipRect)
 | 
					void Graphics::beginClipping(const Rect& clipRect)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static uint8 depth = 0;
 | 
					    glEnable(GL_SCISSOR_TEST);
 | 
				
			||||||
 | 
					    glScissor(clipRect.left(), m_viewportSize.height() - clipRect.bottom() - 1, clipRect.width(), clipRect.height());
 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::endClipping()
 | 
					void Graphics::endClipping()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    glDisable(GL_STENCIL_TEST);
 | 
					    glDisable(GL_SCISSOR_TEST);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graphics::setViewportSize(const Size& size)
 | 
					void Graphics::setViewportSize(const Size& size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					    // 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));
 | 
					    FrameBufferPtr fb(new FrameBuffer(m_size));
 | 
				
			||||||
    fb->bind();
 | 
					    fb->bind();
 | 
				
			||||||
 | 
					    fb->clear(Fw::alpha);
 | 
				
			||||||
    g_painter.saveAndResetState();
 | 
					    g_painter.saveAndResetState();
 | 
				
			||||||
    g_painter.drawTexturedRect(Rect(0,0,m_size), shared_from_this());
 | 
					    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]);
 | 
					    glReadPixels(0, 0, m_size.width(), m_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -310,7 +310,7 @@ void WIN32Window::internalChooseGLVisual()
 | 
				
			||||||
                                         0,                          // No Accumulation Buffer
 | 
					                                         0,                          // No Accumulation Buffer
 | 
				
			||||||
                                         0, 0, 0, 0,                 // Accumulation Bits Ignored
 | 
					                                         0, 0, 0, 0,                 // Accumulation Bits Ignored
 | 
				
			||||||
                                         16,                         // 16Bit Z-Buffer (Depth Buffer)
 | 
					                                         16,                         // 16Bit Z-Buffer (Depth Buffer)
 | 
				
			||||||
                                         8,                          // 8Bit Stencil Buffer
 | 
					                                         0,                          // No Stencil Buffer
 | 
				
			||||||
                                         0,                          // No Auxiliary Buffer
 | 
					                                         0,                          // No Auxiliary Buffer
 | 
				
			||||||
                                         PFD_MAIN_PLANE,             // Main Drawing Layer
 | 
					                                         PFD_MAIN_PLANE,             // Main Drawing Layer
 | 
				
			||||||
                                         0,                          // Reserved
 | 
					                                         0,                          // Reserved
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -369,7 +369,7 @@ void X11Window::internalChooseGLVisual()
 | 
				
			||||||
        GLX_USE_GL,
 | 
					        GLX_USE_GL,
 | 
				
			||||||
        GLX_RGBA,
 | 
					        GLX_RGBA,
 | 
				
			||||||
        GLX_DOUBLEBUFFER,
 | 
					        GLX_DOUBLEBUFFER,
 | 
				
			||||||
        GLX_STENCIL_SIZE, 8,
 | 
					        //GLX_STENCIL_SIZE, 8,
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
        GLX_ACCUM_RED_SIZE, 8,
 | 
					        GLX_ACCUM_RED_SIZE, 8,
 | 
				
			||||||
        GLX_ACCUM_GREEN_SIZE, 8,
 | 
					        GLX_ACCUM_GREEN_SIZE, 8,
 | 
				
			||||||
| 
						 | 
					@ -388,7 +388,7 @@ void X11Window::internalChooseGLVisual()
 | 
				
			||||||
    static int attrList[] = {
 | 
					    static int attrList[] = {
 | 
				
			||||||
        //EGL_BUFFER_SIZE, 24,
 | 
					        //EGL_BUFFER_SIZE, 24,
 | 
				
			||||||
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
 | 
					        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
 | 
				
			||||||
        EGL_STENCIL_SIZE, 1,
 | 
					        //EGL_STENCIL_SIZE, 8,
 | 
				
			||||||
        EGL_NONE
 | 
					        EGL_NONE
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    outfitBuffer->bind();
 | 
					    outfitBuffer->bind();
 | 
				
			||||||
 | 
					    outfitBuffer->clear();
 | 
				
			||||||
    internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
 | 
					    internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
 | 
				
			||||||
    outfitBuffer->release();
 | 
					    outfitBuffer->release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
					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()
 | 
					void Game::processCloseNpcTrade()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,6 @@ MapView::MapView()
 | 
				
			||||||
                         std::min(g_graphics.getMaxTextureSize(), (int)DEFAULT_FRAMBUFFER_HEIGHT));
 | 
					                         std::min(g_graphics.getMaxTextureSize(), (int)DEFAULT_FRAMBUFFER_HEIGHT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_framebuffer = FrameBufferPtr(new FrameBuffer(frameBufferSize));
 | 
					    m_framebuffer = FrameBufferPtr(new FrameBuffer(frameBufferSize));
 | 
				
			||||||
    m_framebuffer->setClearColor(Color::black);
 | 
					 | 
				
			||||||
    setVisibleDimension(Size(15, 11));
 | 
					    setVisibleDimension(Size(15, 11));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
 | 
					    m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
 | 
				
			||||||
| 
						 | 
					@ -77,7 +76,12 @@ void MapView::draw(const Rect& rect)
 | 
				
			||||||
        drawFlags = Otc::DrawGround;
 | 
					        drawFlags = Otc::DrawGround;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
 | 
					    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 it = m_cachedVisibleTiles.begin();
 | 
				
			||||||
        auto end = m_cachedVisibleTiles.end();
 | 
					        auto end = m_cachedVisibleTiles.end();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue