Commit 618a5f0e authored by Maciej Suminski's avatar Maciej Suminski

OpenGL multitarget rendering (compositing).

parent a8f47913
......@@ -29,11 +29,15 @@ add_custom_target(
)
set(GAL_SRCS
# Common part
drawpanel_gal.cpp
painter.cpp
gal/graphics_abstraction_layer.cpp
gal/stroke_font.cpp
gal/color4d.cpp
view/wx_view_controls.cpp
# OpenGL GAL
gal/opengl/opengl_gal.cpp
gal/opengl/shader.cpp
gal/opengl/vertex_item.cpp
......@@ -42,8 +46,10 @@ set(GAL_SRCS
gal/opengl/noncached_container.cpp
gal/opengl/vertex_manager.cpp
gal/opengl/gpu_manager.cpp
gal/opengl/opengl_compositor.cpp
# Cairo GAL
gal/cairo/cairo_gal.cpp
view/wx_view_controls.cpp
)
add_library(gal STATIC ${GAL_SRCS})
......
......@@ -280,6 +280,12 @@ void CAIRO_GAL::RestoreScreen()
}
void CAIRO_GAL::SetTarget( RenderTarget aTarget )
{
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
}
void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{
cairo_move_to( cairoImage, aStartPoint.x, aStartPoint.y );
......
......@@ -62,6 +62,8 @@ void GAL::DrawGrid()
if( !gridVisibility )
return;
SetTarget( TARGET_NONCACHED );
// The grid consists of lines
// For the drawing the start points, end points and increments have to be calculated in world coordinates
VECTOR2D screenStartPoint( 0, 0 );
......
......@@ -77,9 +77,11 @@ void GPU_MANAGER::SetShader( SHADER& aShader )
// Cached manager
GPU_CACHED_MANAGER::GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
GPU_MANAGER( aContainer ), m_buffersInitialized( false ), m_indicesPtr( NULL ),
GPU_MANAGER( aContainer ), m_buffersInitialized( false ),
m_indicesSize( 0 )
{
// Allocate the biggest possible buffer for indices
m_indices.reset( new GLuint[aContainer->GetSize()] );
}
......@@ -252,7 +254,6 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
VERTEX* vertices = m_container->GetAllVertices();
GLfloat* coordinates = (GLfloat*) ( vertices );
GLubyte* colors = (GLubyte*) ( vertices ) + ColorOffset;
GLfloat* shaders = (GLfloat*) ( vertices ) + ShaderOffset / sizeof(GLfloat);
// Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY );
......@@ -263,6 +264,8 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
if( m_shader != NULL ) // Use shader if applicable
{
GLfloat* shaders = (GLfloat*) ( vertices ) + ShaderOffset / sizeof(GLfloat);
m_shader->Use();
glEnableVertexAttribArray( m_shaderAttrib );
glVertexAttribPointer( m_shaderAttrib, ShaderStride, GL_FLOAT, GL_FALSE,
......
/*i
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http:O//www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file opengl_compositor.cpp
* @brief Class that handles multitarget rendering (ie. to different textures/surfaces) and
* later compositing into a single image (OpenGL flavour).
*/
#include <gal/opengl/opengl_compositor.h>
#include <wx/log.h>
using namespace KiGfx;
OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
m_initialized( false ), m_current( 0 )
{
}
OPENGL_COMPOSITOR::~OPENGL_COMPOSITOR()
{
if( m_initialized )
clean();
}
void OPENGL_COMPOSITOR::Initialize()
{
if( m_initialized )
return;
// Get the maximum number of buffers
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &m_maxBuffers );
// We need framebuffer objects for drawing the screen contents
// Generate framebuffer and a depth buffer
glGenFramebuffers( 1, &m_framebuffer );
glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer );
m_currentFbo = m_framebuffer;
// Allocate memory for the depth buffer
// Attach the depth buffer to the framebuffer
glGenRenderbuffers( 1, &m_depthBuffer );
glBindRenderbuffer( GL_RENDERBUFFER, m_depthBuffer );
// Use here a size of 24 bits for the depth buffer, 8 bits for the stencil buffer
// this is required later for anti-aliasing
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, m_depthBuffer );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, m_depthBuffer );
// Check the status, exit if the framebuffer can't be created
GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if( status != GL_FRAMEBUFFER_COMPLETE )
{
wxLogFatalError( wxT( "Cannot create the framebuffer." ) );
}
// Unbind the framebuffer, so by default all the rendering goes directly to the display
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
m_initialized = true;
}
void OPENGL_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
{
if( m_initialized )
clean();
m_width = aWidth;
m_height = aHeight;
}
unsigned int OPENGL_COMPOSITOR::GetBuffer()
{
wxASSERT( m_initialized );
if( m_buffers.size() < m_maxBuffers )
{
// GL_COLOR_ATTACHMENTn are consecutive integers
GLuint attachmentPoint = GL_COLOR_ATTACHMENT0 + usedBuffers();
GLuint textureTarget;
// Generate the texture for the pixel storage
glGenTextures( 1, &textureTarget );
glBindTexture( GL_TEXTURE_2D, textureTarget );
// Set texture parameters
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL );
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
glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer );
m_currentFbo = m_framebuffer;
glFramebufferTexture2D( GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, textureTarget, 0 );
ClearBuffer();
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
// Store the new buffer
BUFFER_ITEM buffer = { textureTarget, attachmentPoint };
m_buffers.push_back( buffer );
return usedBuffers();
}
// Unfortunately we have no more buffers left
return 0;
}
void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
{
if( aBufferHandle <= usedBuffers() )
{
// 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 )
{
glDrawBuffer( m_buffers[m_current].attachmentPoint );
m_current = aBufferHandle - 1;
}
}
}
void OPENGL_COMPOSITOR::ClearBuffer()
{
wxASSERT( m_initialized );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
void OPENGL_COMPOSITOR::BlitBuffer( 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 );
// Switch to the main framebuffer and blit the scene
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
// Depth test has to be disabled to make transparency working
glDisable( GL_DEPTH_TEST );
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
// Enable texturing and bind the main texture
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, m_buffers[aBufferHandle - 1].textureTarget );
// Draw a full screen quad with the texture
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLES );
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, -1.0f, aDepth );
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, -1.0f, aDepth );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, aDepth );
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, -1.0f, aDepth );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, aDepth );
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, 1.0f, aDepth );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
void OPENGL_COMPOSITOR::clean()
{
wxASSERT( m_initialized );
glDeleteFramebuffers( 1, &m_framebuffer );
glDeleteRenderbuffers( 1, &m_depthBuffer );
Buffers::const_iterator it;
for( it = m_buffers.begin(); it != m_buffers.end(); ++it )
{
glDeleteTextures( 1, &it->textureTarget );
}
m_buffers.clear();
m_initialized = false;
}
GLuint OPENGL_COMPOSITOR::m_currentFbo = 0;
......@@ -54,7 +54,8 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
wxEXPAND, aName ),
cachedManager( true ),
nonCachedManager( false )
nonCachedManager( false ),
overlayManager( false )
{
// Create the OpenGL-Context
glContext = new wxGLContext( this );
......@@ -67,9 +68,8 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
// Initialize the flags
isDeleteSavedPixels = true;
isGlewInitialized = false;
isFrameBufferInitialized = false;
isFramebufferInitialized = false;
isUseShader = isUseShaders;
isShaderInitialized = false;
isGrouping = false;
......@@ -109,9 +109,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
// Compute the unit circle vertices and store them in a buffer for faster drawing
computeCircle();
// By default we draw non-cached objects, it changes on BeginGroup()/EndGroup()
currentManager = &nonCachedManager;
}
......@@ -119,13 +116,6 @@ OPENGL_GAL::~OPENGL_GAL()
{
glFlush();
// Delete the buffers
if( isFrameBufferInitialized )
{
deleteFrameBuffer( &frameBuffer, &depthBuffer, &texture );
deleteFrameBuffer( &frameBufferBackup, &depthBufferBackup, &textureBackup );
}
gluDeleteTess( tesselator );
ClearCache();
......@@ -143,15 +133,9 @@ void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight )
{
screenSize = VECTOR2D( aWidth, aHeight );
// Delete old buffers for resizing
if( isFrameBufferInitialized )
{
deleteFrameBuffer( &frameBuffer, &depthBuffer, &texture );
deleteFrameBuffer( &frameBufferBackup, &depthBufferBackup, &textureBackup );
// This flag is used for recreating the buffers
isFrameBufferInitialized = false;
}
// Resize framebuffers
compositor.Resize( aWidth, aHeight );
isFramebufferInitialized = false;
wxGLCanvas::SetSize( aWidth, aHeight );
}
......@@ -165,86 +149,35 @@ void OPENGL_GAL::skipMouseEvent( wxMouseEvent& aEvent )
}
void OPENGL_GAL::generateFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer,
GLuint* aTexture )
{
// We need frame buffer objects for drawing the screen contents
// Generate frame buffer and a depth buffer
glGenFramebuffersEXT( 1, aFrameBuffer );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *aFrameBuffer );
// Allocate memory for the depth buffer
// Attach the depth buffer to the frame buffer
glGenRenderbuffersEXT( 1, aDepthBuffer );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *aDepthBuffer );
// Use here a size of 24 bits for the depth buffer, 8 bits for the stencil buffer
// this is required later for anti-aliasing
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, screenSize.x,
screenSize.y );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
*aDepthBuffer );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, *aDepthBuffer );
// Generate the texture for the pixel storage
// Attach the texture to the frame buffer
glGenTextures( 1, aTexture );
glBindTexture( GL_TEXTURE_2D, *aTexture );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, screenSize.x, screenSize.y, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
*aTexture, 0 );
// Check the status, exit if the frame buffer can't be created
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
{
wxLogError( wxT( "Can't create the frame buffer." ) );
exit( 1 );
}
isFrameBufferInitialized = true;
}
void OPENGL_GAL::deleteFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture )
{
glDeleteFramebuffers( 1, aFrameBuffer );
glDeleteRenderbuffers( 1, aDepthBuffer );
glDeleteTextures( 1, aTexture );
}
void OPENGL_GAL::initFrameBuffers()
void OPENGL_GAL::SaveScreen()
{
generateFrameBuffer( &frameBuffer, &depthBuffer, &texture );
generateFrameBuffer( &frameBufferBackup, &depthBufferBackup, &textureBackup );
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
}
void OPENGL_GAL::SaveScreen()
void OPENGL_GAL::RestoreScreen()
{
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, frameBufferBackup );
glBindFramebuffer( GL_READ_FRAMEBUFFER, frameBuffer );
glBlitFramebuffer( 0, 0, screenSize.x, screenSize.y, 0, 0, screenSize.x, screenSize.y,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, frameBuffer );
wxASSERT_MSG( false, wxT( "Not implemented yet" ) );
}
void OPENGL_GAL::RestoreScreen()
void OPENGL_GAL::SetTarget( RenderTarget aTarget )
{
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, frameBuffer );
glBindFramebuffer( GL_READ_FRAMEBUFFER, frameBufferBackup );
glBlitFramebuffer( 0, 0, screenSize.x, screenSize.y, 0, 0, screenSize.x, screenSize.y,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST );
switch( aTarget )
{
default:
case TARGET_CACHED:
currentManager = &cachedManager;
break;
case TARGET_NONCACHED:
currentManager = &nonCachedManager;
break;
case TARGET_OVERLAY:
currentManager = &overlayManager;
break;
}
}
......@@ -275,7 +208,7 @@ void OPENGL_GAL::initGlew()
exit( 1 );
}
// Frame buffers have to be supported
// Framebuffers have to be supported
if( !GLEW_ARB_framebuffer_object )
{
wxLogError( wxT( "Framebuffer objects are not supported!" ) );
......@@ -303,8 +236,23 @@ void OPENGL_GAL::BeginDrawing()
if( !isGlewInitialized )
initGlew();
if( !isFrameBufferInitialized )
initFrameBuffers();
if( !isFramebufferInitialized )
{
// Set up the view port
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
// Create the screen transformation
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y );
// Prepare rendering target buffers
compositor.Initialize();
mainBuffer = compositor.GetBuffer();
overlayBuffer = compositor.GetBuffer();
isFramebufferInitialized = true;
}
// Compile the shaders
if( !isShaderInitialized && isUseShader )
......@@ -321,19 +269,18 @@ void OPENGL_GAL::BeginDrawing()
// Make VBOs use shaders
cachedManager.SetShader( shader );
nonCachedManager.SetShader( shader );
overlayManager.SetShader( shader );
isShaderInitialized = true;
}
// Bind the main frame buffer object - all contents are drawn there
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, frameBuffer );
// Disable 2D Textures
glDisable( GL_TEXTURE_2D );
// Enable the depth buffer
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
// Setup blending, required for transparent objects
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
......@@ -341,14 +288,6 @@ void OPENGL_GAL::BeginDrawing()
// Enable smooth lines
glEnable( GL_LINE_SMOOTH );
// Set up the view port
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y );
// Create the screen transformation
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y );
glMatrixMode( GL_MODELVIEW );
// Set up the world <-> screen transformation
......@@ -368,69 +307,34 @@ void OPENGL_GAL::BeginDrawing()
// Set defaults
SetFillColor( fillColor );
SetStrokeColor( strokeColor );
isDeleteSavedPixels = true;
// Prepare buffers for drawing
nonCachedManager.Clear();
overlayManager.Clear();
cachedManager.BeginDrawing();
nonCachedManager.BeginDrawing();
}
void OPENGL_GAL::blitMainTexture( bool aIsClearFrameBuffer )
{
// Don't use blending for the final blitting
glDisable( GL_BLEND );
glColor4d( 1.0, 1.0, 1.0, 1.0 );
// Switch to the main frame buffer and blit the scene
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
if( aIsClearFrameBuffer )
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
// Enable texturing and bind the main texture
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture );
// Draw a full screen quad with the texture
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLES );
glTexCoord2i( 0, 1 );
glVertex3i( -1, -1, 0 );
glTexCoord2i( 1, 1 );
glVertex3i( 1, -1, 0 );
glTexCoord2i( 1, 0 );
glVertex3i( 1, 1, 0 );
glTexCoord2i( 0, 1 );
glVertex3i( -1, -1, 0 );
glTexCoord2i( 1, 0 );
glVertex3i( 1, 1, 0 );
glTexCoord2i( 0, 0 );
glVertex3i( -1, 1, 0 );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
overlayManager.BeginDrawing();
}
void OPENGL_GAL::EndDrawing()
{
// Cached & non-cached containers are rendered to the same buffer
compositor.SetBuffer( mainBuffer );
compositor.ClearBuffer();
nonCachedManager.EndDrawing();
cachedManager.EndDrawing();
// Draw the remaining contents, blit the main texture to the screen, swap the buffers
// Overlay container is rendered to a different buffer
compositor.SetBuffer( overlayBuffer );
compositor.ClearBuffer();
overlayManager.EndDrawing();
// Draw the remaining contents, blit the rendering targets to the screen, swap the buffers
glFlush();
blitMainTexture( true );
compositor.DrawBuffer( mainBuffer, -1.0 );
compositor.DrawBuffer( overlayBuffer, 0.0 );
SwapBuffers();
delete clientDC;
......@@ -530,8 +434,10 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
VECTOR2D( lineLength, -aWidth / 2.0 ) );
// Draw line caps
drawStrokedSemiCircle( VECTOR2D( 0.0, 0.0 ), ( aWidth + lineWidth ) / 2, M_PI / 2 );
drawStrokedSemiCircle( VECTOR2D( lineLength, 0.0 ), ( aWidth + lineWidth ) / 2, -M_PI / 2 );
drawStrokedSemiCircle( VECTOR2D( 0.0, 0.0 ),
( aWidth + lineWidth ) / 2, M_PI / 2 );
drawStrokedSemiCircle( VECTOR2D( lineLength, 0.0 ),
( aWidth + lineWidth ) / 2, -M_PI / 2 );
Restore();
}
......@@ -643,15 +549,16 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
v0 /_\/_\ v1
*/
currentManager->Shader( SHADER_FILLED_CIRCLE, 1.0 );
currentManager->Vertex( aCenterPoint.x - aRadius * sqrt( 3.0f ),
aCenterPoint.y - aRadius, layerDepth ); // v0
currentManager->Vertex( aCenterPoint.x - aRadius * sqrt( 3.0f ), // v0
aCenterPoint.y - aRadius, layerDepth );
currentManager->Shader( SHADER_FILLED_CIRCLE, 2.0 );
currentManager->Vertex( aCenterPoint.x + aRadius* sqrt( 3.0f ),
aCenterPoint.y - aRadius, layerDepth ); // v1
currentManager->Vertex( aCenterPoint.x + aRadius* sqrt( 3.0f ), // v1
aCenterPoint.y - aRadius, layerDepth );
currentManager->Shader( SHADER_FILLED_CIRCLE, 3.0 );
currentManager->Vertex( aCenterPoint.x, aCenterPoint.y + aRadius * 2.0f, layerDepth ); // v2
currentManager->Vertex( aCenterPoint.x, aCenterPoint.y + aRadius * 2.0f, // v2
layerDepth );
}
if( isStrokeEnabled )
......@@ -661,8 +568,8 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]).
and the line width. Shader uses this coordinates to determine if fragments are inside
the circle or not.
and the line width. Shader uses this coordinates to determine if fragments are
inside the circle or not.
v2
/\
//\\
......@@ -670,15 +577,16 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
*/
double outerRadius = aRadius + ( lineWidth / 2 );
currentManager->Shader( SHADER_STROKED_CIRCLE, 1.0, aRadius, lineWidth );
currentManager->Vertex( aCenterPoint.x - outerRadius * sqrt( 3.0f ),
aCenterPoint.y - outerRadius, layerDepth ); // v0
currentManager->Vertex( aCenterPoint.x - outerRadius * sqrt( 3.0f ), // v0
aCenterPoint.y - outerRadius, layerDepth );
currentManager->Shader( SHADER_STROKED_CIRCLE, 2.0, aRadius, lineWidth );
currentManager->Vertex( aCenterPoint.x + outerRadius * sqrt( 3.0f ),
aCenterPoint.y - outerRadius, layerDepth ); // v1
currentManager->Vertex( aCenterPoint.x + outerRadius * sqrt( 3.0f ), // v1
aCenterPoint.y - outerRadius, layerDepth );
currentManager->Shader( SHADER_STROKED_CIRCLE, 3.0, aRadius, lineWidth );
currentManager->Vertex( aCenterPoint.x, aCenterPoint.y + outerRadius * 2.0f, layerDepth ); // v2
currentManager->Vertex( aCenterPoint.x, aCenterPoint.y + outerRadius * 2.0f, // v2
layerDepth );
}
}
else
......@@ -716,7 +624,8 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
if( i % 3 == 0 )
{
i++;
// Depending on the vertex, next circle point may be stored in the next vertex..
// Depending on the vertex, next circle point
// may be stored in the next vertex..
next = i + 1;
}
else
......@@ -750,7 +659,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
}
}
// Filled circles are easy to draw by using the stored vertices list, scaling and translating
// Filled circles are easy to draw by using the stored vertices list
if( isFillEnabled )
{
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
......@@ -790,8 +699,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
/* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle.
Parameters given to setShader are indices of the triangle's vertices
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]).
Shader uses this coordinates to determine if fragments are inside the semicircle or not.
v2
......@@ -800,13 +709,13 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad
v0 //__\\ v1
*/
currentManager->Shader( SHADER_FILLED_CIRCLE, 4.0f );
currentManager->Vertex( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
currentManager->Vertex( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
currentManager->Shader( SHADER_FILLED_CIRCLE, 5.0f );
currentManager->Vertex( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
currentManager->Vertex( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
currentManager->Shader( SHADER_FILLED_CIRCLE, 6.0f );
currentManager->Vertex( 0.0f, aRadius * 2.0f, layerDepth ); // v2
currentManager->Vertex( 0.0f, aRadius * 2.0f, layerDepth ); // v2
Restore();
}
......@@ -836,8 +745,8 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f );
currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f );
/* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle.
Parameters given to setShader are indices of the triangle's vertices
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]), the
radius and the line width. Shader uses this coordinates to determine if fragments are
inside the semicircle or not.
......@@ -847,13 +756,13 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
v0 //__\\ v1
*/
currentManager->Shader( SHADER_STROKED_CIRCLE, 4.0f, aRadius, lineWidth );
currentManager->Vertex( -outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
currentManager->Vertex( -outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
currentManager->Shader( SHADER_STROKED_CIRCLE, 5.0f, aRadius, lineWidth );
currentManager->Vertex( outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
currentManager->Vertex( outerRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
currentManager->Shader( SHADER_STROKED_CIRCLE, 6.0f, aRadius, lineWidth );
currentManager->Vertex( 0.0f, outerRadius * 2.0f, layerDepth ); // v2
currentManager->Vertex( 0.0f, outerRadius * 2.0f, layerDepth ); // v2
Restore();
}
......@@ -957,10 +866,9 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
outerScale += 1.0;
innerScale += 1.0;
double alphaIncrement = 2 * M_PI / CIRCLE_POINTS;
double alphaIncrement = 2.0 * M_PI / CIRCLE_POINTS;
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
for( double alpha = aStartAngle; alpha < aEndAngle; )
{
double v0[] = { cos( alpha ) * innerScale, sin( alpha ) * innerScale };
......@@ -1155,8 +1063,7 @@ void OPENGL_GAL::ClearScreen()
{
// Clear screen
glClearColor( backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
......@@ -1219,7 +1126,6 @@ int OPENGL_GAL::BeginGroup()
isGrouping = true;
boost::shared_ptr<VERTEX_ITEM> newItem( new VERTEX_ITEM( cachedManager ) );
currentManager = &cachedManager;
int groupNumber = getNewGroupNumber();
groups.insert( std::make_pair( groupNumber, newItem ) );
......@@ -1229,8 +1135,6 @@ int OPENGL_GAL::BeginGroup()
void OPENGL_GAL::EndGroup()
{
currentManager = &nonCachedManager;
isGrouping = false;
}
......@@ -1399,6 +1303,8 @@ VECTOR2D OPENGL_GAL::ComputeCursorToWorld( const VECTOR2D& aCursorPosition )
void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition )
{
wxLogWarning( wxT( "Not tested ") );
SetCurrent( *glContext );
// Draw the cursor on the surface
......@@ -1409,14 +1315,12 @@ void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition )
aCursorPosition = worldScreenMatrix * cursorPositionWorld;
// Switch to the main frame buffer and blit the scene
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Switch to the main framebuffer and blit the scene
//glBindFramebuffer( GL_FRAMEBUFFER, 0 );
//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
blitMainTexture( false );
glDisable( GL_TEXTURE_2D );
glColor4d( cursorColor.r, cursorColor.g, cursorColor.b, cursorColor.a );
......
......@@ -43,14 +43,14 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
{
if( m_layers.find( aLayer ) == m_layers.end() )
{
m_layers[aLayer] = VIEW_LAYER();
m_layers[aLayer].id = aLayer;
m_layers[aLayer].items = new VIEW_RTREE();
m_layers[aLayer] = VIEW_LAYER();
m_layers[aLayer].id = aLayer;
m_layers[aLayer].items = new VIEW_RTREE();
m_layers[aLayer].renderingOrder = aLayer;
m_layers[aLayer].enabled = true;
m_layers[aLayer].cached = true;
m_layers[aLayer].isDirty = false;
m_layers[aLayer].displayOnly = aDisplayOnly;
m_layers[aLayer].target = TARGET_CACHED;
}
sortLayers();
......@@ -136,7 +136,7 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LayerItemPair>& aResult )
VIEW::VIEW( bool aIsDynamic ) :
m_enableOrderModifier( false ),
m_scale ( 1.0 ),
m_scale( 1.0 ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic )
......@@ -321,7 +321,7 @@ struct VIEW::updateItemsColor
void VIEW::UpdateLayerColor( int aLayer )
{
// There is no point in updating non-cached layers
if( !m_layers[aLayer].cached )
if( m_layers[aLayer].target != TARGET_CACHED )
return;
BOX2I r;
......@@ -344,7 +344,7 @@ void VIEW::UpdateAllLayersColor()
VIEW_LAYER* l = &( ( *i ).second );
// There is no point in updating non-cached layers
if( !m_layers[l->id].cached )
if( l->target != TARGET_CACHED )
continue;
updateItemsColor visitor( l->id, m_painter, m_gal );
......@@ -376,7 +376,7 @@ struct VIEW::changeItemsDepth
void VIEW::ChangeLayerDepth( int aLayer, int aDepth )
{
// There is no point in updating non-cached layers
if( !m_layers[aLayer].cached )
if( m_layers[aLayer].target != TARGET_CACHED )
return;
BOX2I r;
......@@ -483,7 +483,7 @@ struct VIEW::drawItem
if( !drawCondition )
return;
if( currentLayer->cached )
if( currentLayer->target == TARGET_CACHED )
{
// Draw using cached information or create one
int group = aItem->getGroup( currentLayer->id );
......@@ -521,6 +521,7 @@ void VIEW::redrawRect( const BOX2I& aRect )
{
drawItem drawFunc( this, l );
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
l->items->Query( aRect, drawFunc );
l->isDirty = false;
......@@ -709,8 +710,10 @@ void VIEW::RecacheAllItems( bool aImmediately )
{
VIEW_LAYER* l = & ( ( *i ).second );
if( l->cached )
// Obviously, there is only one cached target that has to be recomputed
if( l->target == TARGET_CACHED )
{
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
recacheLayer visitor( this, m_gal, l->id, aImmediately );
l->items->Query( r, visitor );
......
......@@ -252,6 +252,9 @@ public:
/// @copydoc GAL::RestoreScreen()
virtual void RestoreScreen();
/// @copydoc GAL::SetTarget()
virtual void SetTarget( RenderTarget aTarget );
// -------
// Cursor
// -------
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file compositor.h
* @brief Class that handles multitarget rendering (ie. to different textures/surfaces) and
* later compositing into a single image.
*/
#ifndef COMPOSITOR_H_
#define COMPOSITOR_H_
namespace KiGfx
{
class COMPOSITOR
{
public:
virtual ~COMPOSITOR()
{
}
/**
* Function Reset()
* performs primary initialiation, necessary to use the object.
*/
virtual void Initialize() = 0;
/**
* Function Resize()
* clears the state of COMPOSITOR, so it has to be reinitialized again with the new dimensions.
*
* @param aWidth is the framebuffer width (in pixels).
* @param aHeight is the framebuffer height (in pixels).
*/
virtual void Resize( unsigned int aWidth, unsigned int aHeight ) = 0;
/**
* Function GetBuffer()
* prepares a new buffer that may be used as a rendering target.
*
* @return is the handle of the buffer. In case of failure 0 (zero) is returned as the handle.
*/
virtual unsigned int GetBuffer() = 0;
/**
* Function SetBuffer()
* sets the selected buffer as the rendering target. All the following drawing functions are
* going to be rendered in the selected buffer.
*
* @param aBufferHandle is the handle of the buffer or 0 in case of rendering directly to the
* display.
*/
virtual void SetBuffer( unsigned int aBufferHandle ) = 0;
/**
* Function ClearBuffer()
* clears the selected buffer (set by the SetBuffer() function).
*/
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()
* draws the selected buffer on the screen.
*
* @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;
protected:
unsigned int m_width; ///< Width of the buffer (in pixels)
unsigned int m_height; ///< Height of the buffer (in pixels)
};
} // namespace KiGfx
#endif /* COMPOSITOR_H_ */
......@@ -31,4 +31,17 @@
#define SWAP( varA, condition, varB ) if( varA condition varB ) { double tmp = varA; varA = varB; \
varB = tmp; }
namespace KiGfx
{
/**
* RenderTarget: Possible rendering targets
*/
enum RenderTarget
{
TARGET_CACHED, ///< Main rendering target (cached)
TARGET_NONCACHED, ///< Auxiliary rendering target (noncached)
TARGET_OVERLAY ///< Items that may change while the view stays the same (noncached)
};
}
#endif /* DEFINITIONS_H_ */
......@@ -35,6 +35,7 @@
#include <math/matrix3x3.h>
#include <gal/color4d.h>
#include <gal/definitions.h>
#include <gal/stroke_font.h>
#include <newstroke_font.h>
......@@ -546,16 +547,27 @@ public:
return worldScale;
}
// ---------------------------
// Buffer manipulation methods
// ---------------------------
/**
* @brief Save the screen contents.
*/
virtual void SaveScreen() = 0;
/**
* @brief Save the screen contents.
* @brief Restore the screen contents.
*/
virtual void RestoreScreen() = 0;
/**
* @brief Sets the target for rendering.
*
* @param aTarget is the new target for rendering.
*/
virtual void SetTarget( RenderTarget aTarget ) = 0;
// -------------
// Grid methods
// -------------
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file opengl_compositor.h
* @brief Class that handles multitarget rendering (ie. to different textures/surfaces) and
* later compositing into a single image (OpenGL flavour).
*/
#ifndef OPENGL_COMPOSITOR_H_
#define OPENGL_COMPOSITOR_H_
#include <gal/compositor.h>
#include <GL/glew.h>
#include <vector>
namespace KiGfx
{
class OPENGL_COMPOSITOR : public COMPOSITOR
{
public:
OPENGL_COMPOSITOR();
virtual ~OPENGL_COMPOSITOR();
///< @copydoc COMPOSITOR::Initialize()
virtual void Initialize();
///< @copydoc COMPOSITOR::Resize()
virtual void Resize( unsigned int aWidth, unsigned int aHeight );
///< @copydoc COMPOSITOR::GetBuffer()
virtual unsigned int GetBuffer();
///< @copydoc COMPOSITOR::SetBuffer()
virtual void SetBuffer( unsigned int aBufferHandle );
///< @copydoc COMPOSITOR::ClearBuffer()
virtual void ClearBuffer();
///< @copydoc COMPOSITOR::BlitBuffer()
virtual void BlitBuffer( unsigned int aBufferHandle );
///< @copydoc COMPOSITOR::DrawBuffer()
virtual void DrawBuffer( unsigned int aBufferHandle, double aDepth );
protected:
typedef struct
{
GLuint textureTarget; ///< Main texture handle
GLuint attachmentPoint;
} BUFFER_ITEM;
bool m_initialized;
unsigned int m_current;
GLuint m_framebuffer; ///< Main FBO handle
GLuint m_depthBuffer; ///< Depth buffer handle
unsigned int m_maxBuffers; ///< Maximal amount of buffers
typedef std::vector<BUFFER_ITEM> Buffers;
Buffers m_buffers;
/// Store the currently used FBO name in case there was more than one compositor used
static GLuint m_currentFbo;
/**
* Function clean()
* performs freeing of resources.
*/
void clean();
///< Returns number of used buffers
unsigned int usedBuffers()
{
return m_buffers.size();
}
};
} // namespace KiGfx
#endif /* COMPOSITOR_H_ */
......@@ -35,6 +35,7 @@
#include <gal/opengl/vertex_manager.h>
#include <gal/opengl/vertex_item.h>
#include <gal/opengl/noncached_container.h>
#include <gal/opengl/opengl_compositor.h>
#include <wx/wx.h>
#include <wx/glcanvas.h>
......@@ -268,6 +269,9 @@ public:
/// @copydoc GAL::RestoreScreen()
virtual void RestoreScreen();
/// @copydoc GAL::SetTarget()
virtual void SetTarget( RenderTarget aTarget );
// -------
// Cursor
// -------
......@@ -328,8 +332,8 @@ private:
wxEvtHandler* mouseListener;
wxEvtHandler* paintListener;
// VBO buffered vertices for faster circle & semicircle drawing
NONCACHED_CONTAINER circleContainer; ///< Container for storing circle vertices
// Precomputed vertices for faster circle & semicircle drawing
NONCACHED_CONTAINER circleContainer; ///< Container for storing circle vertices
// Vertex buffer objects related fields
typedef std::map< unsigned int, boost::shared_ptr<VERTEX_ITEM> > GroupsMap;
......@@ -338,6 +342,12 @@ private:
VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
VERTEX_MANAGER cachedManager; ///< Container for storing cached VERTEX_ITEMs
VERTEX_MANAGER nonCachedManager; ///< Container for storing non-cached VERTEX_ITEMs
VERTEX_MANAGER overlayManager; ///< Container for storing overlaid VERTEX_ITEMs
// Framebuffer & compositing
OPENGL_COMPOSITOR compositor; ///< Handles multiple rendering targets
unsigned int mainBuffer; ///< Main rendering target
unsigned int overlayBuffer; ///< Auxiliary rendering target (for menus etc.)
// Polygon tesselation
GLUtesselator* tesselator; ///< Pointer to the tesselator
......@@ -350,20 +360,11 @@ private:
int cursorSize; ///< Size of the cursor in pixels
GLubyte* cursorShape; ///< Cursor pixel storage
GLubyte* cursorSave; ///< Saved cursor pixels
bool isDeleteSavedPixels; ///< Flag for deleting saved pixels
VECTOR2D savedCursorPosition; ///< Last saved cursor position
// Frame buffer
GLuint frameBuffer; ///< Main FBO handle
GLuint depthBuffer; ///< Depth buffer handle
GLuint texture; ///< Main texture handle
GLuint frameBufferBackup; ///< Backup FBO handle
GLuint depthBufferBackup; ///< Backup depth buffer handle
GLuint textureBackup; ///< Backup texture handle
// Internal flags
bool isGlewInitialized; ///< Is GLEW initialized?
bool isFrameBufferInitialized; ///< Are the frame buffers initialized?
bool isFramebufferInitialized; ///< Are the framebuffers initialized?
bool isShaderInitialized; ///< Was the shader initialized?
bool isUseShader; ///< Should the shaders be used?
bool isGrouping; ///< Was a group started?
......@@ -434,34 +435,6 @@ private:
*/
void initCursor( int aCursorSize );
/**
* @brief Blit the main texture to the screen.
*
* @param aIsClearFrameBuffer if true, the frame buffer is cleared as well.
*/
void blitMainTexture( bool aIsClearFrameBuffer );
/// @brief Initialize the frame buffers for main contents and backup storage.
void initFrameBuffers();
/**
* @brief Generate a frame buffer for the screen contents.
*
* @param aFrameBuffer is the pointer to the frame buffer handle.
* @param aDepthBuffer is the pointer to the depth buffer handle.
* @param aTexture is the pointer to the texture handle.
*/
void generateFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture );
/**
* @brief Delete the frame buffer for the screen contents.
*
* @param aFrameBuffer is the pointer to the frame buffer handle.
* @param aDepthBuffer is the pointer to the depth buffer handle.
* @param aTexture is the pointer to the texture handle.
*/
void deleteFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture );
/**
* @brief Draw a quad for the line.
*
......
......@@ -43,7 +43,7 @@ enum SHADER_TYPE
SHADER_STROKED_CIRCLE,
};
typedef struct VERTEX
typedef struct
{
GLfloat x, y, z; // Coordinates
GLubyte r, g, b, a; // Color
......
......@@ -34,7 +34,6 @@
namespace KiGfx
{
class VERTEX;
class VERTEX_ITEM;
class SHADER;
......
......@@ -30,6 +30,7 @@
#include <boost/unordered/unordered_map.hpp>
#include <math/box2.h>
#include <gal/definitions.h>
namespace KiGfx
{
......@@ -258,14 +259,14 @@ public:
}
/**
* Function SetLayerCached()
* Turns on or off the cached parameter of a particular layer.
* @param aLayer: the layer
* @param aCached: the new parameter value
* Function SetLayerTarget()
* Changes the rendering target for a particular layer.
* @param aLayer is the layer.
* @param aTarget is the rendering target.
*/
inline void SetLayerCached( int aLayer, bool aCached = true )
inline void SetLayerTarget( int aLayer, RenderTarget aTarget )
{
m_layers[aLayer].cached = aCached;
m_layers[aLayer].target = aTarget;
}
/**
......@@ -367,14 +368,13 @@ private:
bool enabled; ///* is the layer to be rendered?
bool isDirty; ///* does it contain any dirty items (updated since last redraw)
bool displayOnly; ///* is the layer display only?
bool cached; ///* items on non-cached layers are displayed in
///* immediate mode
VIEW_RTREE* items; ///* R-tree indexing all items on this layer.
std::vector<VIEW_ITEM*> dirtyItems; ///* set of dirty items collected since last redraw
int renderingOrder; ///* rendering order of this layer
int id; ///* layer ID
BOX2I extents; ///* sum of bboxes of all items on the layer
BOX2I dirtyExtents; ///* sum of bboxes of all dirty items on the layer
RenderTarget target; ///* where the layer should be rendered
};
// Convenience typedefs
......
......@@ -207,7 +207,7 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
// so there is no point in caching them
for( LAYER_NUM layer = FIRST_NETNAME_LAYER; layer <= LAST_NETNAME_LAYER; ++layer )
{
view->SetLayerCached( layer, false );
view->SetLayerTarget( layer, KiGfx::TARGET_NONCACHED );
}
// Load layer & elements visibility settings
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment