Radium Engine  1.5.20
Loading...
Searching...
No Matches
GlfwOpenGLContext.cpp
1#ifdef HEADLESS_HAS_GLFW
2# include <Headless/OpenGLContext/GlfwOpenGLContext.hpp>
3
4# include <GLFW/glfw3.h>
5
6# include <glbinding-aux/ValidVersions.h>
7# include <glbinding/glbinding.h>
8# include <globjects/globjects.h>
9
10# include <iostream>
11
12namespace Ra {
13namespace Headless {
14using namespace gl;
15using namespace glbinding;
16
17static void error( int errnum, const char* errmsg ) {
18 std::cerr << "GlfwOpenGLContext::GLFW error -- "
19 << "0x" << std::hex << errnum << std::dec << ": " << errmsg << std::endl;
20}
21
22GlfwOpenGLContext::GlfwOpenGLContext( const glbinding::Version& glVersion,
23 const std::array<int, 2>& size ) :
24 OpenGLContext( glVersion, size ) {
25 // initialize openGL
26 if ( glfwInit() ) {
27 glfwSetErrorCallback( error );
28 glfwDefaultWindowHints();
29 glfwWindowHint( GLFW_VISIBLE, false );
30 glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, glVersion.majorVersion() );
31 glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, glVersion.minorVersion() );
32 glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, true );
33 glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
34 m_glfwContext =
35 glfwCreateWindow( size[0], size[1], "Radium CommandLine Context", nullptr, nullptr );
36 }
37 const char* description;
38 int code = glfwGetError( &description );
39 if ( code == GLFW_VERSION_UNAVAILABLE ) {
40 // if the requested opengl version is not available, try to get the recommended version
41 // (4.1)
42 glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
43 glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );
44 m_glfwContext =
45 glfwCreateWindow( size[0], size[1], "Radium CommandLine Context", nullptr, nullptr );
46 code = glfwGetError( &description );
47 }
48 if ( code != GLFW_NO_ERROR ) {
49 std::cerr << "OpenGL context creation failed. Terminate execution." << std::endl;
50 error( code, description );
51 glfwTerminate();
52 std::exit( -1 );
53 }
54 else {
55 // Initialize globjects (internally initializes glbinding, and registers the current
56 // context)
57 glfwMakeContextCurrent( m_glfwContext );
58 globjects::init( []( const char* name ) { return glfwGetProcAddress( name ); } );
59 glfwSetWindowUserPointer( m_glfwContext, this );
60 auto resizeCB = []( GLFWwindow* window, int width, int height ) {
61 auto context = static_cast<GlfwOpenGLContext*>( glfwGetWindowUserPointer( window ) );
62 context->resizeFrameBuffer( width, height );
63 };
64 glfwSetFramebufferSizeCallback( m_glfwContext, resizeCB );
65 auto keyCB = []( GLFWwindow* window, int key, int scancode, int action, int mods ) {
66 auto context = static_cast<GlfwOpenGLContext*>( glfwGetWindowUserPointer( window ) );
67 context->keyboardEventCallback( key, scancode, action, mods );
68 };
69 glfwSetKeyCallback( m_glfwContext, keyCB );
70
71 auto mouseCB = []( GLFWwindow* window, int button, int action, int mods ) {
72 auto context = static_cast<GlfwOpenGLContext*>( glfwGetWindowUserPointer( window ) );
73 // see https://www.glfw.org/docs/latest/window_guide.html#window_scale
74 float xscale, yscale;
75 glfwGetWindowContentScale( window, &xscale, &yscale );
76 // seems that the scale is not to be taken into account
77 double xpos, ypos;
78 glfwGetCursorPos( window, &xpos, &ypos );
79 context->mouseEventCallback( button, action, mods, int( xpos ), int( ypos ) );
80 };
81 glfwSetMouseButtonCallback( m_glfwContext, mouseCB );
82
83 auto scrollCB = []( GLFWwindow* window, double xoffset, double yoffset ) {
84 auto context = static_cast<GlfwOpenGLContext*>( glfwGetWindowUserPointer( window ) );
85 float xscale, yscale;
86 glfwGetWindowContentScale( window, &xscale, &yscale );
87 context->scrollEventCallback( int( xoffset ), int( yoffset ) );
88 };
89 glfwSetScrollCallback( m_glfwContext, scrollCB );
90
91 auto mouseMoveCB = []( GLFWwindow* window, double xpos, double ypos ) {
92 auto context = static_cast<GlfwOpenGLContext*>( glfwGetWindowUserPointer( window ) );
93 context->mouseMoveEventCallback( int( xpos ), int( ypos ) );
94 };
95 glfwSetCursorPosCallback( m_glfwContext, mouseMoveCB );
96 }
97}
98GlfwOpenGLContext::~GlfwOpenGLContext() {
99 glfwTerminate();
100}
101void GlfwOpenGLContext::makeCurrent() const {
102 if ( m_glfwContext ) { glfwMakeContextCurrent( m_glfwContext ); }
103}
104
105void GlfwOpenGLContext::doneCurrent() const {
106 if ( m_glfwContext ) { glfwMakeContextCurrent( nullptr ); }
107}
108
109bool GlfwOpenGLContext::isValid() const {
110 return m_glfwContext != nullptr;
111}
112
113std::string GlfwOpenGLContext::getInfo() const {
114 auto generalInfo = OpenGLContext::getInfo();
115 std::stringstream infoText;
116 infoText << generalInfo << "Context provider : GLFW\n";
117 return infoText.str();
118}
119
120void GlfwOpenGLContext::show( EventMode mode, float delay ) {
121 m_mode = mode;
122 m_delay = delay;
123 glfwShowWindow( m_glfwContext );
124}
125
126void GlfwOpenGLContext::hide() {
127 glfwHideWindow( m_glfwContext );
128}
129
130void GlfwOpenGLContext::resize( const std::array<int, 2>& size ) {
131 glfwSetWindowSize( m_glfwContext, size[0], size[1] );
132}
133
134bool GlfwOpenGLContext::processEvents() {
135 switch ( m_mode ) {
136 case EventMode::POLL:
137 glfwPollEvents();
138 break;
139 case EventMode::WAIT:
140 glfwWaitEvents();
141 break;
142 case EventMode::TIMEOUT:
143 glfwWaitEventsTimeout( m_delay );
144 break;
145 default:
146 glfwPollEvents();
147 break;
148 }
149 return true;
150}
151
152void GlfwOpenGLContext::renderLoop( std::function<void( float )> render ) {
153 double prevFrameDate = glfwGetTime();
154 double curFrameDate;
155
156 int width, height;
157 glfwGetFramebufferSize( m_glfwContext, &width, &height );
158 glViewport( 0, 0, width, height );
159
160 while ( !glfwWindowShouldClose( m_glfwContext ) ) {
161 curFrameDate = glfwGetTime();
162 render( curFrameDate - prevFrameDate );
163 prevFrameDate = curFrameDate;
164
165 glfwSwapBuffers( m_glfwContext );
166 processEvents();
167 }
168}
169
170} // namespace Headless
171} // namespace Ra
172#endif
T endl(T... args)
T exit(T... args)
T hex(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
T str(T... args)