1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 #include <dlfcn.h> 25 #include "SDL.h" 26 #include "SDL_ph_gl.h" 27 28 #if SDL_VIDEO_OPENGL 29 30 #if (_NTO_VERSION >= 630) 31 /* PhotonGL functions */ 32 GLPH_DECLARE_FUNCS; 33 #endif /* 6.3.0 */ 34 35 #if (_NTO_VERSION < 630) 36 void ph_GL_SwapBuffers(_THIS) 37 { 38 PgSetRegion(PtWidgetRid(window)); 39 PdOpenGLContextSwapBuffers(oglctx); 40 } 41 #else 42 void ph_GL_SwapBuffers(_THIS) 43 { 44 qnxgl_swap_buffers(oglbuffers); 45 } 46 #endif /* 6.3.0 */ 47 48 int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) 49 { 50 switch (attrib) 51 { 52 case SDL_GL_DOUBLEBUFFER: 53 *value=this->gl_config.double_buffer; 54 break; 55 case SDL_GL_STENCIL_SIZE: 56 *value=this->gl_config.stencil_size; 57 break; 58 case SDL_GL_DEPTH_SIZE: 59 *value=this->gl_config.depth_size; 60 break; 61 #if (_NTO_VERSION >= 630) 62 case SDL_GL_RED_SIZE: 63 *value=this->gl_config.red_size; 64 break; 65 case SDL_GL_GREEN_SIZE: 66 *value=this->gl_config.green_size; 67 break; 68 case SDL_GL_BLUE_SIZE: 69 *value=this->gl_config.blue_size; 70 break; 71 case SDL_GL_ALPHA_SIZE: 72 *value=this->gl_config.alpha_size; 73 break; 74 case SDL_GL_ACCUM_RED_SIZE: 75 *value=this->gl_config.accum_red_size; 76 break; 77 case SDL_GL_ACCUM_GREEN_SIZE: 78 *value=this->gl_config.accum_green_size; 79 break; 80 case SDL_GL_ACCUM_BLUE_SIZE: 81 *value=this->gl_config.accum_blue_size; 82 break; 83 case SDL_GL_ACCUM_ALPHA_SIZE: 84 *value=this->gl_config.accum_alpha_size; 85 break; 86 case SDL_GL_STEREO: 87 *value=this->gl_config.stereo; 88 break; 89 #endif /* 6.3.0 */ 90 default: 91 *value=0; 92 return(-1); 93 } 94 return 0; 95 } 96 97 #if (_NTO_VERSION < 630) 98 int ph_GL_LoadLibrary(_THIS, const char* path) 99 { 100 /* if code compiled with SDL_VIDEO_OPENGL, that mean that library already linked */ 101 this->gl_config.driver_loaded = 1; 102 103 return 0; 104 } 105 #else 106 int ph_GL_LoadLibrary(_THIS, const char* path) 107 { 108 void* handle; 109 int dlopen_flags=RTLD_WORLD | RTLD_GROUP; 110 111 if (this->gl_config.dll_handle!=NULL) 112 { 113 return 0; 114 } 115 116 handle = dlopen(path, dlopen_flags); 117 118 if (handle==NULL) 119 { 120 SDL_SetError("ph_GL_LoadLibrary(): Could not load OpenGL library"); 121 return -1; 122 } 123 124 this->gl_config.dll_handle = handle; 125 this->gl_config.driver_loaded = 1; 126 127 SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path)); 128 129 return 0; 130 } 131 #endif /* 6.3.0 */ 132 133 #if (_NTO_VERSION < 630) 134 void* ph_GL_GetProcAddress(_THIS, const char* proc) 135 { 136 return NULL; 137 } 138 #else 139 void* ph_GL_GetProcAddress(_THIS, const char* proc) 140 { 141 void* function; 142 143 if (this->gl_config.dll_handle==NULL) 144 { 145 ph_GL_LoadLibrary(this, DEFAULT_OPENGL); 146 if (this->gl_config.dll_handle==NULL) 147 { 148 return NULL; 149 } 150 } 151 152 function=qnxgl_get_func(proc, oglctx, 0); 153 if (function==NULL) 154 { 155 function=dlsym(this->gl_config.dll_handle, proc); 156 } 157 158 return function; 159 } 160 #endif /* 6.3.0 */ 161 162 #if (_NTO_VERSION < 630) 163 int ph_GL_MakeCurrent(_THIS) 164 { 165 PgSetRegion(PtWidgetRid(window)); 166 167 if (oglctx!=NULL) 168 { 169 PhDCSetCurrent(oglctx); 170 } 171 172 return 0; 173 } 174 #else 175 int ph_GL_MakeCurrent(_THIS) 176 { 177 PgSetRegion(PtWidgetRid(window)); 178 179 if (oglctx!=NULL) 180 { 181 if (qnxgl_set_current(oglctx) == -1) 182 { 183 return -1; 184 } 185 } 186 187 return 0; 188 } 189 #endif /* 6.3.0 */ 190 191 #if (_NTO_VERSION < 630) 192 193 /* This code is actual for the Photon3D Runtime which was available prior to 6.3 only */ 194 195 int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) 196 { 197 PhDim_t dim; 198 uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS]; 199 int exposepost=0; 200 int OGLargc; 201 202 dim.w=width; 203 dim.h=height; 204 205 if ((oglctx!=NULL) && (oglflags==flags) && (oglbpp==bpp)) 206 { 207 PdOpenGLContextResize(oglctx, &dim); 208 PhDCSetCurrent(oglctx); 209 return 0; 210 } 211 else 212 { 213 if (oglctx!=NULL) 214 { 215 PhDCSetCurrent(NULL); 216 PhDCRelease(oglctx); 217 oglctx=NULL; 218 exposepost=1; 219 } 220 } 221 222 OGLargc=0; 223 if (this->gl_config.depth_size) 224 { 225 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DEPTH_BITS; 226 OGLAttrib[OGLargc++]=this->gl_config.depth_size; 227 } 228 if (this->gl_config.stencil_size) 229 { 230 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_STENCIL_BITS; 231 OGLAttrib[OGLargc++]=this->gl_config.stencil_size; 232 } 233 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW; 234 if (flags & SDL_FULLSCREEN) 235 { 236 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN; 237 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DIRECT; 238 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_BEST; 239 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_CENTER; 240 } 241 OGLAttrib[OGLargc++]=PHOGL_ATTRIB_NONE; 242 243 if (this->gl_config.double_buffer) 244 { 245 oglctx=PdCreateOpenGLContext(2, &dim, 0, OGLAttrib); 246 } 247 else 248 { 249 oglctx=PdCreateOpenGLContext(1, &dim, 0, OGLAttrib); 250 } 251 252 if (oglctx==NULL) 253 { 254 SDL_SetError("ph_SetupOpenGLContext(): cannot create OpenGL context !\n"); 255 return -1; 256 } 257 258 PhDCSetCurrent(oglctx); 259 260 PtFlush(); 261 262 oglflags=flags; 263 oglbpp=bpp; 264 265 if (exposepost!=0) 266 { 267 /* OpenGL context has been recreated, so report about this fact */ 268 SDL_PrivateExpose(); 269 } 270 271 return 0; 272 } 273 274 #else /* _NTO_VERSION */ 275 276 /* This code is actual for the built-in PhGL support, which became available since 6.3 */ 277 278 int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) 279 { 280 qnxgl_buf_attrib_t qnxgl_attribs[PH_OGL_MAX_ATTRIBS]; 281 qnxgl_buf_attrib_t* qnxgl_attribs_slide; 282 int num_interfaces = 0; 283 int num_buffers = 0; 284 285 /* Initialize the OpenGL subsystem */ 286 287 num_interfaces = qnxgl_init(NULL, NULL, 0); 288 289 if (num_interfaces < 0) 290 { 291 SDL_SetError("ph_SetupOpenGLContext(): cannot initialize OpenGL subsystem !\n"); 292 return -1; 293 } 294 if (num_interfaces == 0) 295 { 296 SDL_SetError("ph_SetupOpenGLContext(): there are no available OpenGL renderers was found !\n"); 297 return -1; 298 } 299 300 /* Driver is linked */ 301 this->gl_config.driver_loaded=1; 302 303 /* Initialize the OpenGL context attributes */ 304 qnxgl_attribs_slide=qnxgl_attribs; 305 306 /* Depth size */ 307 if (this->gl_config.depth_size) 308 { 309 fprintf(stderr, "setted depth size %d\n", this->gl_config.depth_size); 310 qnxgl_attribs_slide = qnxgl_attrib_set_depth(qnxgl_attribs_slide, this->gl_config.depth_size); 311 } 312 313 /* Stencil size */ 314 if (this->gl_config.stencil_size) 315 { 316 qnxgl_attribs_slide = qnxgl_attrib_set_stencil(qnxgl_attribs_slide, this->gl_config.stencil_size); 317 } 318 319 /* The sum of the accum bits of each channel */ 320 if ((this->gl_config.accum_red_size != 0) && (this->gl_config.accum_blue_size != 0) && 321 (this->gl_config.accum_green_size != 0)) 322 { 323 qnxgl_attribs_slide = qnxgl_attrib_set_accum(qnxgl_attribs_slide, 324 this->gl_config.accum_red_size + this->gl_config.accum_blue_size + 325 this->gl_config.accum_green_size + this->gl_config.accum_alpha_size); 326 } 327 328 /* Stereo mode */ 329 if (this->gl_config.stereo) 330 { 331 qnxgl_attribs_slide = qnxgl_attrib_set_stereo(qnxgl_attribs_slide); 332 } 333 334 /* Fullscreen mode */ 335 if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) 336 { 337 qnxgl_attribs_slide = qnxgl_attrib_set_hint_fullscreen(qnxgl_attribs_slide); 338 } 339 340 /* Double buffering mode */ 341 if (this->gl_config.double_buffer) 342 { 343 num_buffers=2; 344 } 345 else 346 { 347 num_buffers=1; 348 } 349 350 /* Loading the function pointers so we can use the extensions */ 351 GLPH_LOAD_FUNCS_GC(oglctx); 352 353 /* Set the buffers region to be that of our window's region */ 354 qnxgl_attribs_slide = glph_attrib_set_region(qnxgl_attribs_slide, PtWidgetRid(window)); 355 356 /* End of the attributes array */ 357 qnxgl_attribs_slide = qnxgl_attrib_set_end(qnxgl_attribs_slide); 358 359 /* Create the buffers with the specified color model */ 360 fprintf(stderr, "ARGB: %d, %d, %d, %d\n", this->gl_config.alpha_size, this->gl_config.red_size, this->gl_config.green_size, this->gl_config.blue_size); 361 oglbuffers = qnxgl_buffers_create( 362 QNXGL_FORMAT_BEST_RGB, 363 /* __QNXGL_BUILD_FORMAT(0, __QNXGL_COLOR_MODEL_RGB, this->gl_config.alpha_size, 364 this->gl_config.red_size, this->gl_config.green_size, this->gl_config.blue_size), */ 365 num_buffers, width, height, qnxgl_attribs, -1); 366 367 368 if (oglbuffers == NULL) 369 { 370 SDL_SetError("ph_SetupOpenGLContext(): failed to create OpenGL buffers !\n"); 371 qnxgl_finish(); 372 return -1; 373 } 374 375 /* Create a QNXGL context for the previously created buffer */ 376 oglctx = qnxgl_context_create(oglbuffers, NULL); 377 378 if (oglctx == NULL) 379 { 380 SDL_SetError("ph_SetupOpenGLContext(): failed to create OpenGL context !\n"); 381 qnxgl_buffers_destroy(oglbuffers); 382 qnxgl_finish(); 383 return -1; 384 } 385 386 /* Attempt to make the context current so we can use OpenGL commands */ 387 if (qnxgl_set_current(oglctx) == -1) 388 { 389 SDL_SetError("ph_SetupOpenGLContext(): failed to make the OpenGL context current !\n"); 390 qnxgl_context_destroy(oglctx); 391 qnxgl_buffers_destroy(oglbuffers); 392 qnxgl_finish(); 393 return -1; 394 } 395 396 PtFlush(); 397 398 oglflags=flags; 399 oglbpp=bpp; 400 401 return 0; 402 } 403 404 #endif /* _NTO_VERSION */ 405 406 #endif /* SDL_VIDEO_OPENGL */ 407