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()
 | 
			
		||||
{
 | 
			
		||||
    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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue