FreeWRL/FreeX3D  3.0.0
display.c
1 /*
2 
3  FreeWRL support library.
4  Display (X11/Motif or OSX/Aqua) initialization.
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 
27 #include <config.h>
28 #include <system.h>
29 #include <system_threads.h>
30 #include <internal.h>
31 #include <display.h>
32 #include <threads.h>
33 #include <libFreeWRL.h>
34 
35 #include "vrml_parser/Structs.h"
36 #include "opengl/RasterFont.h"
37 #include "opengl/OpenGL_Utils.h"
38 #include "opengl/Textures.h"
39 //JAS #include "scenegraph/Collision.h"
40 
41 #include "ui/common.h"
42 
43 #if defined(FREEWRL_PLUGIN) && (defined(TARGET_X11) || defined(TARGET_MOTIF))
44 #include "plugin/pluginUtils.h"
45 #endif
46 
47 
48 // OLD_IPHONE_AQUA #if defined (TARGET_AQUA)
49 // OLD_IPHONE_AQUA #ifndef IPHONE
50 // OLD_IPHONE_AQUA int PaneClipnpx;
51 // OLD_IPHONE_AQUA int PaneClipnpy;
52 // OLD_IPHONE_AQUA
53 // OLD_IPHONE_AQUA int PaneClipct;
54 // OLD_IPHONE_AQUA int PaneClipcb;
55 // OLD_IPHONE_AQUA int PaneClipcr;
56 // OLD_IPHONE_AQUA int PaneClipcl;
57 // OLD_IPHONE_AQUA int PaneClipwidth;
58 // OLD_IPHONE_AQUA int PaneClipheight;
59 // OLD_IPHONE_AQUA int PaneClipChanged = FALSE;
60 // OLD_IPHONE_AQUA #endif
61 // OLD_IPHONE_AQUA #endif
62 
63 //static Stack *_vpstack = NULL; //ivec4 in y-down pixel coords - viewport stack used for clipping drawing
64 
65 typedef struct ivec4 {int X; int Y; int W; int H;} ivec4;
66 typedef struct ivec2 {int X; int Y;} ivec2;
67 ivec4 ivec4_init(int x, int y, int w, int h){
68  ivec4 ret;
69  ret.X = x, ret.Y = y; ret.W = w; ret.H = h;
70  return ret;
71 }
72 
73 ivec2 ivec2_init(int x, int y){
74  ivec2 ret;
75  ret.X = x, ret.Y = y;
76  return ret;
77 }
78 
79 #define MAXSTAT 200
80 typedef struct pdisplay{
81  freewrl_params_t params; //pre-allocated
83  char myMenuStatus[MAXSTAT];
84  int multi_window_capable;
85 }* ppdisplay;
86 void *display_constructor(){
87  void *v = MALLOCV(sizeof(struct pdisplay));
88  memset(v,0,sizeof(struct pdisplay));
89  return v;
90 }
91 void display_init(struct tdisplay* t)
92 {
93  //public
94  //freewrl_params_t p = d->params;
95 
96  t->display_initialized = FALSE;
97 
98  t->screenWidth = 0; /* screen */
99  t->screenHeight = 0;
100  t->window_title = NULL;
101 
102  t->shutterGlasses = 0; /* stereo shutter glasses */
103  t->prv = display_constructor();
104  {
105  ppdisplay p = (ppdisplay)t->prv;
106  memset(&p->rdr_caps,0,sizeof(s_renderer_capabilities_t));
107  t->rdr_caps = &p->rdr_caps;
108  /*
109  p->params.height = 0; // window
110  p->params.width = 0;
111  p->params.winToEmbedInto = INT_ID_UNDEFINED;
112  p->params.fullscreen = FALSE;
113  p->params.xpos = 0;
114  p->params.ypos = 0;
115  p->params.frontend_handles_display_thread = FALSE;
116  */
117 // OLD_IPHONE_AQUA #if defined(ANGLEPROJECT) || defined(_ANDROID) || defined(QNX) || defined(IPHONE)
118 #if defined(ANGLEPROJECT) || defined(_ANDROID) || defined(QNX)
119  p->multi_window_capable = 0; //single-window EGL/ANGLEPROJECT(GLES2)/MOBILE
120 #else
121  p->multi_window_capable = 1; //desktop opengl __linux__, _MSC_VER
122 #endif
123  t->params = (void*)&p->params;
124  }
125 }
126 
127 
128 
129 /* simple display initialize for Android (and, probably, iPhones, too)
130  Nov 2015: now used for desktop backend opengl initialization
131 */
132 
133 int fv_display_initialize()
134 {
135  struct tdisplay* d = &gglobal()->display;
136 #ifdef HAVE_OPENCL
137  struct tOpenCL_Utils *cl = &gglobal()->OpenCL_Utils;
138 #endif //HAVE_OPENCL
139 
140 
141  //printf ("fv_display_initialize called\n");
142  if (d->display_initialized) {
143  //ConsoleMessage ("fv_display_initialized re-called for a second time");
144  return TRUE;
145  }
146 
147  if (!fwl_initialize_GL()) {
148  return FALSE;
149  }
150 
151  /* Display full initialized :P cool ! */
152  d->display_initialized = TRUE;
153 
154 #ifdef HAVE_OPENCL
155 
156  if (!cl->OpenCL_Initialized) {
157  printf ("doing fwl_OpenCL_startup here in fv_display_inintialize\n");
158  fwl_OpenCL_startup(cl);
159  }
160 
161 #endif
162 
163  PRINT_GL_ERROR_IF_ANY ("end of fv_display_initialize");
164 
165  return TRUE;
166 }
167 
168 //void fv_swapbuffers(freewrl_params_t *d);
169 #ifdef WINRT
170 void fv_swapbuffers(freewrl_params_t *d){
171  return;
172 }
173 #endif
174 
175 //void fv_change_GLcontext(freewrl_params_t* d);
176 // each config needs to populate:
177 // ANGLEPROJECT(stub) and WIN32(wglSetContext) done in src/lib/ui/fwWindow32.c
178 //void fv_change_GLcontext(freewrl_params_t* d){
179 // return; //stub for ANLGEPROJECT, EGL/GLES2, mobile which don't change context but need to link
180 //}
181 #if defined(WINRT) || defined(_ANDROID) || defined(ANDROIDNDK) || defined(IOS)
182 void fv_change_GLcontext(freewrl_params_t* d){
183  //stub for non-desktop configs (they can't do multiple windows anyway)
184 }
185 #elif _MSC_VER
186 //win32 in fwWindow32.c
187 #elif __linux__ //LINUX
188 //void fv_change_GLcontext(freewrl_params_t* d){
189 // glXMakeCurrent(d->display,d->surface,d->context);
190 //}
191 
192 // OLD_IPHONE_AQUA #elif AQUA
193 // OLD_IPHONE_AQUA void fv_change_GLcontext(freewrl_params_t* d){
194 // OLD_IPHONE_AQUA aglSetCurrentContext(d->context);
195 // OLD_IPHONE_AQUA }
196 
197 #else
198 void fv_change_GLcontext(freewrl_params_t* d){
199  //stub for non-desktop configs (they can't do multiple windows anyway)
200 }
201 #endif
202 
203 #if !defined(_ANDROID) && !defined(ANDROIDNDK) && !defined(WINRT)
204 int fv_create_window_and_context(freewrl_params_t *params, freewrl_params_t *share);
205 //#if defined (__linux__)
206 //int fv_create_window_and_context(freewrl_params_t *params, freewrl_params_t *share){
207 // /* make the window, create the OpenGL context, share the context if necessary
208 // Nov 2015: linux desktop is still single windowed, with static GLXContext etc, no sharing
209 // - to get sharing, you need to populate params during creation of window and gl context
210 // d->display = Display *Xdpy;
211 // d->surface = Drawable or ???
212 // d->context = GLXContext GLcx;
213 // so when the targetwindow changes, there's enough info to do glXMakeCurrent and glXSwapBuffers
214 // - and when doing glCreateContext you have the previous window's GLXcontext to use as a shareList
215 // */
216 //
217 // if (!fv_open_display()) {
218 // printf("open_display failed\n");
219 // return FALSE;
220 // }
221 //
222 // if (!fv_create_GLcontext()) {
223 // printf("create_GLcontext failed\n");
224 // return FALSE;
225 // }
226 // fv_bind_GLcontext();
227 // return TRUE;
228 //}
229 //#endif //__linux__
230 
231 #ifdef _MSC_VER
232 int fv_create_window_and_context(freewrl_params_t *params, freewrl_params_t *share){
233  if (!fv_create_main_window2(params,share)){ //0 /*argc*/, NULL /*argv*/)) {
234  return FALSE;
235  }
236  return TRUE;
237 }
238 #endif //_MSC_VER
239 // OLD_IPHONE_AQUA #ifdef AQUA
240 // OLD_IPHONE_AQUA int fv_create_window_and_context(freewrl_params_t *params, freewrl_params_t *share){
241 // OLD_IPHONE_AQUA /* make the window, create the OpenGL context, share the context if necessary
242 // OLD_IPHONE_AQUA Nov 2015: OSX desktop is still single windowed, with static AGLcontext etc, no sharing
243 // OLD_IPHONE_AQUA - to get sharing, you need to populate params during creation of window and gl context
244 // OLD_IPHONE_AQUA d->display = (don't need)
245 // OLD_IPHONE_AQUA d->surface = (don't need)
246 // OLD_IPHONE_AQUA d->context = AGLContext
247 // OLD_IPHONE_AQUA so when the targetwindow changes, there's enough info to do aglSetCurrentContext and aglSwapBuffers
248 // OLD_IPHONE_AQUA - and when doing aglCreateContext you have the previous window's AGLContext to use as a share
249 // OLD_IPHONE_AQUA
250 // OLD_IPHONE_AQUA */
251 // OLD_IPHONE_AQUA
252 // OLD_IPHONE_AQUA if (!fv_create_main_window(params)){ //0 /*argc*/, NULL /*argv*/)) {
253 // OLD_IPHONE_AQUA return FALSE;
254 // OLD_IPHONE_AQUA }
255 // OLD_IPHONE_AQUA fv_bind_GLcontext();
256 // OLD_IPHONE_AQUA return TRUE;
257 // OLD_IPHONE_AQUA }
258 // OLD_IPHONE_AQUA #endif
259 
260 void targetwindow_set_params(int itargetwindow, freewrl_params_t* params);
261 freewrl_params_t* targetwindow_get_params(int itargetwindow);
269 int fv_display_initialize_desktop(){
270  int nwindows;
271  struct tdisplay* d;
272  freewrl_params_t *dp;
273  ppdisplay p;
274  ttglobal tg = gglobal();
275  d = &tg->display;
276  p = (ppdisplay)tg->display.prv;
277 
278  dp = (freewrl_params_t*)d->params;
279  if(dp->frontend_handles_display_thread){
280  //all configs are technically frontend handles display thread now,
281  // as seen by the backend (not including desktop.c which is a frontend)
282  // the flag frontend_handles_display_thread here really means
283  // frontend_handles_window_creation_and_opengl_context_creation
284  // for example: winGLES2.exe which uses an EGL kit for window/glcontext
285  return fv_display_initialize(); //display_initialize now really means initialize generic backend opengl
286  }
287 
288  nwindows = 1; //1 is normal freewrl, 2 or 3 is freaky 2,3 windowed freewrl for experiments, search targetwindow and windex
289  if(!p->multi_window_capable) nwindows = 1;
290  /* make the window, get the OpenGL context */
291  if(!fv_create_window_and_context(dp, NULL)){
292  return FALSE;
293  }
294  d->display_initialized = fwl_initialize_GL();
295  targetwindow_set_params(0,dp);
296  if(nwindows > 1){
297  //2nd fun window! to challenge us!
298  freewrl_params_t *p0;
299  dp->winToEmbedInto = -1;
300  p0 = targetwindow_get_params(0);
301  if(!fv_create_window_and_context(dp,p0)){
302  return FALSE;
303  }
304  targetwindow_set_params(1,dp);
305  fwl_initialize_GL(); //has context-specific initializations -like GL_BLEND- so repeat per-context
306  }
307  if(nwindows > 2){
308  freewrl_params_t *p1;
309  dp->winToEmbedInto = -1;
310  p1 = targetwindow_get_params(1);
311  if(!fv_create_window_and_context(dp, p1)){
312  return FALSE;
313  }
314  targetwindow_set_params(2,dp);
315  fwl_initialize_GL();
316  }
317  setWindowTitle0();
318 
319  /* lets make sure everything is sync'd up */
320 #if defined(TARGET_X11) || defined(TARGET_MOTIF)
321  XFlush(Xdpy);
322 #endif
323 
324  gglobal()->display.display_initialized = d->display_initialized;
325 
326  DEBUG_MSG("FreeWRL: running as a plugin: %s\n", BOOL_STR(isBrowserPlugin));
327 
328  PRINT_GL_ERROR_IF_ANY ("end of fv_display_initialize");
329 
330 // OLD_IPHONE_AQUA #if !(defined(TARGET_AQUA) || defined(_MSC_VER) || defined(_ANDROID))
331 #if !(defined(_MSC_VER) || defined(_ANDROID))
332 
333  if (RUNNINGASPLUGIN) {
334 #if defined(FREEWRL_PLUGIN) && (defined(TARGET_X11) || defined(TARGET_MOTIF))
335  sendXwinToPlugin();
336 #endif
337  } else {
338  XMapWindow(Xdpy, Xwin);
339  }
340 #endif
341  return TRUE;
342 }
343 #endif
344 
345 
350 int fwl_parse_geometry_string(const char *geometry, int *out_width, int *out_height,
351  int *out_xpos, int *out_ypos)
352 {
353  int width, height, xpos, ypos;
354  int c;
355 
356  width = height = xpos = ypos = 0;
357 
358  c = sscanf(geometry, "%dx%d+%d+%d",
359  &width, &height, &xpos, &ypos);
360 
361  if (out_width) *out_width = width;
362  if (out_height) *out_height = height;
363  if (out_xpos) *out_xpos = xpos;
364  if (out_ypos) *out_ypos = ypos;
365 
366  if (c > 0)
367  return TRUE;
368  return FALSE;
369 }
370 
371 void fv_setScreenDim(int wi, int he) { fwl_setScreenDim(wi,he); }
372 
373 void fwl_setScreenDim1(int wi, int he, int windex);
374 void fwl_setScreenDim0(int wi, int he)
375 {
376  //this one just sets the tg->display.screenWidth and is called in the targetwindow rendering loop
377  //this allows legacy code use of display.screenWidth etc to work normally in the render functions
378  ttglobal tg = gglobal();
379 
380  tg->display.screenWidth = wi; //width of the whole opengl surface in pixels
381  tg->display.screenHeight = he; //height of the whole opengl surface in pixels
382 }
386 void fwl_setScreenDim(int wi, int he)
387 {
388  //this one is called from platform-specific window event handling code, and
389  //by default assumes there's only one window, windex=0
390  //and sets a windowtarget-specific viewport as well as tg.display.screenwidth/height
391  fwl_setScreenDim0(wi,he);
392  fwl_setScreenDim1(wi,he,0);
393 }
394 double display_screenRatio(){
395  ttglobal tg = gglobal();
396  double ratio = 1.5;
397  if (tg->display.screenHeight != 0) ratio = (double) tg->display.screenWidth/(double) tg->display.screenHeight;
398  return ratio;
399 }
400 void fwl_setClipPlane(int height)
401 {
402  //this should be 2 numbers, one for top and bottom
403  //right now the statusbarHud -which shares the opengl window with the scene- takes 16 pixels on the bottom
404  gglobal()->Mainloop.clipPlane = height;
405 }
409 GLvoid resize_GL(GLsizei width, GLsizei height)
410 {
411  FW_GL_VIEWPORT( 0, 0, width, height );
412  printf("resize_GL\n");
413 }
414 
415 void fwl_updateScreenDim(int wi, int he)
416 {
417  fwl_setScreenDim(wi, he);
418 
419  resize_GL(wi, he);
420 }
421 
422 
423 
428 bool initialize_rdr_caps()
429 {
430  //s_renderer_capabilities_t *rdr_caps;
431  /* Max texture size */
432  GLint tmp; /* ensures that we pass pointers of same size across all platforms */
433  ppdisplay p = (ppdisplay)gglobal()->display.prv;
434 
435 #if defined(HAVE_GLEW_H) && !defined(ANGLEPROJECT)
436  /* Initialize GLEW */
437  {
438  GLenum err;
439  err = glewInit();
440  if (GLEW_OK != err) {
441  /* Problem: glewInit failed, something is seriously wrong. */
442  ERROR_MSG("GLEW initialization error: %s\n", glewGetErrorString(err));
443  return FALSE;
444  }
445  TRACE_MSG("GLEW initialization: version %s\n", glewGetString(GLEW_VERSION));
446  }
447 #endif
448 
449  /* OpenGL is initialized, context is created,
450  get some info, for later use ...*/
451  p->rdr_caps.renderer = (char *) FW_GL_GETSTRING(GL_RENDERER);
452  p->rdr_caps.version = (char *) FW_GL_GETSTRING(GL_VERSION);
453  p->rdr_caps.vendor = (char *) FW_GL_GETSTRING(GL_VENDOR);
454  p->rdr_caps.extensions = (char *) FW_GL_GETSTRING(GL_EXTENSIONS);
455  FW_GL_GETBOOLEANV(GL_STEREO,&(p->rdr_caps.quadBuffer));
456  //if (rdr_caps.quadBuffer) ConsoleMessage("INIT HAVE QUADBUFFER"); else ConsoleMessage("INIT_ NO QUADBUFFER");
457  ConsoleMessage("openGL version %s\n",p->rdr_caps.version);
458 
459  /* rdr_caps.version = "1.5.7"; //"1.4.1"; //for testing */
460  if (p->rdr_caps.version)
461  p->rdr_caps.versionf = (float) atof(p->rdr_caps.version);
462  if (p->rdr_caps.versionf == 0) // can't parse output of GL_VERSION, generally in case it is smth. like "OpenGL ES 3.0 V@66.0 AU@ (CL@)". probably 3.x or bigger.
463  {
464  const char *openGLPrefix = "OpenGL ES ";
465  if (NULL != p->rdr_caps.version && strstr(p->rdr_caps.version, openGLPrefix))
466  {
467  char version[256], *versionPTR;
468  sprintf(version, "%s", p->rdr_caps.version);
469  versionPTR = version + strlen(openGLPrefix);
470  p->rdr_caps.versionf = (float) atof(versionPTR);
471  //free(version);
472  }
473 #if defined(GL_ES_VERSION_2_0) && !defined(ANGLEPROJECT)
474  if (0 == p->rdr_caps.version)
475  {
476  //Try define version with 3.x api
477  GLint major = 0, minor = 0;
478  #if defined(GL_MAJOR_VERSION) && defined(GL_MINOR_VERSION)
479  FW_GL_GETINTEGERV(GL_MAJOR_VERSION, &major);
480  FW_GL_GETINTEGERV(GL_MINOR_VERSION, &minor);
481  #else
482  major = 2;
483  minor = 1;
484  #endif
485  char *version;
486  asprintf(&version, "%d.%d", major, minor);
487  p->rdr_caps.version = version;
488  p->rdr_caps.versionf = (float) atof(p->rdr_caps.version);
489  free(version);
490  }
491 #endif
492  }
493  /* atof technique: http://www.opengl.org/resources/faq/technical/extensions.htm */
494  p->rdr_caps.have_GL_VERSION_1_1 = p->rdr_caps.versionf >= 1.1f;
495  p->rdr_caps.have_GL_VERSION_1_2 = p->rdr_caps.versionf >= 1.2f;
496  p->rdr_caps.have_GL_VERSION_1_3 = p->rdr_caps.versionf >= 1.3f;
497  p->rdr_caps.have_GL_VERSION_1_4 = p->rdr_caps.versionf >= 1.4f;
498  p->rdr_caps.have_GL_VERSION_1_5 = p->rdr_caps.versionf >= 1.5f;
499  p->rdr_caps.have_GL_VERSION_2_0 = p->rdr_caps.versionf >= 2.0f;
500  p->rdr_caps.have_GL_VERSION_2_1 = p->rdr_caps.versionf >= 2.1f;
501  p->rdr_caps.have_GL_VERSION_3_0 = p->rdr_caps.versionf >= 3.0f;
502 
503 
504  /* Initialize renderer capabilities without GLEW */
505 
506  /* Multitexturing */
507  if (p->rdr_caps.extensions){
508  p->rdr_caps.av_multitexture = (strstr(p->rdr_caps.extensions, "GL_ARB_multitexture") != 0);
509 
510  /* Occlusion Queries */
511  p->rdr_caps.av_occlusion_q = ((strstr(p->rdr_caps.extensions, "GL_ARB_occlusion_query") != 0) ||
512  (strstr(p->rdr_caps.extensions, "GL_EXT_occlusion_query_boolean") != 0) ||
513  p->rdr_caps.have_GL_VERSION_3_0);
514 
515 
516  /* Non-power-of-two textures */
517  p->rdr_caps.av_npot_texture = (strstr(p->rdr_caps.extensions, "GL_ARB_texture_non_power_of_two") != 0);
518 
519  /* Texture rectangle (x != y) */
520  p->rdr_caps.av_texture_rect = (strstr(p->rdr_caps.extensions, "GL_ARB_texture_rectangle") != 0);
521  }
522  /* if we are doing our own shading, force the powers of 2, because otherwise mipmaps are not possible. */
523  p->rdr_caps.av_npot_texture=FALSE;
524 
525  /* attempting multi-texture */
526  p->rdr_caps.av_multitexture = 1;
527 
528  FW_GL_GETINTEGERV(GL_MAX_TEXTURE_SIZE, &tmp);
529  p->rdr_caps.runtime_max_texture_size = (int) tmp;
530  p->rdr_caps.system_max_texture_size = (int) tmp;
531 
532  // GL_MAX_TEXTURE_UNITS is for fixed function, and should be deprecated.
533  // use GL_MAX_TEXTURE_IMAGE_UNITS now, according to the OpenGL.org wiki
534 
535 
536  #if defined (GL_MAX_TEXTURE_IMAGE_UNITS)
537  FW_GL_GETINTEGERV(GL_MAX_TEXTURE_IMAGE_UNITS, &tmp);
538  #else
539  FW_GL_GETINTEGERV(GL_MAX_TEXTURE_UNITS, &tmp);
540  #endif
541 
542  p->rdr_caps.texture_units = (int) tmp;
543 
544  /* max supported texturing anisotropicDegree- can be changed in TextureProperties */
545 #ifdef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
546  FW_GL_GETFLOATV (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &p->rdr_caps.anisotropicDegree);
547 #endif
548  /* User settings in environment */
549 
550  //ConsoleMessage ("Environment set texture size: %d", gglobal()->internalc.user_request_texture_size);
551  if (gglobal()->internalc.user_request_texture_size > 0) {
552  DEBUG_MSG("Environment set texture size: %d", gglobal()->internalc.user_request_texture_size);
553  p->rdr_caps.runtime_max_texture_size = gglobal()->internalc.user_request_texture_size;
554  }
555 
556  /* Special drivers settings */
557  if (p->rdr_caps.renderer)
558  if (
559  strstr(p->rdr_caps.renderer, "Intel GMA 9") != NULL ||
560  strstr(p->rdr_caps.renderer, "Intel(R) 9") != NULL ||
561  strstr(p->rdr_caps.renderer, "i915") != NULL ||
562  strstr(p->rdr_caps.renderer, "NVIDIA GeForce2") != NULL
563  ) {
564  if (p->rdr_caps.runtime_max_texture_size > 1024) p->rdr_caps.runtime_max_texture_size = 1024;
565  }
566 
567  /* print some debug infos */
568  rdr_caps_dump(&p->rdr_caps);
569 
570  //make this the renderer caps for this thread.
571  //memcpy(&gglobal()->display.rdr_caps,&rdr_caps,sizeof(rdr_caps));
572  return TRUE;
573 }
574 
575 void initialize_rdr_functions()
576 {
589 }
590 
591 void rdr_caps_dump(s_renderer_capabilities_t *rdr_caps)
592 {
593 #ifdef VERBOSE
594  {
595  char *p, *pp;
596  p = pp = STRDUP(rdr_caps->extensions);
597  while (*pp != '\0') {
598  if (*pp == ' ') *pp = '\n';
599  pp++;
600  }
601  DEBUG_MSG ("OpenGL extensions : %s\n", p);
602  FREE(p);
603  }
604 #endif //VERBOSE
605 
606  DEBUG_MSG ("Multitexture support: %s\n", BOOL_STR(rdr_caps->av_multitexture));
607  DEBUG_MSG ("Occlusion support: %s\n", BOOL_STR(rdr_caps->av_occlusion_q));
608  DEBUG_MSG ("Max texture size %d\n", rdr_caps->runtime_max_texture_size);
609  DEBUG_MSG ("Max texture size %d\n", rdr_caps->system_max_texture_size);
610  DEBUG_MSG ("Texture units %d\n", rdr_caps->texture_units);
611 }
Initialization.
Definition: libFreeWRL.h:71
Definition: display.c:66
Definition: display.c:65