Better way to determine supported OpenGL version and extensions.
This commit is contained in:
parent
9a6a3c8b58
commit
709697ea40
|
@ -36,46 +36,29 @@
|
|||
#endif /* __WXDEBUG__ */
|
||||
|
||||
#include <limits>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
// Prototypes
|
||||
void InitTesselatorCallbacks( GLUtesselator* aTesselator );
|
||||
|
||||
static void InitTesselatorCallbacks( GLUtesselator* aTesselator );
|
||||
const int glAttributes[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0 };
|
||||
|
||||
wxGLContext* OPENGL_GAL::glContext = NULL;
|
||||
|
||||
OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
||||
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
|
||||
wxEXPAND, aName ),
|
||||
parentWindow( aParent ),
|
||||
mouseListener( aMouseListener ),
|
||||
paintListener( aPaintListener ),
|
||||
cachedManager( true ),
|
||||
nonCachedManager( false ),
|
||||
overlayManager( false )
|
||||
{
|
||||
// Create the OpenGL-Context
|
||||
if( glContext == NULL )
|
||||
glContext = new wxGLContext( this );
|
||||
|
||||
aParent->Show(); // wxWidgets require the window to be visible to set its GL context
|
||||
|
||||
// Initialize GLEW, FBOs & VBOs
|
||||
SetCurrent( *glContext );
|
||||
initGlew();
|
||||
|
||||
// Prepare shaders
|
||||
if( !shader.LoadBuiltinShader( 0, SHADER_TYPE_VERTEX ) )
|
||||
throw std::runtime_error( "Cannot compile vertex shader!" );
|
||||
|
||||
if( !shader.LoadBuiltinShader( 1, SHADER_TYPE_FRAGMENT ) )
|
||||
throw std::runtime_error( "Cannot compile fragment shader!" );
|
||||
|
||||
if( !shader.Link() )
|
||||
throw std::runtime_error( "Cannot link the shaders!" );
|
||||
// Check if OpenGL requirements are met
|
||||
runTest();
|
||||
|
||||
// Make VBOs use shaders
|
||||
cachedManager.SetShader( shader );
|
||||
|
@ -145,7 +128,8 @@ void OPENGL_GAL::BeginDrawing()
|
|||
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 );
|
||||
glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y,
|
||||
-depthRange.x, -depthRange.y );
|
||||
|
||||
if( !isFramebufferInitialized )
|
||||
{
|
||||
|
@ -914,37 +898,6 @@ void OPENGL_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::initGlew()
|
||||
{
|
||||
// Initialize GLEW library
|
||||
GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
throw std::runtime_error( (const char*) glewGetErrorString( err ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug( wxString( wxT( "Status: Using GLEW " ) ) +
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
// Check the OpenGL version (minimum 2.1 is required)
|
||||
if( GLEW_VERSION_2_1 )
|
||||
wxLogInfo( wxT( "OpenGL 2.1 supported." ) );
|
||||
else
|
||||
throw std::runtime_error( "OpenGL 2.1 or higher is required!" );
|
||||
|
||||
// Framebuffers have to be supported
|
||||
if( !GLEW_EXT_framebuffer_object )
|
||||
throw std::runtime_error( "Framebuffer objects are not supported!" );
|
||||
|
||||
// Vertex buffer has to be supported
|
||||
if( !GLEW_ARB_vertex_buffer_object )
|
||||
throw std::runtime_error( "Vertex buffer objects are not supported!" );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::blitCursor()
|
||||
{
|
||||
if( !isCursorEnabled )
|
||||
|
@ -984,11 +937,112 @@ unsigned int OPENGL_GAL::getNewGroupNumber()
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// Callback functions for the tesselator
|
||||
// -------------------------------------
|
||||
bool OPENGL_GAL::runTest()
|
||||
{
|
||||
wxDialog* dialog = new wxDialog( GetParent(), -1, wxT( "opengl test" ),
|
||||
wxPoint( 50, 50 ), wxSize( 50, 50 ) );
|
||||
OPENGL_TEST* test = new OPENGL_TEST( dialog, this );
|
||||
|
||||
// Compare Redbook Chapter 11
|
||||
dialog->ShowModal();
|
||||
bool result = test->IsOk();
|
||||
|
||||
if( !result )
|
||||
throw std::runtime_error( test->GetError() );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
OPENGL_GAL::OPENGL_TEST::OPENGL_TEST( wxDialog* aParent, OPENGL_GAL* aGal ) :
|
||||
wxGLCanvas( aParent, wxID_ANY, glAttributes, wxDefaultPosition,
|
||||
wxDefaultSize, 0, wxT( "GLCanvas" ) ),
|
||||
m_parent( aParent ), m_gal( aGal ), m_tested( false ), m_result( false )
|
||||
{
|
||||
Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::OPENGL_TEST::Render ) );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::OPENGL_TEST::Render( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
{
|
||||
if( !m_tested )
|
||||
{
|
||||
m_result = true; // Assume everything is fine, until proven otherwise
|
||||
|
||||
// One test is enough - close the testing dialog when the test is finished
|
||||
Disconnect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::OPENGL_TEST::Render ) );
|
||||
CallAfter( boost::bind( &wxDialog::EndModal, m_parent, wxID_NONE ) );
|
||||
|
||||
SetCurrent( *OPENGL_GAL::glContext );
|
||||
GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
error( (const char*) glewGetErrorString( err ) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug( wxString( wxT( "Status: Using GLEW " ) ) +
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
// Check the OpenGL version (minimum 2.1 is required)
|
||||
if( GLEW_VERSION_2_1 )
|
||||
{
|
||||
wxLogInfo( wxT( "OpenGL 2.1 supported." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
error( "OpenGL 2.1 or higher is required!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Framebuffers have to be supported
|
||||
if( !GLEW_EXT_framebuffer_object )
|
||||
{
|
||||
error( "Framebuffer objects are not supported!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Vertex buffer has to be supported
|
||||
if( !GLEW_ARB_vertex_buffer_object )
|
||||
{
|
||||
error( "Vertex buffer objects are not supported!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare shaders
|
||||
if( !m_gal->shader.LoadBuiltinShader( 0, SHADER_TYPE_VERTEX ) )
|
||||
{
|
||||
error( "Cannot compile vertex shader!" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_gal->shader.LoadBuiltinShader( 1, SHADER_TYPE_FRAGMENT ) )
|
||||
{
|
||||
error( "Cannot compile fragment shader!" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_gal->shader.Link() )
|
||||
{
|
||||
error( "Cannot link the shaders!" );
|
||||
return;
|
||||
}
|
||||
|
||||
m_tested = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::OPENGL_TEST::error(const std::string& aError )
|
||||
{
|
||||
m_result = false;
|
||||
m_tested = true;
|
||||
m_error = aError;
|
||||
}
|
||||
|
||||
// ------------------------------------- // Callback functions for the tesselator // ------------------------------------- // Compare Redbook Chapter 11
|
||||
void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
|
||||
{
|
||||
GLdouble* vertex = static_cast<GLdouble*>( aVertexPtr );
|
||||
|
@ -1029,7 +1083,7 @@ void CALLBACK ErrorCallback( GLenum aErrorCode )
|
|||
}
|
||||
|
||||
|
||||
void InitTesselatorCallbacks( GLUtesselator* aTesselator )
|
||||
static void InitTesselatorCallbacks( GLUtesselator* aTesselator )
|
||||
{
|
||||
gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback );
|
||||
gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback );
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2013 CERN
|
||||
* Copyright (C) 2013-2015 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) for OpenGL
|
||||
|
@ -55,7 +55,7 @@ class SHADER;
|
|||
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
|
||||
*
|
||||
* This is a direct OpenGL-implementation and uses low-level graphics primitives like triangles
|
||||
* and quads. The purpuse is to provide a fast graphics interface, that takes advantage of modern
|
||||
* and quads. The purpose is to provide a fast graphics interface, that takes advantage of modern
|
||||
* graphics card GPUs. All methods here benefit thus from the hardware acceleration.
|
||||
*/
|
||||
class OPENGL_GAL : public GAL, public wxGLCanvas
|
||||
|
@ -254,7 +254,6 @@ private:
|
|||
|
||||
wxClientDC* clientDC; ///< Drawing context
|
||||
static wxGLContext* glContext; ///< OpenGL context of wxWidgets
|
||||
wxWindow* parentWindow; ///< Parent window
|
||||
wxEvtHandler* mouseListener;
|
||||
wxEvtHandler* paintListener;
|
||||
|
||||
|
@ -340,9 +339,6 @@ private:
|
|||
*/
|
||||
void skipMouseEvent( wxMouseEvent& aEvent );
|
||||
|
||||
/// Initialize GLEW
|
||||
void initGlew();
|
||||
|
||||
/**
|
||||
* @brief Blits cursor into the current screen.
|
||||
*/
|
||||
|
@ -354,6 +350,34 @@ private:
|
|||
* @return An unique group number that is not used by any other group.
|
||||
*/
|
||||
unsigned int getNewGroupNumber();
|
||||
|
||||
/**
|
||||
* @brief Checks if the required OpenGL version and extensions are supported.
|
||||
* @return true in case of success.
|
||||
*/
|
||||
bool runTest();
|
||||
|
||||
// Helper class to determine OpenGL capabilities
|
||||
class OPENGL_TEST: public wxGLCanvas
|
||||
{
|
||||
public:
|
||||
OPENGL_TEST( wxDialog* aParent, OPENGL_GAL* aGal );
|
||||
void Render( wxPaintEvent& aEvent );
|
||||
inline bool IsTested() const { return m_tested; }
|
||||
inline bool IsOk() const { return m_result && m_tested; }
|
||||
inline std::string GetError() const { return m_error; }
|
||||
|
||||
private:
|
||||
void error( const std::string& aError );
|
||||
|
||||
wxDialog* m_parent;
|
||||
OPENGL_GAL* m_gal;
|
||||
bool m_tested;
|
||||
bool m_result;
|
||||
std::string m_error;
|
||||
};
|
||||
|
||||
friend class OPENGL_TEST;
|
||||
};
|
||||
} // namespace KIGFX
|
||||
|
||||
|
|
Loading…
Reference in New Issue