BRL-CAD
dm-osgl.cpp
Go to the documentation of this file.
1 /* D M - O S G L . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 1988-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file libdm/dm-osgl.cpp
21  *
22  * An OpenGL Display Manager using OpenSceneGraph.
23  *
24  */
25 
26 #include "common.h"
27 
28 #ifdef DM_OSGL
29 
30 //#define OSG_VIEWER_TEST 1
31 
32 #include <string.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <math.h>
36 
37 #include <osg/GraphicsContext>
38 #include <osgViewer/Viewer>
39 
40 #if defined(_WIN32)
41 # include <osgViewer/api/Win32/GraphicsWindowWin32>
42 #else
43 # include <osgViewer/api/X11/GraphicsWindowX11>
44 #endif
45 
46 extern "C" {
47 #include "tcl.h"
48 #include "tk.h"
49 #include "tkPlatDecls.h"
50 
51 #include "vmath.h"
52 #include "bn.h"
53 #include "raytrace.h"
54 #include "dm.h"
55 #include "dm-Null.h"
56 #include "dm/dm_xvars.h"
57 #include "fb.h"
58 #include "solid.h"
59 #include "./dm_private.h"
60 }
61 #include "fb/fb_osgl.h"
62 #include "dm-osgl.h"
63 
64 /* For Tk, we need to offset when thinking about screen size in
65  * order to allow for the Mac OSX top-of-screen toolbar - Tk
66  * itself is quite happy to put things under it */
67 #define TK_SCREEN_OFFSET 30
68 
69 #define VIEWFACTOR (1.0/(*dmp->dm_vp))
70 #define VIEWSIZE (2.0*(*dmp->dm_vp))
71 
72 /* these are from /usr/include/gl.h could be device dependent */
73 #define XMAXSCREEN 1279
74 #define YMAXSCREEN 1023
75 #define YSTEREO 491 /* subfield height, in scanlines */
76 #define YOFFSET_LEFT 532 /* YSTEREO + YBLANK ? */
77 
78 /* Display Manager package interface */
79 #define IRBOUND 4095.9 /* Max magnification in Rot matrix */
80 #define PLOTBOUND 1000.0 /* Max magnification in Rot matrix */
81 
82 extern "C" {
83  struct dm_internal *osgl_open(Tcl_Interp *interp, int argc, char **argv);
84 }
85 HIDDEN int osgl_close(struct dm_internal *dmp);
86 HIDDEN int osgl_drawBegin(struct dm_internal *dmp);
87 HIDDEN int osgl_drawEnd(struct dm_internal *dmp);
88 HIDDEN int osgl_normal(struct dm_internal *dmp);
89 HIDDEN int osgl_loadMatrix(struct dm_internal *dmp, fastf_t *mat, int which_eye);
90 HIDDEN int osgl_loadPMatrix(struct dm_internal *dmp, fastf_t *mat);
91 HIDDEN int osgl_drawString2D(struct dm_internal *dmp, const char *str, fastf_t x, fastf_t y, int size, int use_aspect);
92 HIDDEN int osgl_drawLine2D(struct dm_internal *dmp, fastf_t X1, fastf_t Y1, fastf_t X2, fastf_t Y2);
93 HIDDEN int osgl_drawLine3D(struct dm_internal *dmp, point_t pt1, point_t pt2);
94 HIDDEN int osgl_drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int sflag);
95 HIDDEN int osgl_drawPoint2D(struct dm_internal *dmp, fastf_t x, fastf_t y);
96 HIDDEN int osgl_drawPoint3D(struct dm_internal *dmp, point_t point);
97 HIDDEN int osgl_drawPoints3D(struct dm_internal *dmp, int npoints, point_t *points);
98 HIDDEN int osgl_drawVList(struct dm_internal *dmp, register struct bn_vlist *vp);
99 HIDDEN int osgl_drawVListHiddenLine(struct dm_internal *dmp, register struct bn_vlist *vp);
100 HIDDEN int osgl_draw(struct dm_internal *dmp, struct bn_vlist *(*callback_function)(void *), void **data);
101 HIDDEN int osgl_setFGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency);
102 HIDDEN int osgl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b);
103 HIDDEN int osgl_setLineAttr(struct dm_internal *dmp, int width, int style);
104 HIDDEN int osgl_configureWin_guts(struct dm_internal *dmp, int force);
105 HIDDEN int osgl_configureWin(struct dm_internal *dmp, int force);
106 HIDDEN int osgl_setLight(struct dm_internal *dmp, int lighting_on);
107 HIDDEN int osgl_setTransparency(struct dm_internal *dmp, int transparency_on);
108 HIDDEN int osgl_setDepthMask(struct dm_internal *dmp, int depthMask_on);
109 HIDDEN int osgl_setZBuffer(struct dm_internal *dmp, int zbuffer_on);
110 HIDDEN int osgl_setWinBounds(struct dm_internal *dmp, fastf_t *w);
111 HIDDEN int osgl_debug(struct dm_internal *dmp, int vl);
112 HIDDEN int osgl_logfile(struct dm_internal *dmp, const char *filename);
113 HIDDEN int osgl_beginDList(struct dm_internal *dmp, unsigned int list);
114 HIDDEN int osgl_endDList(struct dm_internal *dmp);
115 HIDDEN void osgl_drawDList(unsigned int list);
116 HIDDEN int osgl_freeDLists(struct dm_internal *dmp, unsigned int list, int range);
117 HIDDEN int osgl_genDLists(struct dm_internal *dmp, size_t range);
118 HIDDEN int osgl_getDisplayImage(struct dm_internal *dmp, unsigned char **image);
119 HIDDEN void osgl_reshape(struct dm_internal *dmp, int width, int height);
120 HIDDEN int osgl_makeCurrent(struct dm_internal *dmp);
121 
122 
123 static fastf_t default_viewscale = 1000.0;
124 static double xlim_view = 1.0; /* args for glOrtho*/
125 static double ylim_view = 1.0;
126 
127 /* lighting parameters */
128 static float amb_three[] = {0.3, 0.3, 0.3, 1.0};
129 
130 static float light0_position[] = {0.0, 0.0, 1.0, 0.0};
131 static float light0_diffuse[] = {1.0, 1.0, 1.0, 1.0}; /* white */
132 static float wireColor[4];
133 static float ambientColor[4];
134 static float specularColor[4];
135 static float diffuseColor[4];
136 static float backDiffuseColorDark[4];
137 static float backDiffuseColorLight[4];
138 
139 HIDDEN void
140 osgl_printmat(struct bu_vls *tmp_vls, fastf_t *mat) {
141  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[0], mat[4], mat[8], mat[12]);
142  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[1], mat[5], mat[9], mat[13]);
143  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[2], mat[6], mat[10], mat[14]);
144  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[3], mat[7], mat[11], mat[15]);
145 }
146 
147 HIDDEN void
148 osgl_printglmat(struct bu_vls *tmp_vls, GLfloat *m) {
149  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[0], m[4], m[8], m[12]);
150  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[1], m[5], m[9], m[13]);
151  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[2], m[6], m[10], m[14]);
152  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[3], m[7], m[11], m[15]);
153 }
154 
155 extern "C" {
156 void
157 osgl_fogHint(struct dm_internal *dmp, int fastfog)
158 {
159  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
160  mvars->fastfog = fastfog;
161  glHint(GL_FOG_HINT, fastfog ? GL_FASTEST : GL_NICEST);
162 }
163 }
164 
165 HIDDEN int
166 osgl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b)
167 {
168  if (dmp->dm_debugLevel == 1)
169  bu_log("osgl_setBGColor()\n");
170 
171  dmp->dm_bg[0] = r;
172  dmp->dm_bg[1] = g;
173  dmp->dm_bg[2] = b;
174 
175  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->r = r / 255.0;
176  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g = g / 255.0;
177  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b = b / 255.0;
178 
179  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->swapBuffers();
180  glClearColor(((struct osgl_vars *)dmp->dm_vars.priv_vars)->r,
181  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g,
182  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b,
183  0.0);
184  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
185 
186  return TCL_OK;
187 }
188 
189 
190 /*
191  * Either initially, or on resize/reshape of the window,
192  * sense the actual size of the window, and perform any
193  * other initializations of the window configuration.
194  */
195 HIDDEN int
196 osgl_configureWin_guts(struct dm_internal *dmp, int force)
197 {
198  int width;
199  int height;
200 
201  struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
202 
203  if (pubvars->top != pubvars->xtkwin) {
204  width = Tk_Width(Tk_Parent(pubvars->xtkwin));
205  height = Tk_Height(Tk_Parent(pubvars->xtkwin));
206  } else {
207  width = Tk_Width(pubvars->top);
208  height = Tk_Height(pubvars->top);
209  }
210 
211  if (!force &&
212  dmp->dm_height == height &&
213  dmp->dm_width == width)
214  return TCL_OK;
215 
216  osgl_reshape(dmp, width, height);
217  return TCL_OK;
218 }
219 
220 
221 HIDDEN void
222 osgl_reshape(struct dm_internal *dmp, int width, int height)
223 {
224  GLint mm;
225 
226  dmp->dm_height = height;
227  dmp->dm_width = width;
228  dmp->dm_aspect = (fastf_t)dmp->dm_width / (fastf_t)dmp->dm_height;
229 
230  if (dmp->dm_debugLevel) {
231  GLfloat m[16];
232  bu_log("osgl_reshape()\n");
233  bu_log("width = %d, height = %d\n", dmp->dm_width, dmp->dm_height);
234  glGetFloatv (GL_MODELVIEW_MATRIX, m);
235  glGetFloatv (GL_PROJECTION_MATRIX, m);
236  }
237 
238  glViewport(0, 0, dmp->dm_width, dmp->dm_height);
239 
240  glClearColor(((struct osgl_vars *)dmp->dm_vars.priv_vars)->r,
241  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g,
242  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b,
243  0.0);
244  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
245 
246  glGetIntegerv(GL_MATRIX_MODE, &mm);
247  glMatrixMode(GL_PROJECTION);
248  glLoadIdentity();
249  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
250  glMatrixMode(mm);
251 #ifdef OSG_VIEWER_TEST
252  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
253 
254  //struct osg_vars *privvars = (struct osg_vars *)dmp->dm_vars.priv_vars;
255  if (privvars->testviewer) {
256 
257  osgViewer::Viewer::Windows windows;
258  privvars->testviewer->getWindows(windows);
259  for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
260  itr != windows.end();
261  ++itr)
262  {
263  (*itr)->setWindowRectangle(0, 0, dmp->dm_width, dmp->dm_height);
264  }
265 
266  privvars->testviewer->getCamera()->setViewport(0, 0, dmp->dm_width, dmp->dm_height);
267 
268  osg::Matrixf orthom;
269  orthom.makeIdentity();
270  orthom.makeOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
271  privvars->testviewer->getCamera()->setProjectionMatrix(orthom);
272 
273  privvars->testviewer->frame();
274 
275  }
276 #endif
277 }
278 
279 
280 HIDDEN int
281 osgl_makeCurrent(struct dm_internal *dmp)
282 {
283  if (dmp->dm_debugLevel)
284  bu_log("osgl_makeCurrent()\n");
285 
286  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
287 
288  return TCL_OK;
289 }
290 
291 
292 HIDDEN int
293 osgl_configureWin(struct dm_internal *dmp, int force)
294 {
295  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
296 
297  return osgl_configureWin_guts(dmp, force);
298 }
299 
300 
301 HIDDEN int
302 osgl_setLight(struct dm_internal *dmp, int lighting_on)
303 {
304  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
305  if (dmp->dm_debugLevel)
306  bu_log("osgl_setLight()\n");
307 
308  dmp->dm_light = lighting_on;
309  mvars->lighting_on = dmp->dm_light;
310 
311  if (!dmp->dm_light) {
312  /* Turn it off */
313  glDisable(GL_LIGHTING);
314  } else {
315  /* Turn it on */
316 
317  if (1 < dmp->dm_light)
318  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
319  else
320  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
321 
322  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb_three);
323  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
324 
325  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
326  glLightfv(GL_LIGHT0, GL_SPECULAR, light0_diffuse);
327 
328  glEnable(GL_LIGHTING);
329  glEnable(GL_LIGHT0);
330  }
331 
332  return TCL_OK;
333 }
334 
335 /*
336  * Gracefully release the display.
337  */
338 HIDDEN int
339 osgl_close(struct dm_internal *dmp)
340 {
341  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
342  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->releaseContext();
343 
344  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin)
345  Tk_DestroyWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
346 
347  bu_vls_free(&dmp->dm_pathName);
348  bu_vls_free(&dmp->dm_tkName);
349  bu_vls_free(&dmp->dm_dName);
350  bu_free(dmp->dm_vars.priv_vars, "osgl_close: osgl_vars");
351  bu_free(dmp->dm_vars.pub_vars, "osgl_close: dm_xvars");
352  bu_free(dmp, "osgl_close: dmp");
353 
354  return TCL_OK;
355 }
356 
357 HIDDEN
358 static void OSGUpdate(dm *dmp, int delta) {
359  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
360  if (dmp->dm_debugLevel == 1)
361  bu_log("OSGUpdate()\n");
362 
363 
364  if (privvars->timer->time_m() - privvars->last_update_time > delta) {
365  //privvars->graphicsContext->swapBuffers();
366  privvars->last_update_time = privvars->timer->time_m();
367  }
368 }
369 
370 static void
371 OSGEventProc(ClientData clientData, XEvent *UNUSED(eventPtr))
372 {
373  dm *dmp = (dm *)clientData;
374 
375  OSGUpdate(dmp, 10);
376 }
377 
378 /*
379  * Fire up the display manager, and the display processor.
380  *
381  */
382 extern "C" struct dm_internal *
383 osgl_open(Tcl_Interp *interp, int argc, char **argv)
384 {
385  static int count = 0;
386  GLfloat backgnd[4];
387  struct bu_vls str = BU_VLS_INIT_ZERO;
388  struct bu_vls init_proc_vls = BU_VLS_INIT_ZERO;
389  struct dm_internal *dmp = (struct dm_internal *)NULL;
390  struct modifiable_osgl_vars *mvars = NULL;
391  Tk_Window tkwin = (Tk_Window)NULL;
392 
393  struct dm_xvars *pubvars = NULL;
394  struct osgl_vars *privvars = NULL;
395 
396  if ((tkwin = Tk_MainWindow(interp)) == NULL) {
397  return DM_NULL;
398  }
399 
400  BU_GET(dmp, struct dm_internal);
401 
402  *dmp = dm_osgl; /* struct copy */
403  dmp->dm_interp = interp;
404  dmp->dm_lineWidth = 1;
405  dmp->dm_light = 1;
406  dmp->dm_bytes_per_pixel = sizeof(GLuint);
407  dmp->dm_bits_per_channel = 8;
408  bu_vls_init(&(dmp->dm_log));
409 
410  BU_ALLOC(dmp->dm_vars.pub_vars, struct dm_xvars);
411  if (dmp->dm_vars.pub_vars == (void *)NULL) {
412  bu_free(dmp, "osgl_open: dmp");
413  return DM_NULL;
414  }
415  pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
416 
417  BU_ALLOC(dmp->dm_vars.priv_vars, struct osgl_vars);
418  if (dmp->dm_vars.priv_vars == (void *)NULL) {
419  bu_free(dmp->dm_vars.pub_vars, "osgl_open: dmp->dm_vars.pub_vars");
420  bu_free(dmp, "osgl_open: dmp");
421  return DM_NULL;
422  }
423  privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
424 
425  dmp->dm_get_internal(dmp);
426  mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
427 
428  dmp->dm_vp = &default_viewscale;
429 
430  bu_vls_init(&dmp->dm_pathName);
431  bu_vls_init(&dmp->dm_tkName);
432  bu_vls_init(&dmp->dm_dName);
433 
434  dm_processOptions(dmp, &init_proc_vls, --argc, ++argv);
435 
436  if (bu_vls_strlen(&dmp->dm_pathName) == 0)
437  bu_vls_printf(&dmp->dm_pathName, ".dm_osgl%d", count);
438  ++count;
439  if (bu_vls_strlen(&dmp->dm_dName) == 0) {
440  char *dp;
441 
442  dp = getenv("DISPLAY");
443  if (dp)
444  bu_vls_strcpy(&dmp->dm_dName, dp);
445  else
446  bu_vls_strcpy(&dmp->dm_dName, ":0.0");
447  }
448  if (bu_vls_strlen(&init_proc_vls) == 0)
449  bu_vls_strcpy(&init_proc_vls, "bind_dm");
450 
451  /* initialize dm specific variables */
452  pubvars->devmotionnotify = LASTEvent;
453  pubvars->devbuttonpress = LASTEvent;
454  pubvars->devbuttonrelease = LASTEvent;
455  dmp->dm_aspect = 1.0;
456 
457  /* initialize modifiable variables */
458  mvars->rgb = 1;
459  mvars->doublebuffer = 1;
460  mvars->fastfog = 1;
461  mvars->fogdensity = 1.0;
462  mvars->lighting_on = dmp->dm_light;
463  mvars->zbuffer_on = dmp->dm_zbuffer;
464  mvars->zclipping_on = dmp->dm_zclip;
465  mvars->debug = dmp->dm_debugLevel;
466  mvars->bound = dmp->dm_bound;
467  mvars->boundFlag = dmp->dm_boundFlag;
468  mvars->text_shadow = 1;
469 
470  if (dmp->dm_top) {
471  /* Make xtkwin a toplevel window */
472  pubvars->xtkwin =
473  Tk_CreateWindowFromPath(interp,
474  tkwin,
475  bu_vls_addr(&dmp->dm_pathName),
476  bu_vls_addr(&dmp->dm_dName));
477  pubvars->top = pubvars->xtkwin;
478  } else {
479  char *cp;
480 
481  cp = strrchr(bu_vls_addr(&dmp->dm_pathName), (int)'.');
482  if (cp == bu_vls_addr(&dmp->dm_pathName)) {
483  pubvars->top = tkwin;
484  } else {
485  struct bu_vls top_vls = BU_VLS_INIT_ZERO;
486 
487  bu_vls_strncpy(&top_vls, (const char *)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
488 
489  pubvars->top =
490  Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
491  bu_vls_free(&top_vls);
492  }
493 
494  /* Make xtkwin an embedded window */
495  pubvars->xtkwin =
496  Tk_CreateWindow(interp, pubvars->top,
497  cp + 1, (char *)NULL);
498  }
499 
500  if (pubvars->xtkwin == NULL) {
501  bu_log("dm-osgl: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
502  bu_vls_free(&init_proc_vls);
503  (void)osgl_close(dmp);
504  return DM_NULL;
505  }
506 
507  /* Make sure the window is large enough. If these values are not large
508  * enough, the drawing window will not resize properly to match
509  * the height change of the parent window. This is also true
510  * of the original ogl display manager, although it is undocumented *why*
511  * this initial screen-based sizing is needed... */
512  {
513  int make_square = -1;
514 
515  if (dmp->dm_width == 0) {
516  bu_vls_sprintf(&str, "winfo screenwidth .");
517  if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
518  bu_vls_free(&init_proc_vls);
519  bu_vls_free(&str);
520  (void)osgl_close(dmp);
521  return DM_NULL;
522  } else {
523  Tcl_Obj *tclresult = Tcl_GetObjResult(interp);
524  dmp->dm_width = tclresult->internalRep.longValue - TK_SCREEN_OFFSET;
525  }
526  ++make_square;
527  }
528  if (dmp->dm_height == 0) {
529  bu_vls_sprintf(&str, "winfo screenheight .");
530  if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
531  bu_vls_free(&init_proc_vls);
532  bu_vls_free(&str);
533  (void)osgl_close(dmp);
534  return DM_NULL;
535  } else {
536  Tcl_Obj *tclresult = Tcl_GetObjResult(interp);
537  dmp->dm_height = tclresult->internalRep.longValue - TK_SCREEN_OFFSET;
538  }
539  ++make_square;
540  }
541 
542  if (make_square > 0) {
543  /* Make window square */
544  if (dmp->dm_height < dmp->dm_width)
545  dmp->dm_width = dmp->dm_height;
546  else
547  dmp->dm_height = dmp->dm_width;
548  }
549  }
550 
551  bu_vls_printf(&dmp->dm_tkName, "%s",
552  (char *)Tk_Name(pubvars->xtkwin));
553 
554  /* Important - note that this is a bu_vls_sprintf, to clear the string */
555  bu_vls_sprintf(&str, "_init_dm %s %s\n",
556  bu_vls_addr(&init_proc_vls),
557  bu_vls_addr(&dmp->dm_pathName));
558 
559  if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
560  bu_vls_free(&init_proc_vls);
561  bu_vls_free(&str);
562  (void)osgl_close(dmp);
563  return DM_NULL;
564  }
565 
566  bu_vls_free(&init_proc_vls);
567  bu_vls_free(&str);
568 
569  pubvars->dpy =
570  Tk_Display(pubvars->top);
571 
572  /* make sure there really is a display before proceeding. */
573  if (!(pubvars->dpy)) {
574  bu_vls_free(&init_proc_vls);
575  bu_vls_free(&str);
576  (void)osgl_close(dmp);
577  return DM_NULL;
578  }
579 
580  Tk_GeometryRequest(pubvars->xtkwin,
581  dmp->dm_width,
582  dmp->dm_height);
583 
584  pubvars->depth = mvars->depth;
585 
586  Tk_MakeWindowExist(pubvars->xtkwin);
587 
588  pubvars->win = Tk_WindowId(pubvars->xtkwin);
589  dmp->dm_id = pubvars->win;
590 
591  Tk_MapWindow(pubvars->xtkwin);
592 
593  // Init the Windata Variable that holds the handle for the Window to display OSG in.
594  // Check the QOSGWidget.cpp example for more logic relevant to this. Need to find
595  // something showing how to handle Cocoa for the Mac, if that's possible
596  osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
597 #if defined(_WIN32)
598  osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(Tk_GetHWND(((struct dm_xvars *)(dmp->dm_vars.pub_vars))->win));
599 #else
600  osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowX11::WindowData(((struct dm_xvars *)(dmp->dm_vars.pub_vars))->win);
601 #endif
602 
603  // Although we are not making direct use of osgViewer currently, we need its
604  // initialization to make sure we have all the libraries we need loaded and
605  // ready.
606  osgViewer::Viewer *viewer = new osgViewer::Viewer();
607  delete viewer;
608 
609  // Setup the traits parameters
610  traits->x = 0;
611  traits->y = 0;
612  traits->width = dmp->dm_width;
613  traits->height = dmp->dm_height;
614  traits->depth = 24;
615  traits->windowDecoration = false;
616  traits->doubleBuffer = true;
617  traits->sharedContext = 0;
618  traits->setInheritedWindowPixelFormat = true;
619 
620  traits->inheritedWindowData = windata;
621 
622  // Create the Graphics Context
623  privvars->graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get());
624  privvars->traits = traits;
625 
626  privvars->graphicsContext->realize();
627  privvars->graphicsContext->makeCurrent();
628 
629  privvars->timer = new osg::Timer;
630  privvars->last_update_time = 0;
631  privvars->timer->setStartTick();
632 
633  /* this is where font information is set up */
634  privvars->fs = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT);
635  if (privvars->fs == NULL) {
636  bu_log("dm-osgl: Failed to create font stash");
637  bu_vls_free(&init_proc_vls);
638  (void)osgl_close(dmp);
639  return DM_NULL;
640  }
641  privvars->fontNormal = FONS_INVALID;
642  privvars->fontNormal = fonsAddFont(privvars->fs, "sans", bu_brlcad_data("fonts/ProFont.ttf", 0));
643 
644  /* This is the applications display list offset */
645  dmp->dm_displaylist = glGenLists(0);
646 
647  osgl_setBGColor(dmp, 0, 0, 0);
648  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
649 
650  if (mvars->doublebuffer)
651  glDrawBuffer(GL_BACK);
652  else
653  glDrawBuffer(GL_FRONT);
654 
655  /* do viewport, ortho commands and initialize font */
656  (void)osgl_configureWin_guts(dmp, 1);
657 
658  /* Lines will be solid when stippling disabled, dashed when enabled*/
659  glLineStipple(1, 0xCF33);
660  glDisable(GL_LINE_STIPPLE);
661 
662  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
663  glFogi(GL_FOG_MODE, GL_LINEAR);
664  glFogf(GL_FOG_START, 0.0);
665  glFogf(GL_FOG_END, 2.0);
666  glFogfv(GL_FOG_COLOR, backgnd);
667 
668  /*XXX Need to do something about VIEWFACTOR */
669  glFogf(GL_FOG_DENSITY, VIEWFACTOR);
670 
671  /* Initialize matrices */
672  /* Leave it in model_view mode normally */
673  glMatrixMode(GL_PROJECTION);
674  glLoadIdentity();
675  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
676  glGetDoublev(GL_PROJECTION_MATRIX, privvars->faceplate_mat);
677  glPushMatrix();
678  glMatrixMode(GL_MODELVIEW);
679  glLoadIdentity();
680  glPushMatrix();
681  glLoadIdentity();
682  privvars->face_flag = 1; /* faceplate matrix is on top of stack */
683 
684  osgl_setZBuffer(dmp, dmp->dm_zbuffer);
685  osgl_setLight(dmp, dmp->dm_light);
686 
687  Tk_CreateEventHandler(pubvars->xtkwin, PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask, OSGEventProc, (ClientData)dmp);
688 
689 #ifdef OSG_VIEWER_TEST
690  privvars->testviewer = new osgViewer::Viewer();
691  privvars->testviewer->setUpViewInWindow(0, 0, 1, 1);
692  privvars->testviewer->realize();
693 
694  privvars->osg_root = new osg::Group();
695  privvars->testviewer->setSceneData(privvars->osg_root);
696  privvars->testviewer->getCamera()->setCullingMode(osg::CullSettings::NO_CULLING);
697 
698  privvars->testviewer->frame();
699 #endif
700  return dmp;
701 }
702 
703 
704 int
705 osgl_share_dlist(struct dm_internal *UNUSED(dmp1), struct dm_internal *UNUSED(dmp2))
706 {
707 #if 0
708  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp1->m_vars;
709  GLfloat backgnd[4];
710  GLfloat vf;
711  GLXContext old_glxContext;
712 
713  if (dmp1 == (struct dm_internal *)NULL)
714  return TCL_ERROR;
715 
716  if (dmp2 == (struct dm_internal *)NULL) {
717  /* create a new graphics context for dmp1 with private display lists */
718 
719  old_glxContext = ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc;
720 
721  if ((((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc =
722  glXCreateContext(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy,
723  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->vip,
724  (GLXContext)NULL, GL_TRUE))==NULL) {
725  bu_log("osgl_share_dlist: couldn't create glXContext.\nUsing old context\n.");
726  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
727 
728  return TCL_ERROR;
729  }
730 
731  if (!glXMakeCurrent(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy,
732  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->win,
733  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc)) {
734  bu_log("osgl_share_dlist: Couldn't make context current\nUsing old context\n.");
735  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
736 
737  return TCL_ERROR;
738  }
739 
740  /* display list (fontOffset + char) will display a given ASCII char */
741  if ((((struct osgl_vars *)dmp1->dm_vars.priv_vars)->fontOffset = glGenLists(128))==0) {
742  bu_log("dm-osgl: Can't make display lists for font.\nUsing old context\n.");
743  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
744 
745  return TCL_ERROR;
746  }
747 
748  /* This is the applications display list offset */
749  dmp1->dm_displaylist = ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->fontOffset + 128;
750 
751  osgl_setBGColor(dmp1, 0, 0, 0);
752  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
753 
754  if (mvars->doublebuffer)
755  glDrawBuffer(GL_BACK);
756  else
757  glDrawBuffer(GL_FRONT);
758 
759  /* this is important so that osgl_configureWin knows to set the font */
760  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->fontstruct = NULL;
761 
762  /* do viewport, ortho commands and initialize font */
763  (void)osgl_configureWin_guts(dmp1, 1);
764 
765  /* Lines will be solid when stippling disabled, dashed when enabled*/
766  glLineStipple(1, 0xCF33);
767  glDisable(GL_LINE_STIPPLE);
768 
769  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
770  glFogi(GL_FOG_MODE, GL_LINEAR);
771  glFogf(GL_FOG_START, 0.0);
772  glFogf(GL_FOG_END, 2.0);
773  glFogfv(GL_FOG_COLOR, backgnd);
774 
775  /*XXX Need to do something about VIEWFACTOR */
776  vf = 1.0/(*dmp1->dm_vp);
777  glFogf(GL_FOG_DENSITY, vf);
778 
779  /* Initialize matrices */
780  /* Leave it in model_view mode normally */
781  glMatrixMode(GL_PROJECTION);
782  glLoadIdentity();
783  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
784  glGetDoublev(GL_PROJECTION_MATRIX, ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->faceplate_mat);
785  glPushMatrix();
786  glMatrixMode(GL_MODELVIEW);
787  glLoadIdentity();
788  glPushMatrix();
789  glLoadIdentity();
790  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->face_flag = 1; /* faceplate matrix is on top of stack */
791 
792  /* destroy old context */
793  glXMakeCurrent(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy, None, NULL);
794  glXDestroyContext(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy, old_glxContext);
795  } else {
796  /* dmp1 will share its display lists with dmp2 */
797 
798  old_glxContext = ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->glxc;
799 
800  if ((((struct osgl_vars *)dmp2->dm_vars.priv_vars)->glxc =
801  glXCreateContext(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy,
802  ((struct dm_xvars *)dmp2->dm_vars.pub_vars)->vip,
803  ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->glxc,
804  GL_TRUE))==NULL) {
805  bu_log("osgl_share_dlist: couldn't create glXContext.\nUsing old context\n.");
806  ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->glxc = old_glxContext;
807 
808  return TCL_ERROR;
809  }
810 
811  if (!glXMakeCurrent(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy,
812  ((struct dm_xvars *)dmp2->dm_vars.pub_vars)->win,
813  ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->glxc)) {
814  bu_log("osgl_share_dlist: Couldn't make context current\nUsing old context\n.");
815  ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->glxc = old_glxContext;
816 
817  return TCL_ERROR;
818  }
819 
820  ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->fontOffset = ((struct osgl_vars *)dmp1->dm_vars.priv_vars)->fontOffset;
821  dmp2->dm_displaylist = dmp1->dm_displaylist;
822 
823  osgl_setBGColor(dmp2, 0, 0, 0);
824  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
825 
826  if (mvars->doublebuffer)
827  glDrawBuffer(GL_BACK);
828  else
829  glDrawBuffer(GL_FRONT);
830 
831  /* do viewport, ortho commands and initialize font */
832  (void)osgl_configureWin_guts(dmp2, 1);
833 
834  /* Lines will be solid when stippling disabled, dashed when enabled*/
835  glLineStipple(1, 0xCF33);
836  glDisable(GL_LINE_STIPPLE);
837 
838  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
839  glFogi(GL_FOG_MODE, GL_LINEAR);
840  glFogf(GL_FOG_START, 0.0);
841  glFogf(GL_FOG_END, 2.0);
842  glFogfv(GL_FOG_COLOR, backgnd);
843 
844  /*XXX Need to do something about VIEWFACTOR */
845  vf = 1.0/(*dmp2->dm_vp);
846  glFogf(GL_FOG_DENSITY, vf);
847 
848  /* Initialize matrices */
849  /* Leave it in model_view mode normally */
850  glMatrixMode(GL_PROJECTION);
851  glLoadIdentity();
852  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
853  glGetDoublev(GL_PROJECTION_MATRIX, ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->faceplate_mat);
854  glPushMatrix();
855  glMatrixMode(GL_MODELVIEW);
856  glLoadIdentity();
857  glPushMatrix();
858  glLoadIdentity();
859  ((struct osgl_vars *)dmp2->dm_vars.priv_vars)->face_flag = 1; /* faceplate matrix is on top of stack */
860 
861  /* destroy old context */
862  glXMakeCurrent(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy, None, NULL);
863  glXDestroyContext(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy, old_glxContext);
864  }
865 #endif
866  return TCL_OK;
867 }
868 
869 
870 /*
871  * There are global variables which are parameters to this routine.
872  */
873 HIDDEN int
874 osgl_drawBegin(struct dm_internal *dmp)
875 {
876  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
877  GLfloat fogdepth;
878 
879  if (dmp->dm_debugLevel) {
880  bu_log("osgl_drawBegin\n");
881  }
882 
883  if (dmp->dm_debugLevel == 3) {
884  GLfloat m[16];
885  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
886 
887  bu_vls_printf(&tmp_vls, "initial view matrix = \n");
888 
889  glGetFloatv (GL_MODELVIEW_MATRIX, m);
890  osgl_printglmat(&tmp_vls, m);
891  bu_vls_printf(&tmp_vls, "initial projection matrix = \n");
892  glGetFloatv (GL_PROJECTION_MATRIX, m);
893  osgl_printglmat(&tmp_vls, m);
894 
895  bu_log("%s", bu_vls_addr(&tmp_vls));
896  bu_vls_free(&tmp_vls);
897  }
898 
899  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
900 
901  /* clear back buffer */
902  if (!dmp->dm_clearBufferAfter && mvars->doublebuffer) {
903  glClearColor(((struct osgl_vars *)dmp->dm_vars.priv_vars)->r,
904  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g,
905  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b,
906  0.0);
907  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
908  }
909 
910  if (((struct osgl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
911  glMatrixMode(GL_PROJECTION);
912  glPopMatrix();
913  glMatrixMode(GL_MODELVIEW);
914  glPopMatrix();
915  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->face_flag = 0;
916  if (mvars->cueing_on) {
917  glEnable(GL_FOG);
918  /*XXX Need to do something with Viewscale */
919  fogdepth = 2.2 * (*dmp->dm_vp); /* 2.2 is heuristic */
920  glFogf(GL_FOG_END, fogdepth);
921  fogdepth = (GLfloat) (0.5*mvars->fogdensity/
922  (*dmp->dm_vp));
923  glFogf(GL_FOG_DENSITY, fogdepth);
924  glFogi(GL_FOG_MODE, dmp->dm_perspective ? GL_EXP : GL_LINEAR);
925  }
926  if (dmp->dm_light) {
927  glEnable(GL_LIGHTING);
928  }
929  }
930 
931  if (dmp->dm_debugLevel == 3) {
932  GLfloat m[16];
933  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
934 
935  bu_vls_printf(&tmp_vls, "after begin view matrix = \n");
936 
937  glGetFloatv (GL_MODELVIEW_MATRIX, m);
938  osgl_printglmat(&tmp_vls, m);
939  bu_vls_printf(&tmp_vls, "after begin projection matrix = \n");
940  glGetFloatv (GL_PROJECTION_MATRIX, m);
941  osgl_printglmat(&tmp_vls, m);
942 
943  bu_log("%s", bu_vls_addr(&tmp_vls));
944  bu_vls_free(&tmp_vls);
945  }
946 
947 
948  return TCL_OK;
949 }
950 
951 
952 HIDDEN int
953 osgl_drawEnd(struct dm_internal *dmp)
954 {
955  if (dmp->dm_debugLevel)
956  bu_log("osgl_drawEnd\n");
957 
958  if (dmp->dm_debugLevel == 3) {
959  GLfloat m[16];
960  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
961  bu_vls_printf(&tmp_vls, "beginning of end view matrix = \n");
962  glGetFloatv (GL_MODELVIEW_MATRIX, m);
963  osgl_printglmat(&tmp_vls, m);
964  bu_vls_printf(&tmp_vls, "beginning of end projection matrix = \n");
965  glGetFloatv (GL_PROJECTION_MATRIX, m);
966  osgl_printglmat(&tmp_vls, m);
967  bu_log("%s", bu_vls_addr(&tmp_vls));
968  bu_vls_free(&tmp_vls);
969  }
970 
971 
972  if (dmp->dm_light) {
973  glMatrixMode(GL_MODELVIEW);
974  glLoadIdentity();
975  glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
976  }
977 
978  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->graphicsContext->swapBuffers();
979  if (dmp->dm_clearBufferAfter) {
980  /* give Graphics pipe time to work */
981  glClearColor(((struct osgl_vars *)dmp->dm_vars.priv_vars)->r,
982  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g,
983  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b,
984  0.0);
985  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
986  }
987 
988  if (dmp->dm_debugLevel) {
989  int error;
990  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
991 
992  bu_vls_printf(&tmp_vls, "ANY ERRORS?\n");
993 
994  while ((error = glGetError())!=0) {
995  bu_vls_printf(&tmp_vls, "Error: %x\n", error);
996  }
997 
998  bu_log("%s", bu_vls_addr(&tmp_vls));
999  bu_vls_free(&tmp_vls);
1000  }
1001 
1002  if (dmp->dm_debugLevel == 3) {
1003  GLfloat m[16];
1004  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1005  bu_vls_printf(&tmp_vls, "end of drawend view matrix = \n");
1006  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1007  osgl_printglmat(&tmp_vls, m);
1008  bu_vls_printf(&tmp_vls, "end of drawend projection matrix = \n");
1009  glGetFloatv (GL_PROJECTION_MATRIX, m);
1010  osgl_printglmat(&tmp_vls, m);
1011  bu_log("%s", bu_vls_addr(&tmp_vls));
1012  bu_vls_free(&tmp_vls);
1013  }
1014 
1015 #ifdef OSG_VIEWER_TEST
1016  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
1017  privvars->testviewer->frame();
1018 #endif
1019  return TCL_OK;
1020 }
1021 
1022 
1023 /*
1024  * Load a new transformation matrix. This will be followed by
1025  * many calls to osgl_draw().
1026  */
1027 HIDDEN int
1028 osgl_loadMatrix(struct dm_internal *dmp, fastf_t *mat, int which_eye)
1029 {
1030  fastf_t *mptr;
1031  GLfloat gtmat[16];
1032 
1033  if (dmp->dm_debugLevel == 1)
1034  bu_log("osgl_loadMatrix()\n");
1035 
1036  if (dmp->dm_debugLevel == 3) {
1037  GLfloat m[16];
1038  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1039  bu_vls_printf(&tmp_vls, "beginning of loadMatrix view matrix = \n");
1040  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1041  osgl_printglmat(&tmp_vls, m);
1042  bu_vls_printf(&tmp_vls, "beginning of loadMatrix projection matrix = \n");
1043  glGetFloatv (GL_PROJECTION_MATRIX, m);
1044  osgl_printglmat(&tmp_vls, m);
1045  bu_log("%s", bu_vls_addr(&tmp_vls));
1046  bu_vls_free(&tmp_vls);
1047  }
1048 
1049 
1050  if (dmp->dm_debugLevel == 3) {
1051  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1052 
1053  bu_vls_printf(&tmp_vls, "transformation matrix = \n");
1054  osgl_printmat(&tmp_vls, mat);
1055 
1056  bu_log("%s", bu_vls_addr(&tmp_vls));
1057  bu_vls_free(&tmp_vls);
1058  }
1059 
1060  switch (which_eye) {
1061  case 0:
1062  /* Non-stereo */
1063  break;
1064  case 1:
1065  /* R eye */
1066  glViewport(0, 0, (XMAXSCREEN)+1, (YSTEREO)+1);
1067  glScissor(0, 0, (XMAXSCREEN)+1, (YSTEREO)+1);
1068  osgl_drawString2D(dmp, "R", 0.986, 0.0, 0, 1);
1069  break;
1070  case 2:
1071  /* L eye */
1072  glViewport(0, 0+YOFFSET_LEFT, (XMAXSCREEN)+1,
1073  (YSTEREO+YOFFSET_LEFT)-(YOFFSET_LEFT)+1);
1074  glScissor(0, 0+YOFFSET_LEFT, (XMAXSCREEN)+1,
1075  (YSTEREO+YOFFSET_LEFT)-(YOFFSET_LEFT)+1);
1076  break;
1077  }
1078 
1079  mptr = mat;
1080 
1081  gtmat[0] = *(mptr++);
1082  gtmat[4] = *(mptr++);
1083  gtmat[8] = *(mptr++);
1084  gtmat[12] = *(mptr++);
1085 
1086  gtmat[1] = *(mptr++) * dmp->dm_aspect;
1087  gtmat[5] = *(mptr++) * dmp->dm_aspect;
1088  gtmat[9] = *(mptr++) * dmp->dm_aspect;
1089  gtmat[13] = *(mptr++) * dmp->dm_aspect;
1090 
1091  gtmat[2] = *(mptr++);
1092  gtmat[6] = *(mptr++);
1093  gtmat[10] = *(mptr++);
1094  gtmat[14] = *(mptr++);
1095 
1096  gtmat[3] = *(mptr++);
1097  gtmat[7] = *(mptr++);
1098  gtmat[11] = *(mptr++);
1099  gtmat[15] = *(mptr++);
1100 
1101  glMatrixMode(GL_MODELVIEW);
1102  glLoadIdentity();
1103  glLoadMatrixf(gtmat);
1104 
1105  if (dmp->dm_debugLevel == 3) {
1106  GLfloat m[16];
1107  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1108  bu_vls_printf(&tmp_vls, "end of loadMatrix view matrix = \n");
1109  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1110  osgl_printglmat(&tmp_vls, m);
1111  bu_vls_printf(&tmp_vls, "end of loadMatrix projection matrix = \n");
1112  glGetFloatv (GL_PROJECTION_MATRIX, m);
1113  osgl_printglmat(&tmp_vls, m);
1114  bu_log("%s", bu_vls_addr(&tmp_vls));
1115  bu_vls_free(&tmp_vls);
1116  }
1117 
1118 
1119 #ifdef OSG_VIEWER_TEST
1120  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
1121  mat_t glmat;
1122  glmat[0] = mat[0];
1123  glmat[4] = mat[1];
1124  glmat[8] = mat[2];
1125  glmat[12] = mat[3];
1126 
1127  glmat[1] = mat[4] * dmp->dm_aspect;
1128  glmat[5] = mat[5] * dmp->dm_aspect;
1129  glmat[9] = mat[6] * dmp->dm_aspect;
1130  glmat[13] = mat[7] * dmp->dm_aspect;
1131 
1132  glmat[2] = mat[8];
1133  glmat[6] = mat[9];
1134  glmat[10] = mat[10];
1135  glmat[14] = mat[11];
1136 
1137  glmat[3] = mat[12];
1138  glmat[7] = mat[13];
1139  glmat[11] = mat[14];
1140  glmat[15] = mat[15];
1141 
1142  osg::Matrix osg_mp(
1143  glmat[0], glmat[1], glmat[2], glmat[3],
1144  glmat[4], glmat[5], glmat[6], glmat[7],
1145  glmat[8], glmat[9], glmat[10], glmat[11],
1146  glmat[12], glmat[13], glmat[14], glmat[15]);
1147 
1148  privvars->testviewer->getCamera()->getViewMatrix().set(osg_mp);
1149  privvars->testviewer->frame();
1150 #endif
1151 
1152  return TCL_OK;
1153 }
1154 
1155 
1156 /*
1157  * Load a new projection matrix.
1158  *
1159  */
1160 HIDDEN int
1161 osgl_loadPMatrix(struct dm_internal *dmp, fastf_t *mat)
1162 {
1163  fastf_t *mptr;
1164  GLfloat gtmat[16];
1165 
1166  glMatrixMode(GL_PROJECTION);
1167 
1168  if (mat == (fastf_t *)NULL) {
1169  if (((struct osgl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
1170  glPopMatrix();
1171  glLoadIdentity();
1172  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1173  glPushMatrix();
1174  glLoadMatrixd(((struct osgl_vars *)dmp->dm_vars.priv_vars)->faceplate_mat);
1175  } else {
1176  glLoadIdentity();
1177  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1178  }
1179 
1180  return TCL_OK;
1181  }
1182 
1183  mptr = mat;
1184 
1185  gtmat[0] = *(mptr++);
1186  gtmat[4] = *(mptr++);
1187  gtmat[8] = *(mptr++);
1188  gtmat[12] = *(mptr++);
1189 
1190  gtmat[1] = *(mptr++);
1191  gtmat[5] = *(mptr++);
1192  gtmat[9] = *(mptr++);
1193  gtmat[13] = *(mptr++);
1194 
1195  gtmat[2] = *(mptr++);
1196  gtmat[6] = *(mptr++);
1197  gtmat[10] = -*(mptr++);
1198  gtmat[14] = -*(mptr++);
1199 
1200  gtmat[3] = *(mptr++);
1201  gtmat[7] = *(mptr++);
1202  gtmat[11] = *(mptr++);
1203  gtmat[15] = *(mptr++);
1204 
1205  glLoadIdentity();
1206  glLoadMatrixf(gtmat);
1207 
1208 #ifdef OSG_VIEWER_TEST
1209  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
1210  mat_t glmat;
1211  glmat[0] = mat[0];
1212  glmat[4] = mat[1];
1213  glmat[8] = mat[2];
1214  glmat[12] = mat[3];
1215 
1216  glmat[1] = mat[4];
1217  glmat[5] = mat[5];
1218  glmat[9] = mat[6];
1219  glmat[13] = mat[7];
1220 
1221  glmat[2] = mat[8];
1222  glmat[6] = mat[9];
1223  glmat[10] = -mat[10];
1224  glmat[14] = -mat[11];
1225 
1226  glmat[3] = mat[12];
1227  glmat[7] = mat[13];
1228  glmat[11] = mat[14];
1229  glmat[15] = mat[15];
1230 
1231  osg::Matrix osg_mp(
1232  glmat[0], glmat[1], glmat[2], glmat[3],
1233  glmat[4], glmat[5], glmat[6], glmat[7],
1234  glmat[8], glmat[9], glmat[10], glmat[11],
1235  glmat[12], glmat[13], glmat[14], glmat[15]);
1236 
1237  privvars->testviewer->getCamera()->setProjectionMatrix(osg_mp);
1238  privvars->testviewer->frame();
1239 #endif
1240  return TCL_OK;
1241 }
1242 
1243 
1244 HIDDEN int
1245 osgl_drawVListHiddenLine(struct dm_internal *dmp, register struct bn_vlist *vp)
1246 {
1247  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
1248  register struct bn_vlist *tvp;
1249  register int first;
1250 
1251  if (dmp->dm_debugLevel == 1)
1252  bu_log("osgl_drawVList()\n");
1253 
1254 
1255  /* First, draw polygons using background color. */
1256 
1257  if (dmp->dm_light) {
1258  glDisable(GL_LIGHTING);
1259  }
1260 
1261  glDisable(GL_BLEND);
1262  glDepthMask(GL_TRUE);
1263  glEnable(GL_DEPTH_TEST);
1264  glDepthFunc(GL_LEQUAL);
1265  glEnable(GL_POLYGON_OFFSET_FILL);
1266  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1267  glPolygonOffset(1.0, 1.0);
1268 
1269  /* Set color to background color for drawing polygons. */
1270  glColor3f(((struct osgl_vars *)dmp->dm_vars.priv_vars)->r,
1271  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->g,
1272  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->b);
1273 
1274  /* Viewing region is from -1.0 to +1.0 */
1275  first = 1;
1276  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1277  register int i;
1278  register int nused = tvp->nused;
1279  register int *cmd = tvp->cmd;
1280  point_t *pt = tvp->pt;
1281  for (i = 0; i < nused; i++, cmd++, pt++) {
1282  GLdouble dpt[3];
1283  VMOVE(dpt, *pt); /* fastf_t-to-double */
1284 /*
1285  if (dmp->dm_debugLevel > 2)
1286  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1287 
1288  switch (*cmd) {
1289  case BN_VLIST_LINE_MOVE:
1290  case BN_VLIST_LINE_DRAW:
1291  break;
1292  case BN_VLIST_POLY_START:
1293  /* Start poly marker & normal */
1294  if (first == 0)
1295  glEnd();
1296  first = 0;
1297 
1298  glBegin(GL_POLYGON);
1299  /* Set surface normal (vl_pnt points outward) */
1300  glNormal3dv(dpt);
1301  break;
1302  case BN_VLIST_POLY_MOVE:
1303  case BN_VLIST_POLY_DRAW:
1304  case BN_VLIST_TRI_MOVE:
1305  case BN_VLIST_TRI_DRAW:
1306  glVertex3dv(dpt);
1307  break;
1308  case BN_VLIST_POLY_END:
1309  /* Draw, End Polygon */
1310  glEnd();
1311  first = 1;
1312  break;
1314  case BN_VLIST_TRI_VERTNORM:
1315  /* Set per-vertex normal. Given before vert. */
1316  glNormal3dv(dpt);
1317  break;
1318  case BN_VLIST_TRI_START:
1319  if (first)
1320  glBegin(GL_TRIANGLES);
1321 
1322  first = 0;
1323 
1324  /* Set surface normal (vl_pnt points outward) */
1325  glNormal3dv(dpt);
1326 
1327  break;
1328  case BN_VLIST_TRI_END:
1329  break;
1330  }
1331  }
1332  }
1333 
1334  if (first == 0)
1335  glEnd();
1336 
1337  /* Last, draw wireframe/edges. */
1338 
1339  /* Set color to wireColor for drawing wireframe/edges */
1340  glColor3f(wireColor[0], wireColor[1], wireColor[2]);
1341 
1342  /* Viewing region is from -1.0 to +1.0 */
1343  first = 1;
1344  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1345  register int i;
1346  register int nused = tvp->nused;
1347  register int *cmd = tvp->cmd;
1348  point_t *pt = tvp->pt;
1349 
1350  for (i = 0; i < nused; i++, cmd++, pt++) {
1351  GLdouble dpt[3];
1352  VMOVE(dpt, *pt); /* fastf_t-to-double */
1353 /*
1354  if (dmp->dm_debugLevel > 2)
1355  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1356 
1357  switch (*cmd) {
1358  case BN_VLIST_LINE_MOVE:
1359  /* Move, start line */
1360  if (first == 0)
1361  glEnd();
1362  first = 0;
1363 
1364  glBegin(GL_LINE_STRIP);
1365  glVertex3dv(dpt);
1366  break;
1367  case BN_VLIST_POLY_START:
1368  case BN_VLIST_TRI_START:
1369  /* Start poly marker & normal */
1370  if (first == 0)
1371  glEnd();
1372  first = 0;
1373 
1374  glBegin(GL_LINE_STRIP);
1375  break;
1376  case BN_VLIST_LINE_DRAW:
1377  case BN_VLIST_POLY_MOVE:
1378  case BN_VLIST_POLY_DRAW:
1379  case BN_VLIST_TRI_MOVE:
1380  case BN_VLIST_TRI_DRAW:
1381  glVertex3dv(dpt);
1382  break;
1383  case BN_VLIST_POLY_END:
1384  case BN_VLIST_TRI_END:
1385  /* Draw, End Polygon */
1386  glVertex3dv(dpt);
1387  glEnd();
1388  first = 1;
1389  break;
1391  case BN_VLIST_TRI_VERTNORM:
1392  /* Set per-vertex normal. Given before vert. */
1393  glNormal3dv(dpt);
1394  break;
1395  }
1396  }
1397  }
1398 
1399  if (first == 0)
1400  glEnd();
1401 
1402  if (dmp->dm_light) {
1403  glEnable(GL_LIGHTING);
1404  }
1405 
1406  if (!mvars->zbuffer_on)
1407  glDisable(GL_DEPTH_TEST);
1408 
1409  if (!dmp->dm_depthMask)
1410  glDepthMask(GL_FALSE);
1411 
1412  glDisable(GL_POLYGON_OFFSET_FILL);
1413 
1414  return TCL_OK;
1415 }
1416 
1417 
1418 HIDDEN int
1419 osgl_drawVList(struct dm_internal *dmp, struct bn_vlist *vp)
1420 {
1421  struct bn_vlist *tvp;
1422  register int first;
1423  register int mflag = 1;
1424  static float black[4] = {0.0, 0.0, 0.0, 0.0};
1425  GLfloat originalPointSize, originalLineWidth;
1426 
1427  glGetFloatv(GL_POINT_SIZE, &originalPointSize);
1428  glGetFloatv(GL_LINE_WIDTH, &originalLineWidth);
1429 
1430  if (dmp->dm_debugLevel == 1)
1431  bu_log("osgl_drawVList()\n");
1432 
1433  /* OGL dm appears to have this set already, but we need to
1434  * do it here to match the default appearance of the wireframes
1435  * with OSG. */
1436  glEnable(GL_DEPTH_TEST);
1437 
1438  /* Viewing region is from -1.0 to +1.0 */
1439  first = 1;
1440  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1441  int i;
1442  int nused = tvp->nused;
1443  int *cmd = tvp->cmd;
1444  point_t *pt = tvp->pt;
1445  for (i = 0; i < nused; i++, cmd++, pt++) {
1446  GLdouble dpt[3];
1447  VMOVE(dpt, *pt);
1448 /*
1449  if (dmp->dm_debugLevel > 2)
1450  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1451 
1452  switch (*cmd) {
1453  case BN_VLIST_LINE_MOVE:
1454  /* Move, start line */
1455  if (first == 0)
1456  glEnd();
1457  first = 0;
1458 
1459  if (dmp->dm_light && mflag) {
1460  mflag = 0;
1461  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, wireColor);
1462  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black);
1463  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
1464  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black);
1465 
1466  if (dmp->dm_transparency)
1467  glDisable(GL_BLEND);
1468  }
1469 
1470  glBegin(GL_LINE_STRIP);
1471  glVertex3dv(dpt);
1472  break;
1473  case BN_VLIST_POLY_START:
1474  case BN_VLIST_TRI_START:
1475  /* Start poly marker & normal */
1476 
1477  if (dmp->dm_light && mflag) {
1478  mflag = 0;
1479  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
1480  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
1481  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
1482  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
1483 
1484  switch (dmp->dm_light) {
1485  case 1:
1486  break;
1487  case 2:
1488  glMaterialfv(GL_BACK, GL_DIFFUSE, diffuseColor);
1489  break;
1490  case 3:
1491  glMaterialfv(GL_BACK, GL_DIFFUSE, backDiffuseColorDark);
1492  break;
1493  default:
1494  glMaterialfv(GL_BACK, GL_DIFFUSE, backDiffuseColorLight);
1495  break;
1496  }
1497 
1498  if (dmp->dm_transparency)
1499  glEnable(GL_BLEND);
1500  }
1501 
1502  if (*cmd == BN_VLIST_POLY_START) {
1503  if (first == 0)
1504  glEnd();
1505 
1506  glBegin(GL_POLYGON);
1507  } else if (first)
1508  glBegin(GL_TRIANGLES);
1509 
1510  /* Set surface normal (vl_pnt points outward) */
1511  glNormal3dv(dpt);
1512 
1513  first = 0;
1514 
1515  break;
1516  case BN_VLIST_LINE_DRAW:
1517  case BN_VLIST_POLY_MOVE:
1518  case BN_VLIST_POLY_DRAW:
1519  case BN_VLIST_TRI_MOVE:
1520  case BN_VLIST_TRI_DRAW:
1521  glVertex3dv(dpt);
1522  break;
1523  case BN_VLIST_POLY_END:
1524  /* Draw, End Polygon */
1525  glEnd();
1526  first = 1;
1527  break;
1528  case BN_VLIST_TRI_END:
1529  break;
1531  case BN_VLIST_TRI_VERTNORM:
1532  /* Set per-vertex normal. Given before vert. */
1533  glNormal3dv(dpt);
1534  break;
1535  case BN_VLIST_POINT_DRAW:
1536  if (first == 0)
1537  glEnd();
1538  first = 0;
1539  glBegin(GL_POINTS);
1540  glVertex3dv(dpt);
1541  break;
1542  case BN_VLIST_LINE_WIDTH: {
1543  GLfloat lineWidth = (GLfloat)(*pt)[0];
1544  if (lineWidth > 0.0) {
1545  glLineWidth(lineWidth);
1546  }
1547  break;
1548  }
1549  case BN_VLIST_POINT_SIZE: {
1550  GLfloat pointSize = (GLfloat)(*pt)[0];
1551  if (pointSize > 0.0) {
1552  glPointSize(pointSize);
1553  }
1554  break;
1555  }
1556  }
1557  }
1558  }
1559 
1560  if (first == 0)
1561  glEnd();
1562 
1563  if (dmp->dm_light && dmp->dm_transparency)
1564  glDisable(GL_BLEND);
1565 
1566  glPointSize(originalPointSize);
1567  glLineWidth(originalLineWidth);
1568 
1569 #ifdef OSG_VIEWER_TEST
1570  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
1571 
1572  glPointSize(originalPointSize);
1573  glLineWidth(originalLineWidth);
1574 
1575  // create the osg containers to hold our data.
1576  osg::ref_ptr<osg::Geode> geode = new osg::Geode(); // Maybe create this at drawBegin?
1577  osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
1578  osg::ref_ptr<osg::Vec3dArray> vertices = new osg::Vec3dArray;
1579  osg::ref_ptr<osg::Vec3dArray> normals = new osg::Vec3dArray;
1580 
1581  // Set line color
1582  osg::Vec4Array* line_color = new osg::Vec4Array;
1583  line_color->push_back(osg::Vec4(255, 255, 100, 70));
1584  geom->setColorArray(line_color, osg::Array::BIND_OVERALL);
1585 
1586  // Set wireframe state
1587  osg::StateSet *geom_state = geom->getOrCreateStateSet();
1588  osg::ref_ptr<osg::PolygonMode> geom_polymode = new osg::PolygonMode;
1589  geom_polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
1590  geom_state->setAttributeAndModes(geom_polymode);
1591  geom_state->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
1592 
1593  /* Viewing region is from -1.0 to +1.0 */
1594  int begin = 0;
1595  int nverts = 0;
1596  first = 1;
1597  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1598  int i;
1599  int nused = tvp->nused;
1600  int *cmd = tvp->cmd;
1601  point_t *pt = tvp->pt;
1602  for (i = 0; i < nused; i++, cmd++, pt++) {
1603  switch (*cmd) {
1604  case BN_VLIST_LINE_MOVE:
1605  /* Move, start line */
1606  if (first == 0) {
1607  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,begin,nverts));
1608 
1609  } else
1610  first = 0;
1611 
1612  vertices->push_back(osg::Vec3d((*pt)[X], (*pt)[Y], (*pt)[Z]));
1613  normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
1614  begin += nverts;
1615  nverts = 1;
1616  break;
1617  case BN_VLIST_POLY_START:
1618  normals->push_back(osg::Vec3d((*pt)[X], (*pt)[Y], (*pt)[Z]));
1619  begin += nverts;
1620  nverts = 0;
1621  break;
1622  case BN_VLIST_LINE_DRAW:
1623  case BN_VLIST_POLY_MOVE:
1624  case BN_VLIST_POLY_DRAW:
1625  vertices->push_back(osg::Vec3d((*pt)[X], (*pt)[Y], (*pt)[Z]));
1626  ++nverts;
1627  break;
1628  case BN_VLIST_POLY_END:
1629  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,begin,nverts));
1630  first = 1;
1631  break;
1633  break;
1634  }
1635  }
1636  }
1637 
1638  if (first == 0) {
1639  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,begin,nverts));
1640  }
1641 
1642  geom->setVertexArray(vertices);
1643  geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
1644  //geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
1645 
1646  geom->setUseDisplayList(true);
1647  geode->addDrawable(geom);
1648  privvars->osg_root->addChild(geode);
1649 #endif
1650 
1651 
1652  /* Need this back off for underlay with framebuffer */
1653  glDisable(GL_DEPTH_TEST);
1654 
1655  return TCL_OK;
1656 }
1657 
1658 
1659 HIDDEN int
1660 osgl_draw(struct dm_internal *dmp, struct bn_vlist *(*callback_function)(void *), void **data)
1661 {
1662  struct bn_vlist *vp;
1663  if (!callback_function) {
1664  if (data) {
1665  vp = (struct bn_vlist *)data;
1666  osgl_drawVList(dmp, vp);
1667  }
1668  } else {
1669  if (!data) {
1670  return TCL_ERROR;
1671  } else {
1672  (void)callback_function(data);
1673  }
1674  }
1675  return TCL_OK;
1676 }
1677 
1678 
1679 /*
1680  * Restore the display processor to a normal mode of operation
1681  * (i.e., not scaled, rotated, displaced, etc.).
1682  */
1683 HIDDEN int
1684 osgl_normal(struct dm_internal *dmp)
1685 {
1686  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
1687  if (dmp->dm_debugLevel)
1688  bu_log("osgl_normal\n");
1689 
1690  if (dmp->dm_debugLevel == 3) {
1691  GLfloat m[16];
1692  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1693  bu_vls_printf(&tmp_vls, "beginning of osgl_normal view matrix = \n");
1694  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1695  osgl_printglmat(&tmp_vls, m);
1696  bu_vls_printf(&tmp_vls, "beginning of osgl_normal projection matrix = \n");
1697  glGetFloatv (GL_PROJECTION_MATRIX, m);
1698  osgl_printglmat(&tmp_vls, m);
1699  bu_log("%s", bu_vls_addr(&tmp_vls));
1700  bu_vls_free(&tmp_vls);
1701  }
1702 
1703  if (!((struct osgl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
1704  glMatrixMode(GL_PROJECTION);
1705  glPushMatrix();
1706  glLoadMatrixd(((struct osgl_vars *)dmp->dm_vars.priv_vars)->faceplate_mat);
1707  glMatrixMode(GL_MODELVIEW);
1708  glPushMatrix();
1709  glLoadIdentity();
1710  ((struct osgl_vars *)dmp->dm_vars.priv_vars)->face_flag = 1;
1711  if (mvars->cueing_on)
1712  glDisable(GL_FOG);
1713  if (dmp->dm_light)
1714  glDisable(GL_LIGHTING);
1715  }
1716 
1717  if (dmp->dm_debugLevel == 3) {
1718  GLfloat m[16];
1719  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1720  bu_vls_printf(&tmp_vls, "end of osgl_normal view matrix = \n");
1721  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1722  osgl_printglmat(&tmp_vls, m);
1723  bu_vls_printf(&tmp_vls, "end of osgl_normal projection matrix = \n");
1724  glGetFloatv (GL_PROJECTION_MATRIX, m);
1725  osgl_printglmat(&tmp_vls, m);
1726  bu_log("%s", bu_vls_addr(&tmp_vls));
1727  bu_vls_free(&tmp_vls);
1728  }
1729 
1730  return TCL_OK;
1731 }
1732 
1733 
1734 /*
1735  * Output a string.
1736  * The starting position of the beam is as specified.
1737  */
1738 HIDDEN int
1739 osgl_drawString2D(struct dm_internal *dmp, const char *str, fastf_t x, fastf_t y, int UNUSED(size), int UNUSED(use_aspect))
1740 {
1741  fastf_t font_size = dm_get_fontsize(dmp);
1742  struct osgl_vars *privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
1743  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
1744  int blend_state = glIsEnabled(GL_BLEND);
1745  fastf_t coord_x, coord_y;
1746  if (dmp->dm_debugLevel)
1747  bu_log("osgl_drawString2D()\n");
1748  if (!(int)font_size) {
1749  font_size = dm_get_height(dmp)/60.0;
1750  }
1751  if (privvars->fontNormal != FONS_INVALID) {
1752  coord_x = (x + 1)/2 * dm_get_width(dmp);
1753  coord_y = dm_get_height(dmp) - ((y + 1)/2 * dm_get_height(dmp));
1754 
1755  glEnable(GL_BLEND);
1756  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1757 
1758  glMatrixMode(GL_PROJECTION);
1759  glLoadIdentity();
1760  glOrtho(0,dm_get_width(dmp),dm_get_height(dmp),0,-1,1);
1761  glMatrixMode(GL_MODELVIEW);
1762  glLoadIdentity();
1763 
1764  fonsSetFont(privvars->fs, privvars->fontNormal);
1765  /* drop shadow */
1766  if (mvars->text_shadow) {
1767  unsigned int black = glfonsRGBA(0, 0, 0, 255);
1768  fonsSetColor(privvars->fs, black);
1769  fonsDrawText(privvars->fs, coord_x, coord_y-2, str, NULL);
1770  fonsDrawText(privvars->fs, coord_x, coord_y+2, str, NULL);
1771  fonsDrawText(privvars->fs, coord_x-2, coord_y, str, NULL);
1772  fonsDrawText(privvars->fs, coord_x+2, coord_y, str, NULL);
1773  }
1774  /* normal text */
1775  unsigned int color = glfonsRGBA(dmp->dm_fg[0], dmp->dm_fg[1], dmp->dm_fg[2], 255);
1776  fonsSetSize(privvars->fs, (int)font_size); /* cast to int so we always get a font */
1777  fonsSetColor(privvars->fs, color);
1778  fonsDrawText(privvars->fs, coord_x, coord_y, str, NULL);
1779 
1780  if (!blend_state) glDisable(GL_BLEND);
1781  glMatrixMode(GL_PROJECTION);
1782  glLoadIdentity();
1783  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1784  glMatrixMode(GL_MODELVIEW);
1785  glLoadIdentity();
1786  }
1787 
1788  return TCL_OK;
1789 }
1790 
1791 
1792 HIDDEN int
1793 osgl_drawLine2D(struct dm_internal *dmp, fastf_t X1, fastf_t Y1, fastf_t X2, fastf_t Y2)
1794 {
1795  return drawLine2D(dmp, X1, Y1, X2, Y2, "osgl_drawLine2D()\n");
1796 }
1797 
1798 
1799 HIDDEN int
1800 osgl_drawLine3D(struct dm_internal *dmp, point_t pt1, point_t pt2)
1801 {
1802  return drawLine3D(dmp, pt1, pt2, "osgl_drawLine3D()\n", wireColor);
1803 }
1804 
1805 
1806 HIDDEN int
1807 osgl_drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int sflag)
1808 {
1809  return drawLines3D(dmp, npoints, points, sflag, "osgl_drawLine3D()\n", wireColor);
1810 }
1811 
1812 
1813 HIDDEN int
1814 osgl_drawPoint2D(struct dm_internal *dmp, fastf_t x, fastf_t y)
1815 {
1816  if (dmp->dm_debugLevel) {
1817  bu_log("osgl_drawPoint2D():\n");
1818  bu_log("\tdmp: %p\tx - %lf\ty - %lf\n", (void *)dmp, x, y);
1819  }
1820 
1821  glBegin(GL_POINTS);
1822  glVertex2f(x, y);
1823  glEnd();
1824 
1825  return TCL_OK;
1826 }
1827 
1828 
1829 HIDDEN int
1830 osgl_drawPoint3D(struct dm_internal *dmp, point_t point)
1831 {
1832  GLdouble dpt[3];
1833 
1834  if (!dmp || !point)
1835  return TCL_ERROR;
1836 
1837  if (dmp->dm_debugLevel) {
1838  bu_log("osgl_drawPoint3D():\n");
1839  bu_log("\tdmp: %p\tpt - %lf %lf %lf\n", (void*)dmp, V3ARGS(point));
1840  }
1841 
1842  /* fastf_t to double */
1843  VMOVE(dpt, point);
1844 
1845  glBegin(GL_POINTS);
1846  glVertex3dv(dpt);
1847  glEnd();
1848 
1849  return TCL_OK;
1850 }
1851 
1852 
1853 HIDDEN int
1854 osgl_drawPoints3D(struct dm_internal *dmp, int npoints, point_t *points)
1855 {
1856  GLdouble dpt[3];
1857  register int i;
1858 
1859  if (!dmp || npoints < 0 || !points)
1860  return TCL_ERROR;
1861 
1862  if (dmp->dm_debugLevel) {
1863  bu_log("osgl_drawPoint3D():\n");
1864  }
1865 
1866 
1867  glBegin(GL_POINTS);
1868  for (i = 0; i < npoints; ++i) {
1869  /* fastf_t to double */
1870  VMOVE(dpt, points[i]);
1871  glVertex3dv(dpt);
1872  }
1873  glEnd();
1874 
1875  return TCL_OK;
1876 }
1877 
1878 
1879 HIDDEN int
1880 osgl_setFGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency)
1881 {
1882  /*if (dmp->dm_debugLevel)
1883  bu_log("osgl_setFGColor()\n");*/
1884 
1885  dmp->dm_fg[0] = r;
1886  dmp->dm_fg[1] = g;
1887  dmp->dm_fg[2] = b;
1888 
1889  /* wireColor gets the full rgb */
1890  wireColor[0] = r / 255.0;
1891  wireColor[1] = g / 255.0;
1892  wireColor[2] = b / 255.0;
1893  wireColor[3] = transparency;
1894 
1895  if (strict) {
1896  glColor3ub((GLubyte)r, (GLubyte)g, (GLubyte)b);
1897  } else {
1898 
1899  if (dmp->dm_light) {
1900  /* Ambient = .2, Diffuse = .6, Specular = .2 */
1901 
1902  ambientColor[0] = wireColor[0] * 0.2;
1903  ambientColor[1] = wireColor[1] * 0.2;
1904  ambientColor[2] = wireColor[2] * 0.2;
1905  ambientColor[3] = wireColor[3];
1906 
1907  specularColor[0] = ambientColor[0];
1908  specularColor[1] = ambientColor[1];
1909  specularColor[2] = ambientColor[2];
1910  specularColor[3] = ambientColor[3];
1911 
1912  diffuseColor[0] = wireColor[0] * 0.6;
1913  diffuseColor[1] = wireColor[1] * 0.6;
1914  diffuseColor[2] = wireColor[2] * 0.6;
1915  diffuseColor[3] = wireColor[3];
1916 
1917  backDiffuseColorDark[0] = wireColor[0] * 0.3;
1918  backDiffuseColorDark[1] = wireColor[1] * 0.3;
1919  backDiffuseColorDark[2] = wireColor[2] * 0.3;
1920  backDiffuseColorDark[3] = wireColor[3];
1921 
1922  backDiffuseColorLight[0] = wireColor[0] * 0.9;
1923  backDiffuseColorLight[1] = wireColor[1] * 0.9;
1924  backDiffuseColorLight[2] = wireColor[2] * 0.9;
1925  backDiffuseColorLight[3] = wireColor[3];
1926 
1927  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
1928  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
1929  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
1930  } else {
1931  glColor3ub((GLubyte)r, (GLubyte)g, (GLubyte)b);
1932  }
1933  }
1934 
1935  return TCL_OK;
1936 }
1937 
1938 
1939 HIDDEN int
1940 osgl_setLineAttr(struct dm_internal *dmp, int width, int style)
1941 {
1942  /*if (dmp->dm_debugLevel)
1943  bu_log("osgl_setLineAttr()\n");*/
1944 
1945  dmp->dm_lineWidth = width;
1946  dmp->dm_lineStyle = style;
1947 
1948  glLineWidth((GLfloat) width);
1949 
1950  if (style == DM_DASHED_LINE)
1951  glEnable(GL_LINE_STIPPLE);
1952  else
1953  glDisable(GL_LINE_STIPPLE);
1954 
1955  return TCL_OK;
1956 }
1957 
1958 
1959 HIDDEN int
1960 osgl_debug(struct dm_internal *dmp, int lvl)
1961 {
1962  dmp->dm_debugLevel = lvl;
1963 
1964  return TCL_OK;
1965 }
1966 
1967 HIDDEN int
1968 osgl_logfile(struct dm_internal *dmp, const char *filename)
1969 {
1970  bu_vls_sprintf(&dmp->dm_log, "%s", filename);
1971 
1972  return TCL_OK;
1973 }
1974 
1975 HIDDEN int
1976 osgl_setWinBounds(struct dm_internal *dmp, fastf_t *w)
1977 {
1978  GLint mm;
1979 
1980  if (dmp->dm_debugLevel)
1981  bu_log("osgl_setWinBounds()\n");
1982 
1983  dmp->dm_clipmin[0] = w[0];
1984  dmp->dm_clipmin[1] = w[2];
1985  dmp->dm_clipmin[2] = w[4];
1986  dmp->dm_clipmax[0] = w[1];
1987  dmp->dm_clipmax[1] = w[3];
1988  dmp->dm_clipmax[2] = w[5];
1989 
1990  glGetIntegerv(GL_MATRIX_MODE, &mm);
1991  glMatrixMode(GL_PROJECTION);
1992  glPopMatrix();
1993  glLoadIdentity();
1994  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1995  glPushMatrix();
1996  glMatrixMode(mm);
1997 
1998  return TCL_OK;
1999 }
2000 
2001 
2002 HIDDEN int
2003 osgl_setTransparency(struct dm_internal *dmp,
2004  int transparency_on)
2005 {
2006  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
2007  if (dmp->dm_debugLevel)
2008  bu_log("osgl_setTransparency()\n");
2009 
2010  dmp->dm_transparency = transparency_on;
2011  mvars->transparency_on = dmp->dm_transparency;
2012 
2013  if (transparency_on) {
2014  /* Turn it on */
2015  glEnable(GL_BLEND);
2016  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2017  } else {
2018  /* Turn it off */
2019  glDisable(GL_BLEND);
2020  }
2021 
2022  return TCL_OK;
2023 }
2024 
2025 
2026 HIDDEN int
2027 osgl_setDepthMask(struct dm_internal *dmp,
2028  int enable) {
2029  if (dmp->dm_debugLevel)
2030  bu_log("osgl_setDepthMask()\n");
2031 
2032  dmp->dm_depthMask = enable;
2033 
2034  if (enable)
2035  glDepthMask(GL_TRUE);
2036  else
2037  glDepthMask(GL_FALSE);
2038 
2039  return TCL_OK;
2040 }
2041 
2042 
2043 HIDDEN int
2044 osgl_setZBuffer(struct dm_internal *dmp, int zbuffer_on)
2045 {
2046  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
2047  if (dmp->dm_debugLevel)
2048  bu_log("osgl_setZBuffer:\n");
2049 
2050  dmp->dm_zbuffer = zbuffer_on;
2051  mvars->zbuffer_on = dmp->dm_zbuffer;
2052 
2053  if (mvars->zbuf == 0) {
2054  dmp->dm_zbuffer = 0;
2055  mvars->zbuffer_on = dmp->dm_zbuffer;
2056  }
2057 
2058  if (mvars->zbuffer_on) {
2059  glDepthFunc(GL_LEQUAL);
2060  glEnable(GL_DEPTH_TEST);
2061  } else {
2062  glDisable(GL_DEPTH_TEST);
2063  }
2064 
2065  return TCL_OK;
2066 }
2067 
2068 
2069 HIDDEN int
2070 osgl_beginDList(struct dm_internal *dmp, unsigned int list)
2071 {
2072  if (dmp->dm_debugLevel)
2073  bu_log("osgl_beginDList()\n");
2074 
2075  glNewList((GLuint)list, GL_COMPILE);
2076  return TCL_OK;
2077 }
2078 
2079 
2080 HIDDEN int
2081 osgl_endDList(struct dm_internal *dmp)
2082 {
2083  if (dmp->dm_debugLevel)
2084  bu_log("osgl_endDList()\n");
2085 
2086  glEndList();
2087  return TCL_OK;
2088 }
2089 
2090 
2091 HIDDEN void
2092 osgl_drawDList(unsigned int list)
2093 {
2094  glCallList((GLuint)list);
2095 }
2096 
2097 
2098 HIDDEN int
2099 osgl_freeDLists(struct dm_internal *dmp, unsigned int list, int range)
2100 {
2101  if (dmp->dm_debugLevel)
2102  bu_log("osgl_freeDLists()\n");
2103 
2104  glDeleteLists((GLuint)list, (GLsizei)range);
2105  return TCL_OK;
2106 }
2107 
2108 
2109 HIDDEN int
2110 osgl_genDLists(struct dm_internal *dmp, size_t range)
2111 {
2112  if (dmp->dm_debugLevel)
2113  bu_log("osgl_freeDLists()\n");
2114 
2115  return glGenLists((GLsizei)range);
2116 }
2117 
2118 HIDDEN int
2119 osgl_draw_obj(struct dm_internal *dmp, struct display_list *obj)
2120 {
2121  struct solid *sp;
2122  FOR_ALL_SOLIDS(sp, &obj->dl_headSolid) {
2123  if (sp->s_dlist == 0)
2124  sp->s_dlist = dm_gen_dlists(dmp, 1);
2125 
2126  (void)dm_make_current(dmp);
2127  (void)dm_begin_dlist(dmp, sp->s_dlist);
2128  if (sp->s_iflag == UP)
2129  (void)dm_set_fg(dmp, 255, 255, 255, 0, sp->s_transparency);
2130  else
2131  (void)dm_set_fg(dmp,
2132  (unsigned char)sp->s_color[0],
2133  (unsigned char)sp->s_color[1],
2134  (unsigned char)sp->s_color[2], 0, sp->s_transparency);
2135  (void)dm_draw_vlist(dmp, (struct bn_vlist *)&sp->s_vlist);
2136  (void)dm_end_dlist(dmp);
2137  }
2138  return 0;
2139 }
2140 
2141 HIDDEN int
2142 osgl_getDisplayImage(struct dm_internal *dmp, unsigned char **image)
2143 {
2144  unsigned char *idata = NULL;
2145  int width = 0;
2146  int height = 0;
2147  int bytes_per_pixel = 3; /*rgb no alpha for raw pix */
2148  GLuint *pixels;
2149  unsigned int pixel;
2150  unsigned int red_mask = 0xff000000;
2151  unsigned int green_mask = 0x00ff0000;
2152  unsigned int blue_mask = 0x0000ff00;
2153  int h, w;
2154 #if defined(DM_WGL)
2155  unsigned int alpha_mask = 0x000000ff;
2156  int big_endian;
2157  int swap_bytes;
2158 
2159  if ((bu_byteorder() == BU_BIG_ENDIAN))
2160  big_endian = 1;
2161  else
2162  big_endian = 0;
2163 
2164  /* WTF */
2165  swap_bytes = !big_endian;
2166 #endif
2167 
2168  if (dmp->dm_type == DM_TYPE_WGL || dmp->dm_type == DM_TYPE_OSGL) {
2169  width = dmp->dm_width;
2170  height = dmp->dm_height;
2171 
2172  pixels = (GLuint *)bu_calloc(width * height, sizeof(GLuint), "pixels");
2173 
2174  {
2175  glReadBuffer(GL_FRONT);
2176 #if defined(DM_WGL)
2177  /* XXX GL_UNSIGNED_INT_8_8_8_8 is currently not
2178  * available on windows. Need to update when it
2179  * becomes available.
2180  */
2181  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2182 #else
2183  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels);
2184 #endif
2185 
2186  idata = (unsigned char *)bu_calloc(height * width * bytes_per_pixel, sizeof(unsigned char), "rgb data");
2187  *image = idata;
2188 
2189  for (h = 0; h < height; h++) {
2190  for (w = 0; w < width; w++) {
2191  int i = h*width + w;
2192  int i_h_inv = (height - h - 1)*width + w;
2193  int j = i*bytes_per_pixel;
2194  unsigned char *value = (unsigned char *)(idata + j);
2195 #if defined(DM_WGL)
2196  unsigned char alpha;
2197 #endif
2198 
2199  pixel = pixels[i_h_inv];
2200 
2201  value[0] = (pixel & red_mask) >> 24;
2202  value[1] = (pixel & green_mask) >> 16;
2203  value[2] = (pixel & blue_mask) >> 8;
2204 
2205 #if defined(DM_WGL)
2206  alpha = pixel & alpha_mask;
2207  if (swap_bytes) {
2208  unsigned char tmp_byte;
2209 
2210  value[0] = alpha;
2211  /* swap byte1 and byte2 */
2212  tmp_byte = value[1];
2213  value[1] = value[2];
2214  value[2] = tmp_byte;
2215  }
2216 #endif
2217  }
2218 
2219  }
2220 
2221  bu_free(pixels, "pixels");
2222  }
2223  } else {
2224  bu_log("osgl_getDisplayImage: Display type not set as OSGL or WGL\n");
2225  return TCL_ERROR;
2226  }
2227 
2228  return TCL_OK; /* caller will need to bu_free(idata, "image data"); */
2229 }
2230 
2231 int
2232 osgl_openFb(struct dm_internal *dmp)
2233 {
2234  struct fb_platform_specific *fb_ps;
2235  struct osgl_fb_info *ofb_ps;
2236  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
2237  /*struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;*/
2238  struct osgl_vars *privars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
2239 
2241  ofb_ps = (struct osgl_fb_info *)fb_ps->data;
2242 
2243  ofb_ps->glc = (void *)privars->graphicsContext;
2244  ofb_ps->traits = (void *)privars->traits;
2245  ofb_ps->double_buffer = mvars->doublebuffer;
2246  ofb_ps->soft_cmap = 0;
2247  dmp->fbp = fb_open_existing("osgl", dm_get_width(dmp), dm_get_height(dmp), fb_ps);
2248  fb_put_platform_specific(fb_ps);
2249  return 0;
2250 }
2251 
2252 void
2253 osgl_get_internal(struct dm_internal *dmp)
2254 {
2255  struct modifiable_osgl_vars *mvars = NULL;
2256  if (!dmp->m_vars) {
2257  BU_GET(dmp->m_vars, struct modifiable_osgl_vars);
2258  mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
2259  mvars->this_dm = dmp;
2260  bu_vls_init(&(mvars->log));
2261  }
2262 }
2263 
2264 void
2265 osgl_put_internal(struct dm_internal *dmp)
2266 {
2267  struct modifiable_osgl_vars *mvars = NULL;
2268  if (dmp->m_vars) {
2269  mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
2270  bu_vls_free(&(mvars->log));
2271  BU_PUT(dmp->m_vars, struct modifiable_osgl_vars);
2272  }
2273 }
2274 
2275 void
2276 Osgl_colorchange(const struct bu_structparse *sdp,
2277  const char *name,
2278  void *base,
2279  const char *value,
2280  void *data)
2281 {
2282  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2283  if (mvars->cueing_on) {
2284  glEnable(GL_FOG);
2285  } else {
2286  glDisable(GL_FOG);
2287  }
2288 
2289  dm_generic_hook(sdp, name, base, value, data);
2290 }
2291 
2292 static void
2293 osgl_zclip_hook(const struct bu_structparse *sdp,
2294  const char *name,
2295  void *base,
2296  const char *value,
2297  void *data)
2298 {
2299  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2300  dm *dmp = mvars->this_dm;
2301  fastf_t bounds[6] = { GED_MIN, GED_MAX, GED_MIN, GED_MAX, GED_MIN, GED_MAX };
2302 
2303  dmp->dm_zclip = mvars->zclipping_on;
2304 
2305  if (dmp->dm_zclip) {
2306  bounds[4] = -1.0;
2307  bounds[5] = 1.0;
2308  }
2309 
2310  (void)dm_make_current(dmp);
2311  (void)dm_set_win_bounds(dmp, bounds);
2312 
2313  dm_generic_hook(sdp, name, base, value, data);
2314 }
2315 
2316 static void
2317 osgl_debug_hook(const struct bu_structparse *sdp,
2318  const char *name,
2319  void *base,
2320  const char *value,
2321  void *data)
2322 {
2323  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2324  dm *dmp = mvars->this_dm;
2325 
2326  dm_debug(dmp, mvars->debug);
2327 
2328  dm_generic_hook(sdp, name, base, value, data);
2329 }
2330 
2331 
2332 static void
2333 osgl_logfile_hook(const struct bu_structparse *sdp,
2334  const char *name,
2335  void *base,
2336  const char *value,
2337  void *data)
2338 {
2339  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2340  dm *dmp = mvars->this_dm;
2341 
2342  dm_logfile(dmp, bu_vls_addr(&mvars->log));
2343 
2344  dm_generic_hook(sdp, name, base, value, data);
2345 }
2346 
2347 static void
2348 osgl_bound_hook(const struct bu_structparse *sdp,
2349  const char *name,
2350  void *base,
2351  const char *value,
2352  void *data)
2353 {
2354  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2355  dm *dmp = mvars->this_dm;
2356 
2357  dmp->dm_bound = mvars->bound;
2358 
2359  dm_generic_hook(sdp, name, base, value, data);
2360 }
2361 
2362 static void
2363 osgl_bound_flag_hook(const struct bu_structparse *sdp,
2364  const char *name,
2365  void *base,
2366  const char *value,
2367  void *data)
2368 {
2369  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2370  dm *dmp = mvars->this_dm;
2371 
2372  dmp->dm_boundFlag = mvars->boundFlag;
2373 
2374  dm_generic_hook(sdp, name, base, value, data);
2375 }
2376 
2377 static void
2378 osgl_zbuffer_hook(const struct bu_structparse *sdp,
2379  const char *name,
2380  void *base,
2381  const char *value,
2382  void *data)
2383 {
2384  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2385  dm *dmp = mvars->this_dm;
2386 
2387  (void)dm_make_current(dmp);
2388  (void)dm_set_zbuffer(dmp, mvars->zbuffer_on);
2389 
2390  dm_generic_hook(sdp, name, base, value, data);
2391 }
2392 
2393 static void
2394 osgl_lighting_hook(const struct bu_structparse *sdp,
2395  const char *name,
2396  void *base,
2397  const char *value,
2398  void *data)
2399 {
2400  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2401  dm *dmp = mvars->this_dm;
2402 
2403  (void)dm_make_current(dmp);
2404  (void)dm_set_light(dmp, mvars->lighting_on);
2405 
2406  dm_generic_hook(sdp, name, base, value, data);
2407 }
2408 
2409 static void
2410 osgl_transparency_hook(const struct bu_structparse *sdp,
2411  const char *name,
2412  void *base,
2413  const char *value,
2414  void *data)
2415 {
2416  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2417  dm *dmp = mvars->this_dm;
2418 
2419  (void)dm_make_current(dmp);
2420  (void)dm_set_transparency(dmp, mvars->transparency_on);
2421 
2422  dm_generic_hook(sdp, name, base, value, data);
2423 }
2424 
2425 static void
2426 osgl_fog_hook(const struct bu_structparse *sdp,
2427  const char *name,
2428  void *base,
2429  const char *value,
2430  void *data)
2431 {
2432  struct modifiable_osgl_vars *mvars = (struct modifiable_osgl_vars *)base;
2433  dm *dmp = mvars->this_dm;
2434 
2435  dm_fogHint(dmp, mvars->fastfog);
2436 
2437  dm_generic_hook(sdp, name, base, value, data);
2438 }
2439 
2440 struct bu_structparse Osgl_vparse[] = {
2441  {"%d", 1, "depthcue", Osgl_MV_O(cueing_on), Osgl_colorchange, NULL, NULL },
2442  {"%d", 1, "zclip", Osgl_MV_O(zclipping_on), osgl_zclip_hook, NULL, NULL },
2443  {"%d", 1, "zbuffer", Osgl_MV_O(zbuffer_on), osgl_zbuffer_hook, NULL, NULL },
2444  {"%d", 1, "lighting", Osgl_MV_O(lighting_on), osgl_lighting_hook, NULL, NULL },
2445  {"%d", 1, "transparency", Osgl_MV_O(transparency_on), osgl_transparency_hook, NULL, NULL },
2446  {"%d", 1, "fastfog", Osgl_MV_O(fastfog), osgl_fog_hook, NULL, NULL },
2447  {"%g", 1, "density", Osgl_MV_O(fogdensity), dm_generic_hook, NULL, NULL },
2448  {"%d", 1, "has_zbuf", Osgl_MV_O(zbuf), dm_generic_hook, NULL, NULL },
2449  {"%d", 1, "has_rgb", Osgl_MV_O(rgb), dm_generic_hook, NULL, NULL },
2450  {"%d", 1, "has_doublebuffer", Osgl_MV_O(doublebuffer), dm_generic_hook, NULL, NULL },
2451  {"%d", 1, "depth", Osgl_MV_O(depth), dm_generic_hook, NULL, NULL },
2452  {"%d", 1, "debug", Osgl_MV_O(debug), osgl_debug_hook, NULL, NULL },
2453  {"%V", 1, "log", Osgl_MV_O(log), osgl_logfile_hook, NULL, NULL },
2454  {"%g", 1, "bound", Osgl_MV_O(bound), osgl_bound_hook, NULL, NULL },
2455  {"%d", 1, "useBound", Osgl_MV_O(boundFlag), osgl_bound_flag_hook, NULL, NULL },
2456  {"%d", 1, "text_shadow", Osgl_MV_O(text_shadow), dm_generic_hook, NULL, NULL },
2457  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
2458 };
2459 
2460 struct dm_internal dm_osgl = {
2461  osgl_close,
2462  osgl_drawBegin,
2463  osgl_drawEnd,
2464  osgl_normal,
2465  osgl_loadMatrix,
2466  osgl_loadPMatrix,
2467  osgl_drawString2D,
2468  osgl_drawLine2D,
2469  osgl_drawLine3D,
2470  osgl_drawLines3D,
2471  osgl_drawPoint2D,
2472  osgl_drawPoint3D,
2473  osgl_drawPoints3D,
2474  osgl_drawVList,
2475  osgl_drawVListHiddenLine,
2476  osgl_draw,
2477  osgl_setFGColor,
2478  osgl_setBGColor,
2479  osgl_setLineAttr,
2480  osgl_configureWin,
2481  osgl_setWinBounds,
2482  osgl_setLight,
2483  osgl_setTransparency,
2484  osgl_setDepthMask,
2485  osgl_setZBuffer,
2486  osgl_debug,
2487  osgl_logfile,
2488  osgl_beginDList,
2489  osgl_endDList,
2490  osgl_drawDList,
2491  osgl_freeDLists,
2492  osgl_genDLists,
2493  osgl_draw_obj,
2494  osgl_getDisplayImage, /* display to image function */
2495  osgl_reshape,
2496  osgl_makeCurrent,
2497  osgl_openFb,
2498  osgl_get_internal,
2499  osgl_put_internal,
2500  0,
2501  1, /* has displaylist */
2502  0, /* no stereo by default */
2503  1.0, /* zoom-in limit */
2504  1, /* bound flag */
2505  "osgl",
2506  "OpenGL graphics via OpenSceneGraph",
2507  DM_TYPE_OSGL,
2508  1,
2509  0,
2510  0,
2511  0, /* bytes per pixel */
2512  0, /* bits per channel */
2513  0,
2514  0,
2515  1.0, /* aspect ratio */
2516  0,
2517  {0, 0},
2518  NULL,
2519  NULL,
2520  BU_VLS_INIT_ZERO, /* bu_vls path name*/
2521  BU_VLS_INIT_ZERO, /* bu_vls full name drawing window */
2522  BU_VLS_INIT_ZERO, /* bu_vls short name drawing window */
2523  {0, 0, 0}, /* bg color */
2524  {0, 0, 0}, /* fg color */
2525  {GED_MIN, GED_MIN, GED_MIN}, /* clipmin */
2526  {GED_MAX, GED_MAX, GED_MAX}, /* clipmax */
2527  0, /* no debugging */
2528  BU_VLS_INIT_ZERO, /* bu_vls logfile */
2529  0, /* no perspective */
2530  0, /* no lighting */
2531  0, /* no transparency */
2532  1, /* depth buffer is writable */
2533  1, /* zbuffer */
2534  0, /* no zclipping */
2535  0, /* clear back buffer after drawing and swap */
2536  0, /* not overriding the auto font size */
2537  Osgl_vparse,
2538  FB_NULL,
2539  0 /* Tcl interpreter */
2540 };
2541 
2542 
2543 #endif /* DM_OSGL */
2544 
2545 /*
2546  * Local Variables:
2547  * mode: C
2548  * tab-width: 8
2549  * indent-tabs-mode: t
2550  * c-file-style: "stroustrup"
2551  * End:
2552  * ex: shiftwidth=4 tabstop=8
2553  */
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
char filename[MAXLENGTH]
Definition: human.c:105
size_t nused
elements 0..nused active
Definition: vlist.h:73
#define GED_MAX
Definition: ged.h:253
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
struct bu_list l
magic, forw, back
Definition: vlist.h:72
struct bu_list dl_headSolid
head of solid list for this object
Definition: bview.h:49
char * UP
int devbuttonpress
Definition: dm_xvars.h:82
int dm_top
!0 means toplevel window
Definition: dm_private.h:90
int dm_set_light(dm *dmp, int light)
Definition: dm-generic.c:540
void fonsSetFont(FONScontext *s, int font)
int dm_width
Definition: dm_private.h:91
void * pub_vars
Definition: dm_private.h:35
ustring interp
#define DM_DASHED_LINE
Definition: dm.h:109
int dm_zclip
!0 means zclipping
Definition: dm_private.h:116
void * data
Definition: fb.h:176
fb * fbp
Framebuffer associated with this display instance.
Definition: dm_private.h:120
int dm_displaylist
!0 means device has displaylist
Definition: dm_private.h:83
int dm_get_width(dm *dmp)
Definition: dm-generic.c:335
int cmd[BN_VLIST_CHUNK]
VL_CMD_*.
Definition: vlist.h:74
FONScontext * glfonsCreate(int width, int height, int flags)
Tk_Window xtkwin
Definition: dm_xvars.h:65
int dm_gen_dlists(dm *dmp, size_t range)
Definition: dm-generic.c:660
Definition: clone.c:90
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
#define DM_TYPE_OSGL
Definition: dm.h:105
int depth
Definition: dm_xvars.h:66
#define DM_TYPE_WGL
Definition: dm.h:99
vect_t dm_clipmax
maximum clipping vector
Definition: dm_private.h:108
Tcl_Interp * dm_interp
Tcl interpreter.
Definition: dm_private.h:121
unsigned char dm_fg[3]
foreground color
Definition: dm_private.h:106
int dm_processOptions(dm *dmp, struct bu_vls *init_proc_vls, int argc, char **argv)
Definition: options.c:38
int dm_end_dlist(dm *dmp)
Definition: dm-generic.c:679
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
bu_endian_t bu_byteorder(void)
Definition: endian.c:27
int dm_logfile(dm *dmp, const char *filename)
Definition: dm-generic.c:802
Header file for the BRL-CAD common definitions.
int dm_bits_per_channel
Definition: dm_private.h:94
int dm_light
!0 means lighting on
Definition: dm_private.h:112
ustring width
fastf_t dm_aspect
Definition: dm_private.h:97
#define HIDDEN
Definition: common.h:86
struct fb_platform_specific * fb_get_platform_specific(uint32_t magic)
Definition: fb_generic.c:113
const char * bu_brlcad_data(const char *rhs, int fail_quietly)
Definition: brlcad_path.c:405
#define BN_VLIST_POLY_MOVE
move to first poly vertex
Definition: vlist.h:85
int dm_clearBufferAfter
1 means clear back buffer after drawing and swap
Definition: dm_private.h:117
#define BN_VLIST_TRI_VERTNORM
per-vertex normal, for interpolation
Definition: vlist.h:93
struct bu_vls dm_tkName
short Tcl/Tk name of drawing window
Definition: dm_private.h:103
int dm_begin_dlist(dm *dmp, unsigned int list)
Definition: dm-generic.c:667
if(share_geom)
Definition: nmg_mod.c:3829
fastf_t * dm_vp
(FIXME: ogl still depends on this) Viewscale pointer
Definition: dm_private.h:98
void fonsSetSize(FONScontext *s, float size)
int dm_bytes_per_pixel
Definition: dm_private.h:93
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
Definition: color.c:49
COMPLEX data[64]
Definition: fftest.c:34
#define DM_NULL
Definition: dm.h:43
float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
int drawLine2D(struct dm_internal *dmp, fastf_t X1, fastf_t Y1, fastf_t X2, fastf_t Y2, const char *log_bu)
#define FB_NULL
Definition: fb.h:95
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
int dm_perspective
!0 means perspective on
Definition: dm_private.h:111
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
unsigned long dm_id
window id
Definition: dm_private.h:82
struct bu_vls dm_log
!NULL && !empty means log debug output to the file
Definition: dm_private.h:110
void bu_vls_sprintf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:707
#define BN_VLIST_POLY_START
pt[] has surface normal
Definition: vlist.h:84
int devmotionnotify
Definition: dm_xvars.h:81
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
#define V3ARGS(a)
Definition: color.c:56
int dm_set_fg(dm *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency)
Definition: dm-generic.c:441
struct bu_vls dm_dName
Display name.
Definition: dm_private.h:104
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
Tk_Window top
Definition: dm_xvars.h:64
Coord * point
Definition: chull3d.cpp:52
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
int fonsAddFont(FONScontext *s, const char *name, const char *path)
int devbuttonrelease
Definition: dm_xvars.h:83
#define UNUSED(parameter)
Definition: common.h:239
#define BN_VLIST_POLY_DRAW
subsequent poly vertex
Definition: vlist.h:86
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
#define GED_MIN
Definition: ged.h:254
void(* dm_get_internal)(struct dm_internal *dmp)
Definition: dm_private.h:80
int dm_get_height(dm *dmp)
Definition: dm-generic.c:342
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define BN_VLIST_TRI_END
last vert (repeats 1st), draw poly
Definition: vlist.h:92
int dm_make_current(dm *dmp)
Definition: dm-generic.c:448
Display * dpy
Definition: dm_xvars.h:62
int dm_lineWidth
Definition: dm_private.h:95
int dm_debug(dm *dmp, int lvl)
Definition: dm-generic.c:796
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
ustring alpha
int drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int sflag, const char *log_bu, float *wireColor)
void * Tk_Window
Definition: dm_xvars.h:44
Window win
Definition: dm_xvars.h:63
#define BN_VLIST_TRI_START
pt[] has surface normal
Definition: vlist.h:89
fb * fb_open_existing(const char *file, int _width, int _height, struct fb_platform_specific *fb_p)
Definition: fb_generic.c:146
#define BN_VLIST_POINT_SIZE
specify point pixel size
Definition: vlist.h:95
int dm_get_fontsize(dm *dmp)
Definition: dm-generic.c:385
int drawLine3D(struct dm_internal *dmp, point_t pt1, point_t pt2, const char *log_bu, float *wireColor)
void * priv_vars
Definition: dm_private.h:36
vect_t dm_clipmin
minimum clipping vector
Definition: dm_private.h:107
void dm_fogHint(dm *dmp, int fastfog)
Definition: dm-generic.c:243
Definition: vlist.h:71
struct dm_vars dm_vars
display manager dependent variables
Definition: dm_private.h:99
int dm_height
Definition: dm_private.h:92
int dm_zbuffer
!0 means zbuffer on
Definition: dm_private.h:115
#define BN_VLIST_POLY_VERTNORM
per-vertex normal, for interpolation
Definition: vlist.h:88
int dm_set_win_bounds(dm *dmp, fastf_t *w)
Definition: dm-generic.c:484
void fonsSetColor(FONScontext *s, unsigned int color)
#define BN_VLIST_POLY_END
last vert (repeats 1st), draw poly
Definition: vlist.h:87
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
struct bu_vls dm_pathName
full Tcl/Tk name of drawing window
Definition: dm_private.h:102
#define FONS_INVALID
Definition: fontstash.h:25
#define BN_VLIST_TRI_DRAW
subsequent triangle vertex
Definition: vlist.h:91
double dm_bound
zoom-in limit
Definition: dm_private.h:85
dm dm_osgl
unsigned char dm_bg[3]
background color
Definition: dm_private.h:105
Definition: color.c:51
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
void dm_generic_hook(const struct bu_structparse *sdp, const char *name, void *base, const char *value, void *data)
Definition: dm-generic.c:831
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int dm_transparency
!0 means transparency on
Definition: dm_private.h:113
Definition: human.c:197
void * m_vars
Definition: dm_private.h:100
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int dm_boundFlag
Definition: dm_private.h:86
point_t pt[BN_VLIST_CHUNK]
associated 3-point/vect
Definition: vlist.h:75
#define FB_OSGL_MAGIC
Definition: magic.h:192
#define BN_VLIST_LINE_WIDTH
specify line pixel width
Definition: vlist.h:96
int dm_debugLevel
!0 means debugging
Definition: dm_private.h:109
int dm_type
display manager type
Definition: dm_private.h:89
Definition: vls.h:56
HIDDEN const point_t delta
Definition: sh_prj.c:618
#define LINE
Definition: gqa.c:390
double fastf_t
Definition: defines.h:300
int dm_draw_vlist(dm *dmp, struct bn_vlist *vp)
Definition: dm-generic.c:692
int dm_lineStyle
Definition: dm_private.h:96
int dm_set_zbuffer(dm *dmp, int zbuffer)
Definition: dm-generic.c:582
Definition: color.c:50
void fb_put_platform_specific(struct fb_platform_specific *fb_p)
Definition: fb_generic.c:129
int dm_depthMask
!0 means depth buffer is writable
Definition: dm_private.h:114
int dm_set_transparency(dm *dmp, int transparency)
Definition: dm-generic.c:568
#define BN_VLIST_POINT_DRAW
Draw a single point.
Definition: vlist.h:94
#define BN_VLIST_TRI_MOVE
move to first triangle vertex
Definition: vlist.h:90