Refactor COMPOSITOR/OPENGL_COMPOSITOR to enable customization of scene rendering and presentation
This commit is contained in:
parent
77f9cd0cb0
commit
02bb410cdb
|
@ -46,6 +46,7 @@ set( GAL_SRCS
|
|||
gal/opengl/noncached_container.cpp
|
||||
gal/opengl/vertex_manager.cpp
|
||||
gal/opengl/gpu_manager.cpp
|
||||
gal/opengl/antialiasing.cpp
|
||||
gal/opengl/opengl_compositor.cpp
|
||||
gal/opengl/utils.cpp
|
||||
|
||||
|
|
|
@ -119,6 +119,9 @@ void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
|||
cairo_set_matrix( *m_currentContext, &m_matrix );
|
||||
}
|
||||
|
||||
void CAIRO_COMPOSITOR::Begin()
|
||||
{
|
||||
}
|
||||
|
||||
void CAIRO_COMPOSITOR::ClearBuffer()
|
||||
{
|
||||
|
@ -144,6 +147,9 @@ void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
|||
cairo_set_matrix( m_mainContext, &m_matrix );
|
||||
}
|
||||
|
||||
void CAIRO_COMPOSITOR::Present()
|
||||
{
|
||||
}
|
||||
|
||||
void CAIRO_COMPOSITOR::clean()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#include <gal/opengl/antialiasing.h>
|
||||
#include <gal/opengl/opengl_compositor.h>
|
||||
#include <gal/opengl/utils.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "gl_builtin_shaders.h"
|
||||
|
||||
namespace KIGFX {
|
||||
|
||||
// =========================
|
||||
// ANTIALIASING_NONE
|
||||
// =========================
|
||||
|
||||
ANTIALIASING_NONE::ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor )
|
||||
: compositor(aCompositor)
|
||||
{
|
||||
}
|
||||
|
||||
bool ANTIALIASING_NONE::Init()
|
||||
{
|
||||
// Nothing to initialize
|
||||
return true;
|
||||
}
|
||||
|
||||
VECTOR2U ANTIALIASING_NONE::GetInternalBufferSize()
|
||||
{
|
||||
return compositor->GetScreenSize();
|
||||
}
|
||||
|
||||
void ANTIALIASING_NONE::DrawBuffer( GLuint buffer )
|
||||
{
|
||||
compositor->DrawBuffer( buffer, OPENGL_COMPOSITOR::DIRECT_RENDERING );
|
||||
}
|
||||
|
||||
void ANTIALIASING_NONE::Present()
|
||||
{
|
||||
// Nothing to present, draw_buffer already drew to the screen
|
||||
}
|
||||
|
||||
void ANTIALIASING_NONE::OnLostBuffers()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void ANTIALIASING_NONE::Begin()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
unsigned int ANTIALIASING_NONE::CreateBuffer()
|
||||
{
|
||||
return compositor->CreateBuffer( compositor->GetScreenSize() );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef OPENGL_ANTIALIASING_H__
|
||||
#define OPENGL_ANTIALIASING_H__
|
||||
|
||||
#include <memory>
|
||||
#include <gal/opengl/shader.h>
|
||||
#include <math/vector2d.h>
|
||||
|
||||
namespace KIGFX {
|
||||
|
||||
class OPENGL_COMPOSITOR;
|
||||
|
||||
class OPENGL_PRESENTOR
|
||||
{
|
||||
public:
|
||||
virtual bool Init() = 0;
|
||||
virtual unsigned int CreateBuffer() = 0;
|
||||
|
||||
virtual VECTOR2U GetInternalBufferSize() = 0;
|
||||
virtual void OnLostBuffers() = 0;
|
||||
|
||||
virtual void Begin() = 0;
|
||||
virtual void DrawBuffer(GLuint buffer) = 0;
|
||||
virtual void Present() = 0;
|
||||
};
|
||||
|
||||
class ANTIALIASING_NONE : public OPENGL_PRESENTOR {
|
||||
public:
|
||||
ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor );
|
||||
|
||||
bool Init() override;
|
||||
unsigned int CreateBuffer() override;
|
||||
|
||||
VECTOR2U GetInternalBufferSize() override;
|
||||
void OnLostBuffers() override;
|
||||
|
||||
void Begin() override;
|
||||
void DrawBuffer( GLuint buffer ) override;
|
||||
void Present() override;
|
||||
|
||||
private:
|
||||
OPENGL_COMPOSITOR* compositor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -40,6 +40,7 @@ OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
|
|||
m_initialized( false ), m_curBuffer( 0 ),
|
||||
m_mainFbo( 0 ), m_depthBuffer( 0 ), m_curFbo( DIRECT_RENDERING )
|
||||
{
|
||||
m_antialiasing.reset( new ANTIALIASING_NONE( this ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,6 +56,8 @@ void OPENGL_COMPOSITOR::Initialize()
|
|||
if( m_initialized )
|
||||
return;
|
||||
|
||||
VECTOR2U dims = m_antialiasing->GetInternalBufferSize();
|
||||
|
||||
// We need framebuffer objects for drawing the screen contents
|
||||
// Generate framebuffer and a depth buffer
|
||||
glGenFramebuffersEXT( 1, &m_mainFbo );
|
||||
|
@ -68,7 +71,7 @@ void OPENGL_COMPOSITOR::Initialize()
|
|||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depthBuffer );
|
||||
checkGlError( "binding renderbuffer" );
|
||||
|
||||
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, m_width, m_height );
|
||||
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, dims.x, dims.y );
|
||||
checkGlError( "creating renderbuffer storage" );
|
||||
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER_EXT, m_depthBuffer );
|
||||
|
@ -86,12 +89,18 @@ void OPENGL_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
|
|||
if( m_initialized )
|
||||
clean();
|
||||
|
||||
m_antialiasing->OnLostBuffers();
|
||||
|
||||
m_width = aWidth;
|
||||
m_height = aHeight;
|
||||
}
|
||||
|
||||
|
||||
unsigned int OPENGL_COMPOSITOR::CreateBuffer()
|
||||
{
|
||||
return m_antialiasing->CreateBuffer();
|
||||
}
|
||||
|
||||
unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||
{
|
||||
assert( m_initialized );
|
||||
|
||||
|
@ -109,7 +118,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
|
|||
|
||||
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*) &maxTextureSize );
|
||||
|
||||
if( maxTextureSize < (int) m_width || maxTextureSize < (int) m_height )
|
||||
if( maxTextureSize < (int) aDimensions.x || maxTextureSize < (int) aDimensions.y )
|
||||
{
|
||||
throw std::runtime_error( "Requested texture size is not supported. "
|
||||
"Could not create a buffer." );
|
||||
|
@ -120,6 +129,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
|
|||
GLuint textureTarget;
|
||||
|
||||
// Generate the texture for the pixel storage
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glGenTextures( 1, &textureTarget );
|
||||
checkGlError( "generating framebuffer texture target" );
|
||||
glBindTexture( GL_TEXTURE_2D, textureTarget );
|
||||
|
@ -127,7 +137,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
|
|||
|
||||
// Set texture parameters
|
||||
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA,
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, aDimensions.x, aDimensions.y, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, NULL );
|
||||
checkGlError( "creating framebuffer texture" );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||
|
@ -190,12 +200,17 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
|
|||
bindFb( DIRECT_RENDERING );
|
||||
|
||||
// Store the new buffer
|
||||
OPENGL_BUFFER buffer = { textureTarget, attachmentPoint };
|
||||
OPENGL_BUFFER buffer = { aDimensions, textureTarget, attachmentPoint };
|
||||
m_buffers.push_back( buffer );
|
||||
|
||||
return usedBuffers();
|
||||
}
|
||||
|
||||
GLenum OPENGL_COMPOSITOR::GetBufferTexture( unsigned int aBufferHandle )
|
||||
{
|
||||
assert( aBufferHandle > 0 && aBufferHandle <= usedBuffers() );
|
||||
return m_buffers[aBufferHandle - 1].textureTarget;
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
||||
{
|
||||
|
@ -211,7 +226,14 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
|||
m_curBuffer = aBufferHandle - 1;
|
||||
glDrawBuffer( m_buffers[m_curBuffer].attachmentPoint );
|
||||
checkGlError( "setting draw buffer" );
|
||||
|
||||
glViewport( 0, 0,
|
||||
m_buffers[m_curBuffer].dimensions.x, m_buffers[m_curBuffer].dimensions.y );
|
||||
} else {
|
||||
glViewport( 0, 0, GetScreenSize().x, GetScreenSize().y );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,14 +245,29 @@ void OPENGL_COMPOSITOR::ClearBuffer()
|
|||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||
}
|
||||
|
||||
VECTOR2U OPENGL_COMPOSITOR::GetScreenSize() const
|
||||
{
|
||||
return{ m_width, m_height };
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
||||
void OPENGL_COMPOSITOR::Begin()
|
||||
{
|
||||
m_antialiasing->Begin();
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::DrawBuffer(unsigned int aBufferHandle)
|
||||
{
|
||||
m_antialiasing->DrawBuffer( aBufferHandle );
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::DrawBuffer(unsigned int aSourceHandle, unsigned int aDestHandle)
|
||||
{
|
||||
assert( m_initialized );
|
||||
assert( aBufferHandle != 0 && aBufferHandle <= usedBuffers() );
|
||||
assert( aSourceHandle != 0 && aSourceHandle <= usedBuffers() );
|
||||
assert (aDestHandle <= usedBuffers() );
|
||||
|
||||
// Switch to the main framebuffer and blit the scene
|
||||
bindFb( DIRECT_RENDERING );
|
||||
bindFb( aDestHandle );
|
||||
|
||||
// Depth test has to be disabled to make transparency working
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
|
@ -238,7 +275,7 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
|||
|
||||
// Enable texturing and bind the main texture
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, m_buffers[aBufferHandle - 1].textureTarget );
|
||||
glBindTexture( GL_TEXTURE_2D, m_buffers[aSourceHandle - 1].textureTarget );
|
||||
|
||||
// Draw a full screen quad with the texture
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
|
@ -249,19 +286,19 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
|||
glLoadIdentity();
|
||||
|
||||
glBegin( GL_TRIANGLES );
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2f( -1.0f, -1.0f );
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2f( 1.0f, -1.0f );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2f( 1.0f, 1.0f );
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2f ( -1.0f, 1.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2f ( -1.0f, -1.0f );
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2f ( 1.0f, 1.0f );
|
||||
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2f( -1.0f, -1.0f );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2f( 1.0f, 1.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2f( -1.0f, 1.0f );
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2f ( 1.0f, 1.0f );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2f ( -1.0f, -1.0f );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2f ( 1.0f, -1.0f );
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -269,6 +306,10 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::Present()
|
||||
{
|
||||
m_antialiasing->Present();
|
||||
}
|
||||
|
||||
void OPENGL_COMPOSITOR::bindFb( unsigned int aFb ) {
|
||||
// Currently there are only 2 valid FBOs
|
||||
|
|
|
@ -199,19 +199,12 @@ void OPENGL_GAL::BeginDrawing()
|
|||
|
||||
GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext, this );
|
||||
|
||||
#ifdef RETINA_OPENGL_PATCH
|
||||
const float scaleFactor = GetBackingScaleFactor();
|
||||
#else
|
||||
const float scaleFactor = 1.0f;
|
||||
#endif
|
||||
|
||||
// Set up the view port
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glViewport( 0, 0, (GLsizei) screenSize.x * scaleFactor, (GLsizei) screenSize.y * scaleFactor );
|
||||
|
||||
// Create the screen transformation
|
||||
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y );
|
||||
// Create the screen transformation (Do the RH-LH conversion here)
|
||||
glOrtho( 0, (GLint) screenSize.x, (GLsizei) screenSize.y, 0, -depthRange.x, -depthRange.y );
|
||||
|
||||
if( !isFramebufferInitialized )
|
||||
{
|
||||
|
@ -223,6 +216,8 @@ void OPENGL_GAL::BeginDrawing()
|
|||
isFramebufferInitialized = true;
|
||||
}
|
||||
|
||||
compositor->Begin();
|
||||
|
||||
// Disable 2D Textures
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
|
@ -336,6 +331,7 @@ void OPENGL_GAL::EndDrawing()
|
|||
// Draw the remaining contents, blit the rendering targets to the screen, swap the buffers
|
||||
compositor->DrawBuffer( mainBuffer );
|
||||
compositor->DrawBuffer( overlayBuffer );
|
||||
compositor->Present();
|
||||
blitCursor();
|
||||
|
||||
SwapBuffers();
|
||||
|
|
|
@ -62,12 +62,18 @@ public:
|
|||
/// @copydoc COMPOSITOR::SetBuffer()
|
||||
virtual void SetBuffer( unsigned int aBufferHandle ) override;
|
||||
|
||||
/// @copydoc COMPOSITOR::Begin()
|
||||
virtual void Begin() override;
|
||||
|
||||
/// @copydoc COMPOSITOR::ClearBuffer()
|
||||
virtual void ClearBuffer() override;
|
||||
|
||||
/// @copydoc COMPOSITOR::DrawBuffer()
|
||||
virtual void DrawBuffer( unsigned int aBufferHandle ) override;
|
||||
|
||||
/// @copydoc COMPOSITOR::Present()
|
||||
virtual void Present() override;
|
||||
|
||||
/**
|
||||
* Function SetMainContext()
|
||||
* Sets a context to be treated as the main context (ie. as a target of buffers rendering and
|
||||
|
|
|
@ -88,14 +88,26 @@ public:
|
|||
*/
|
||||
virtual void ClearBuffer() = 0;
|
||||
|
||||
/**
|
||||
* Function Begin()
|
||||
* Call this at the beginning of each frame
|
||||
*/
|
||||
virtual void Begin() = 0;
|
||||
|
||||
/**
|
||||
* Function DrawBuffer()
|
||||
* draws the selected buffer on the screen.
|
||||
* draws the selected buffer to the output buffer.
|
||||
*
|
||||
* @param aBufferHandle is the handle of the buffer to be drawn.
|
||||
*/
|
||||
virtual void DrawBuffer( unsigned int aBufferHandle ) = 0;
|
||||
|
||||
/**
|
||||
* Function Present()
|
||||
* Call this to present the output buffer to the screen.
|
||||
*/
|
||||
virtual void Present() = 0;
|
||||
|
||||
protected:
|
||||
unsigned int m_width; ///< Width of the buffer (in pixels)
|
||||
unsigned int m_height; ///< Height of the buffer (in pixels)
|
||||
|
|
|
@ -32,11 +32,13 @@
|
|||
#define OPENGL_COMPOSITOR_H_
|
||||
|
||||
#include <gal/compositor.h>
|
||||
#include <gal/opengl/antialiasing.h>
|
||||
#include <GL/glew.h>
|
||||
#include <deque>
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
|
||||
class OPENGL_COMPOSITOR : public COMPOSITOR
|
||||
{
|
||||
public:
|
||||
|
@ -70,13 +72,26 @@ public:
|
|||
/// @copydoc COMPOSITOR::DrawBuffer()
|
||||
virtual void DrawBuffer( unsigned int aBufferHandle ) override;
|
||||
|
||||
/// @copydoc COMPOSITOR::Begin()
|
||||
virtual void Begin() override;
|
||||
|
||||
// @copydoc COMPOSITOR::Present()
|
||||
virtual void Present() override;
|
||||
|
||||
// Constant used by glBindFramebuffer to turn off rendering to framebuffers
|
||||
static const unsigned int DIRECT_RENDERING = 0;
|
||||
|
||||
public:
|
||||
VECTOR2U GetScreenSize() const;
|
||||
GLenum GetBufferTexture( unsigned int aBufferHandle );
|
||||
void DrawBuffer( unsigned int aSourceHandle, unsigned int aDestHandle );
|
||||
unsigned int CreateBuffer( VECTOR2U aDimensions );
|
||||
|
||||
protected:
|
||||
// Buffers are simply textures storing a result of certain target rendering.
|
||||
typedef struct
|
||||
{
|
||||
VECTOR2U dimensions;
|
||||
GLuint textureTarget; ///< Main texture handle
|
||||
GLuint attachmentPoint; ///< Point to which an image from texture is attached
|
||||
} OPENGL_BUFFER;
|
||||
|
@ -93,6 +108,8 @@ protected:
|
|||
/// Store the used FBO name in case there was more than one compositor used
|
||||
GLuint m_curFbo;
|
||||
|
||||
std::unique_ptr< OPENGL_PRESENTOR > m_antialiasing;
|
||||
|
||||
/// Binds a specific Framebuffer Object.
|
||||
void bindFb( unsigned int aFb );
|
||||
|
||||
|
|
|
@ -576,8 +576,9 @@ std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
|
|||
|
||||
|
||||
/* Default specializations */
|
||||
typedef VECTOR2<double> VECTOR2D;
|
||||
typedef VECTOR2<int> VECTOR2I;
|
||||
typedef VECTOR2<double> VECTOR2D;
|
||||
typedef VECTOR2<int> VECTOR2I;
|
||||
typedef VECTOR2<unsigned int> VECTOR2U;
|
||||
|
||||
/* Compatibility typedefs */
|
||||
// FIXME should be removed to avoid multiple typedefs for the same type
|
||||
|
|
Loading…
Reference in New Issue