Fixed blending function for OpenGL compositing. Corrected documentation, removed unnecessary functions.

This commit is contained in:
Maciej Suminski 2013-07-24 15:06:59 +02:00
parent 67c0cd2205
commit 27113348b9
4 changed files with 67 additions and 87 deletions

View File

@ -1,4 +1,4 @@
/*i /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
@ -103,58 +103,56 @@ unsigned int OPENGL_COMPOSITOR::GetBuffer()
{ {
wxASSERT( m_initialized ); wxASSERT( m_initialized );
if( m_buffers.size() < m_maxBuffers ) if( m_buffers.size() >= m_maxBuffers )
{ return 0; // Unfortunately we have no more free buffers left
// GL_COLOR_ATTACHMENTn are consecutive integers
GLuint attachmentPoint = GL_COLOR_ATTACHMENT0 + usedBuffers();
GLuint textureTarget;
// Generate the texture for the pixel storage // GL_COLOR_ATTACHMENTn are consecutive integers
glGenTextures( 1, &textureTarget ); GLuint attachmentPoint = GL_COLOR_ATTACHMENT0 + usedBuffers();
glBindTexture( GL_TEXTURE_2D, textureTarget ); GLuint textureTarget;
// Set texture parameters // Generate the texture for the pixel storage
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, glGenTextures( 1, &textureTarget );
GL_UNSIGNED_BYTE, NULL ); glBindTexture( GL_TEXTURE_2D, textureTarget );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
// Bind the texture to the specific attachment point, clear and rebind the screen // Set texture parameters
glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer ); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
m_currentFbo = m_framebuffer; glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA,
glFramebufferTexture2D( GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, textureTarget, 0 ); GL_UNSIGNED_BYTE, NULL );
ClearBuffer(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
m_currentFbo = 0;
// Store the new buffer // Bind the texture to the specific attachment point, clear and rebind the screen
BUFFER_ITEM buffer = { textureTarget, attachmentPoint }; glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer );
m_buffers.push_back( buffer ); m_currentFbo = m_framebuffer;
glFramebufferTexture2D( GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, textureTarget, 0 );
ClearBuffer();
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
return usedBuffers(); // Store the new buffer
} OPENGL_BUFFER buffer = { textureTarget, attachmentPoint };
m_buffers.push_back( buffer );
// Unfortunately we have no more buffers left return usedBuffers();
return 0;
} }
void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle ) void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
{ {
if( aBufferHandle <= usedBuffers() ) if( aBufferHandle > usedBuffers() )
{ return;
// Change the rendering destination to the selected attachment point
if( m_currentFbo != m_framebuffer )
{
glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer );
m_currentFbo = m_framebuffer;
}
if( m_current != aBufferHandle - 1 ) // Change the rendering destination to the selected attachment point
{ if( m_currentFbo != m_framebuffer )
glDrawBuffer( m_buffers[m_current].attachmentPoint ); {
m_current = aBufferHandle - 1; glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer );
} m_currentFbo = m_framebuffer;
}
if( m_current != aBufferHandle - 1 )
{
m_current = aBufferHandle - 1;
glDrawBuffer( m_buffers[m_current].attachmentPoint );
} }
} }
@ -168,15 +166,7 @@ void OPENGL_COMPOSITOR::ClearBuffer()
} }
void OPENGL_COMPOSITOR::BlitBuffer( unsigned int aBufferHandle ) void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
{
wxASSERT( m_initialized );
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
}
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle, double aDepth )
{ {
wxASSERT( m_initialized ); wxASSERT( m_initialized );
@ -202,18 +192,18 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle, double aDepth )
glBegin( GL_TRIANGLES ); glBegin( GL_TRIANGLES );
glTexCoord2f( 0.0f, 1.0f ); glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, -1.0f, aDepth ); glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 1.0f ); glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, -1.0f, aDepth ); glVertex2f( 1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f ); glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, aDepth ); glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 1.0f ); glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, -1.0f, aDepth ); glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f ); glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, aDepth ); glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f ); glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, 1.0f, aDepth ); glVertex2f( -1.0f, 1.0f );
glEnd(); glEnd();
glPopMatrix(); glPopMatrix();
@ -229,7 +219,7 @@ void OPENGL_COMPOSITOR::clean()
glDeleteFramebuffers( 1, &m_framebuffer ); glDeleteFramebuffers( 1, &m_framebuffer );
glDeleteRenderbuffers( 1, &m_depthBuffer ); glDeleteRenderbuffers( 1, &m_depthBuffer );
Buffers::const_iterator it; OPENGL_BUFFERS::const_iterator it;
for( it = m_buffers.begin(); it != m_buffers.end(); ++it ) for( it = m_buffers.begin(); it != m_buffers.end(); ++it )
{ {
glDeleteTextures( 1, &it->textureTarget ); glDeleteTextures( 1, &it->textureTarget );

View File

@ -333,8 +333,8 @@ void OPENGL_GAL::EndDrawing()
// Draw the remaining contents, blit the rendering targets to the screen, swap the buffers // Draw the remaining contents, blit the rendering targets to the screen, swap the buffers
glFlush(); glFlush();
compositor.DrawBuffer( mainBuffer, -1.0 ); compositor.DrawBuffer( mainBuffer );
compositor.DrawBuffer( overlayBuffer, 0.0 ); compositor.DrawBuffer( overlayBuffer );
SwapBuffers(); SwapBuffers();
delete clientDC; delete clientDC;

View File

@ -80,22 +80,13 @@ public:
*/ */
virtual void ClearBuffer() = 0; virtual void ClearBuffer() = 0;
/**
* Function BlitBuffer()
* pastes the content of the buffer to the current buffer (set by SetBuffer() function).
*
* @param aBufferHandle is the handle to the buffer that is going to be pasted.
*/
virtual void BlitBuffer( unsigned int aBufferHandle ) = 0;
/** /**
* Function DrawBuffer() * Function DrawBuffer()
* draws the selected buffer on the screen. * draws the selected buffer on the screen.
* *
* @param aBufferHandle is the handle of the buffer to be drawn. * @param aBufferHandle is the handle of the buffer to be drawn.
* @param aDepth is the depth on which the buffer should be drawn. // TODO mention if higher depth value means close to the screen or is it opposite
*/ */
virtual void DrawBuffer( unsigned int aBufferHandle, double aDepth ) = 0; virtual void DrawBuffer( unsigned int aBufferHandle ) = 0;
protected: protected:
unsigned int m_width; ///< Width of the buffer (in pixels) unsigned int m_width; ///< Width of the buffer (in pixels)

View File

@ -33,7 +33,7 @@
#include <gal/compositor.h> #include <gal/compositor.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <vector> #include <deque>
namespace KiGfx namespace KiGfx
{ {
@ -44,41 +44,40 @@ public:
OPENGL_COMPOSITOR(); OPENGL_COMPOSITOR();
virtual ~OPENGL_COMPOSITOR(); virtual ~OPENGL_COMPOSITOR();
///< @copydoc COMPOSITOR::Initialize() /// @copydoc COMPOSITOR::Initialize()
virtual void Initialize(); virtual void Initialize();
///< @copydoc COMPOSITOR::Resize() /// @copydoc COMPOSITOR::Resize()
virtual void Resize( unsigned int aWidth, unsigned int aHeight ); virtual void Resize( unsigned int aWidth, unsigned int aHeight );
///< @copydoc COMPOSITOR::GetBuffer() /// @copydoc COMPOSITOR::GetBuffer()
virtual unsigned int GetBuffer(); virtual unsigned int GetBuffer();
///< @copydoc COMPOSITOR::SetBuffer() /// @copydoc COMPOSITOR::SetBuffer()
virtual void SetBuffer( unsigned int aBufferHandle ); virtual void SetBuffer( unsigned int aBufferHandle );
///< @copydoc COMPOSITOR::ClearBuffer() /// @copydoc COMPOSITOR::ClearBuffer()
virtual void ClearBuffer(); virtual void ClearBuffer();
///< @copydoc COMPOSITOR::BlitBuffer() /// @copydoc COMPOSITOR::DrawBuffer()
virtual void BlitBuffer( unsigned int aBufferHandle ); virtual void DrawBuffer( unsigned int aBufferHandle );
///< @copydoc COMPOSITOR::DrawBuffer()
virtual void DrawBuffer( unsigned int aBufferHandle, double aDepth );
protected: protected:
typedef struct typedef struct
{ {
GLuint textureTarget; ///< Main texture handle GLuint textureTarget; ///< Main texture handle
GLuint attachmentPoint; GLuint attachmentPoint; ///< Point to which an image from texture is attached
} BUFFER_ITEM; } OPENGL_BUFFER;
bool m_initialized; bool m_initialized; ///< Initialization status flag
unsigned int m_current; unsigned int m_current; ///< Currently used buffer handle
GLuint m_framebuffer; ///< Main FBO handle GLuint m_framebuffer; ///< Main FBO handle
GLuint m_depthBuffer; ///< Depth buffer handle GLuint m_depthBuffer; ///< Depth buffer handle
unsigned int m_maxBuffers; ///< Maximal amount of buffers unsigned int m_maxBuffers; ///< Maximal amount of buffers
typedef std::vector<BUFFER_ITEM> Buffers; typedef std::deque<OPENGL_BUFFER> OPENGL_BUFFERS;
Buffers m_buffers;
/// Stores information about initialized buffers
OPENGL_BUFFERS m_buffers;
/// Store the currently used FBO name in case there was more than one compositor used /// Store the currently used FBO name in case there was more than one compositor used
static GLuint m_currentFbo; static GLuint m_currentFbo;
@ -89,7 +88,7 @@ protected:
*/ */
void clean(); void clean();
///< Returns number of used buffers /// Returns number of used buffers
unsigned int usedBuffers() unsigned int usedBuffers()
{ {
return m_buffers.size(); return m_buffers.size();