Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 
12 namespace Ra {
13 namespace Headless {
14 using namespace gl;
15 using namespace glbinding;
16 
17 static 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 
22 GlfwOpenGLContext::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 }
98 GlfwOpenGLContext::~GlfwOpenGLContext() {
99  glfwTerminate();
100 }
101 void GlfwOpenGLContext::makeCurrent() const {
102  if ( m_glfwContext ) { glfwMakeContextCurrent( m_glfwContext ); }
103 }
104 
105 void GlfwOpenGLContext::doneCurrent() const {
106  if ( m_glfwContext ) { glfwMakeContextCurrent( nullptr ); }
107 }
108 
109 bool GlfwOpenGLContext::isValid() const {
110  return m_glfwContext != nullptr;
111 }
112 
113 std::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 
120 void GlfwOpenGLContext::show( EventMode mode, float delay ) {
121  m_mode = mode;
122  m_delay = delay;
123  glfwShowWindow( m_glfwContext );
124 }
125 
126 void GlfwOpenGLContext::hide() {
127  glfwHideWindow( m_glfwContext );
128 }
129 
130 void GlfwOpenGLContext::resize( const std::array<int, 2>& size ) {
131  glfwSetWindowSize( m_glfwContext, size[0], size[1] );
132 }
133 
134 bool 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 
152 void 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
Definition: Cage.cpp:3