Home | History | Annotate | Download | only in photon
      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