BRL-CAD
dm-ogl.c
Go to the documentation of this file.
1 /* D M - O G L . C
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-ogl.c
21  *
22  * An X11 OpenGL Display Manager.
23  *
24  */
25 
26 #include "common.h"
27 
28 #ifdef DM_OGL
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <math.h>
33 #include <string.h>
34 
35 #ifdef HAVE_X11_XOSDEFS_H
36 # include <X11/Xfuncproto.h>
37 # include <X11/Xosdefs.h>
38 #endif
39 #ifdef linux
40 # undef X_NOT_STDC_ENV
41 # undef X_NOT_POSIX
42 #endif
43 
44 #include <X11/extensions/XInput.h>
45 
46 /* glx.h on Mac OS X (and perhaps elsewhere) defines a slew of
47  * parameter names that shadow system symbols. protect the system
48  * symbols by redefining the parameters prior to header inclusion.
49  */
50 #define j1 J1
51 #define y1 Y1
52 #define read rd
53 #define index idx
54 #define access acs
55 #define remainder rem
56 #ifdef HAVE_GL_GLX_H
57 # include <GL/glx.h>
58 #endif
59 #ifdef HAVE_GL_GL_H
60 # include <GL/gl.h>
61 #endif
62 #undef remainder
63 #undef access
64 #undef index
65 #undef read
66 #undef y1
67 #undef j1
68 
69 #include "tk.h"
70 
71 #undef VMIN /* is used in vmath.h, too */
72 
73 #include "vmath.h"
74 #include "bn.h"
75 #include "raytrace.h"
76 #include "dm.h"
77 #include "dm-ogl.h"
78 #include "dm-Null.h"
79 #include "dm/dm_xvars.h"
80 #include "fb.h"
81 #include "fb/fb_ogl.h"
82 #include "solid.h"
83 
84 #include "./dm_private.h"
85 
86 #define VIEWFACTOR (1.0/(*dmp->dm_vp))
87 #define VIEWSIZE (2.0*(*dmp->dm_vp))
88 
89 /* these are from /usr/include/gl.h could be device dependent */
90 #define XMAXSCREEN 1279
91 #define YMAXSCREEN 1023
92 #define YSTEREO 491 /* subfield height, in scanlines */
93 #define YOFFSET_LEFT 532 /* YSTEREO + YBLANK ? */
94 
95 #define Ogl_MV_O(_m) offsetof(struct modifiable_ogl_vars, _m)
96 
97 struct modifiable_ogl_vars {
98  dm *this_dm;
99  int cueing_on;
100  int zclipping_on;
101  int zbuffer_on;
102  int lighting_on;
103  int transparency_on;
104  int fastfog;
105  double fogdensity;
106  int zbuf;
107  int rgb;
108  int doublebuffer;
109  int depth;
110  int debug;
111  struct bu_vls log;
112  double bound;
113  int boundFlag;
114 };
115 
116 
117 HIDDEN XVisualInfo *ogl_choose_visual(struct dm_internal *dmp, Tk_Window tkwin);
118 
119 /* Display Manager package interface */
120 #define IRBOUND 4095.9 /* Max magnification in Rot matrix */
121 #define PLOTBOUND 1000.0 /* Max magnification in Rot matrix */
122 
123 struct dm_internal *ogl_open(Tcl_Interp *interp, int argc, char **argv);
124 HIDDEN int ogl_close(struct dm_internal *dmp);
125 HIDDEN int ogl_drawBegin(struct dm_internal *dmp);
126 HIDDEN int ogl_drawEnd(struct dm_internal *dmp);
127 HIDDEN int ogl_normal(struct dm_internal *dmp);
128 HIDDEN int ogl_loadMatrix(struct dm_internal *dmp, fastf_t *mat, int which_eye);
129 HIDDEN int ogl_loadPMatrix(struct dm_internal *dmp, fastf_t *mat);
130 HIDDEN int ogl_drawString2D(struct dm_internal *dmp, const char *str, fastf_t x, fastf_t y, int size, int use_aspect);
131 HIDDEN int ogl_drawLine2D(struct dm_internal *dmp, fastf_t X1, fastf_t Y1, fastf_t X2, fastf_t Y2);
132 HIDDEN int ogl_drawLine3D(struct dm_internal *dmp, point_t pt1, point_t pt2);
133 HIDDEN int ogl_drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int sflag);
134 HIDDEN int ogl_drawPoint2D(struct dm_internal *dmp, fastf_t x, fastf_t y);
135 HIDDEN int ogl_drawPoint3D(struct dm_internal *dmp, point_t point);
136 HIDDEN int ogl_drawPoints3D(struct dm_internal *dmp, int npoints, point_t *points);
137 HIDDEN int ogl_drawVList(struct dm_internal *dmp, register struct bn_vlist *vp);
138 HIDDEN int ogl_drawVListHiddenLine(struct dm_internal *dmp, register struct bn_vlist *vp);
139 HIDDEN int ogl_draw(struct dm_internal *dmp, struct bn_vlist *(*callback_function)(void *), void **data);
140 HIDDEN int ogl_setFGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency);
141 HIDDEN int ogl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b);
142 HIDDEN int ogl_setLineAttr(struct dm_internal *dmp, int width, int style);
143 HIDDEN int ogl_configureWin_guts(struct dm_internal *dmp, int force);
144 HIDDEN int ogl_configureWin(struct dm_internal *dmp, int force);
145 HIDDEN int ogl_setLight(struct dm_internal *dmp, int lighting_on);
146 HIDDEN int ogl_setTransparency(struct dm_internal *dmp, int transparency_on);
147 HIDDEN int ogl_setDepthMask(struct dm_internal *dmp, int depthMask_on);
148 HIDDEN int ogl_setZBuffer(struct dm_internal *dmp, int zbuffer_on);
149 HIDDEN int ogl_setWinBounds(struct dm_internal *dmp, fastf_t *w);
150 HIDDEN int ogl_debug(struct dm_internal *dmp, int vl);
151 HIDDEN int ogl_logfile(struct dm_internal *dmp, const char *filename);
152 HIDDEN int ogl_beginDList(struct dm_internal *dmp, unsigned int list);
153 HIDDEN int ogl_endDList(struct dm_internal *dmp);
154 HIDDEN void ogl_drawDList(unsigned int list);
155 HIDDEN int ogl_freeDLists(struct dm_internal *dmp, unsigned int list, int range);
156 HIDDEN int ogl_genDLists(struct dm_internal *dmp, size_t range);
157 HIDDEN int ogl_getDisplayImage(struct dm_internal *dmp, unsigned char **image);
158 HIDDEN void ogl_reshape(struct dm_internal *dmp, int width, int height);
159 HIDDEN int ogl_makeCurrent(struct dm_internal *dmp);
160 
161 
162 static fastf_t default_viewscale = 1000.0;
163 static double xlim_view = 1.0; /* args for glOrtho*/
164 static double ylim_view = 1.0;
165 
166 /* lighting parameters */
167 static float amb_three[] = {0.3, 0.3, 0.3, 1.0};
168 
169 static float light0_position[] = {0.0, 0.0, 1.0, 0.0};
170 static float light0_diffuse[] = {1.0, 1.0, 1.0, 1.0}; /* white */
171 static float wireColor[4];
172 static float ambientColor[4];
173 static float specularColor[4];
174 static float diffuseColor[4];
175 static float backDiffuseColorDark[4];
176 static float backDiffuseColorLight[4];
177 
178 HIDDEN void
179 ogl_printmat(struct bu_vls *tmp_vls, fastf_t *mat) {
180  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[0], mat[4], mat[8], mat[12]);
181  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[1], mat[5], mat[9], mat[13]);
182  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[2], mat[6], mat[10], mat[14]);
183  bu_vls_printf(tmp_vls, "%g %g %g %g\n", mat[3], mat[7], mat[11], mat[15]);
184 }
185 
186 HIDDEN void
187 ogl_printglmat(struct bu_vls *tmp_vls, GLfloat *m) {
188  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[0], m[4], m[8], m[12]);
189  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[1], m[5], m[9], m[13]);
190  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[2], m[6], m[10], m[14]);
191  bu_vls_printf(tmp_vls, "%g %g %g %g\n", m[3], m[7], m[11], m[15]);
192 }
193 
194 
195 void
196 ogl_fogHint(struct dm_internal *dmp, int fastfog)
197 {
198  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
199  mvars->fastfog = fastfog;
200  glHint(GL_FOG_HINT, fastfog ? GL_FASTEST : GL_NICEST);
201 }
202 
203 
204 HIDDEN int
205 ogl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b)
206 {
207  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
208  if (dmp->dm_debugLevel == 1)
209  bu_log("ogl_setBGColor()\n");
210 
211  dmp->dm_bg[0] = r;
212  dmp->dm_bg[1] = g;
213  dmp->dm_bg[2] = b;
214 
215  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->r = r / 255.0;
216  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g = g / 255.0;
217  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b = b / 255.0;
218 
219  if (mvars->doublebuffer) {
220  glXSwapBuffers(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
221  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win);
222  glClearColor(((struct ogl_vars *)dmp->dm_vars.priv_vars)->r,
223  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g,
224  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b,
225  0.0);
226  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
227  }
228 
229  return TCL_OK;
230 }
231 
232 
233 /*
234  * Either initially, or on resize/reshape of the window,
235  * sense the actual size of the window, and perform any
236  * other initializations of the window configuration.
237  *
238  * also change font size if necessary
239  */
240 HIDDEN int
241 ogl_configureWin_guts(struct dm_internal *dmp, int force)
242 {
243  XWindowAttributes xwa;
244  XFontStruct *newfontstruct;
245 
246  if (dmp->dm_debugLevel)
247  bu_log("ogl_configureWin_guts()\n");
248 
249  XGetWindowAttributes(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
250  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win, &xwa);
251 
252  /* nothing to do */
253  if (!force &&
254  dmp->dm_height == xwa.height &&
255  dmp->dm_width == xwa.width)
256  return TCL_OK;
257 
258  ogl_reshape(dmp, xwa.width, xwa.height);
259 
260  /* First time through, load a font or quit */
261  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct == NULL) {
262  if ((((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct =
263  XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
264  FONT9)) == NULL) {
265  /* Try hardcoded backup font */
266  if ((((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct =
267  XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
268  FONTBACK)) == NULL) {
269  bu_log("ogl_configureWin_guts: Can't open font '%s' or '%s'\n", FONT9, FONTBACK);
270  return TCL_ERROR;
271  }
272  }
273  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
274  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
275  }
276 
277  if (DM_VALID_FONT_SIZE(dmp->dm_fontsize)) {
278  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != dmp->dm_fontsize) {
279  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
280  DM_FONT_SIZE_TO_NAME(dmp->dm_fontsize))) != NULL) {
281  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
282  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
283  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
284  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
285  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
286  }
287  }
288  } else {
289  /* Always try to choose a the font that best fits the window size.
290  */
291 
292  if (dmp->dm_width < 582) {
293  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 5) {
294  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
295  FONT5)) != NULL) {
296  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
297  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
298  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
299  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
300  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
301  }
302  }
303  } else if (dmp->dm_width < 679) {
304  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 6) {
305  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
306  FONT6)) != NULL) {
307  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
308  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
309  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
310  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
311  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
312  }
313  }
314  } else if (dmp->dm_width < 776) {
315  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 7) {
316  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
317  FONT7)) != NULL) {
318  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
319  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
320  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
321  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
322  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
323  }
324  }
325  } else if (dmp->dm_width < 873) {
326  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 8) {
327  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
328  FONT8)) != NULL) {
329  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
330  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
331  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
332  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
333  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
334  }
335  }
336  } else if (dmp->dm_width < 1455) {
337  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 9) {
338  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
339  FONT9)) != NULL) {
340  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
341  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
342  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
343  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
344  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
345  }
346  }
347  } else if (dmp->dm_width < 2037) {
348  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 10) {
349  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
350  FONT10)) != NULL) {
351  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
352  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
353  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
354  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
355  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
356  }
357  }
358  } else {
359  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->per_char->width != 12) {
360  if ((newfontstruct = XLoadQueryFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
361  FONT12)) != NULL) {
362  XFreeFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
363  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct);
364  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = newfontstruct;
365  glXUseXFont(((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct->fid,
366  0, 127, ((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
367  }
368  }
369  }
370  }
371 
372  return TCL_OK;
373 }
374 
375 
376 HIDDEN void
377 ogl_reshape(struct dm_internal *dmp, int width, int height)
378 {
379  GLint mm;
380 
381  dmp->dm_height = height;
382  dmp->dm_width = width;
383  dmp->dm_aspect = (fastf_t)dmp->dm_width / (fastf_t)dmp->dm_height;
384 
385  if (dmp->dm_debugLevel) {
386  GLfloat m[16];
387  bu_log("ogl_reshape()\n");
388  bu_log("width = %d, height = %d\n", dmp->dm_width, dmp->dm_height);
389  glGetFloatv (GL_MODELVIEW_MATRIX, m);
390  glGetFloatv (GL_PROJECTION_MATRIX, m);
391  }
392 
393  glViewport(0, 0, dmp->dm_width, dmp->dm_height);
394 
395  glClearColor(((struct ogl_vars *)dmp->dm_vars.priv_vars)->r,
396  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g,
397  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b,
398  0.0);
399  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
400 
401  glGetIntegerv(GL_MATRIX_MODE, &mm);
402  glMatrixMode(GL_PROJECTION);
403  glLoadIdentity();
404  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
405  glMatrixMode(mm);
406 }
407 
408 
409 HIDDEN int
410 ogl_makeCurrent(struct dm_internal *dmp)
411 {
412  if (dmp->dm_debugLevel)
413  bu_log("ogl_makeCurrent()\n");
414 
415  if (!glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
416  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
417  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc)) {
418  bu_log("ogl_makeCurrent: Couldn't make context current\n");
419  return TCL_ERROR;
420  }
421 
422  return TCL_OK;
423 }
424 
425 
426 HIDDEN int
427 ogl_configureWin(struct dm_internal *dmp, int force)
428 {
429  if (!glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
430  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
431  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc)) {
432  bu_log("ogl_configureWin: Couldn't make context current\n");
433  return TCL_ERROR;
434  }
435 
436  return ogl_configureWin_guts(dmp, force);
437 }
438 
439 
440 HIDDEN int
441 ogl_setLight(struct dm_internal *dmp, int lighting_on)
442 {
443  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
444  if (dmp->dm_debugLevel)
445  bu_log("ogl_setLight()\n");
446 
447  dmp->dm_light = lighting_on;
448  mvars->lighting_on = dmp->dm_light;
449 
450  if (!dmp->dm_light) {
451  /* Turn it off */
452  glDisable(GL_LIGHTING);
453  } else {
454  /* Turn it on */
455 
456  if (1 < dmp->dm_light)
457  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
458  else
459  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
460 
461  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb_three);
462  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
463 
464  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
465  glLightfv(GL_LIGHT0, GL_SPECULAR, light0_diffuse);
466 
467  glEnable(GL_LIGHTING);
468  glEnable(GL_LIGHT0);
469  }
470 
471  return TCL_OK;
472 }
473 
474 
475 /**
476  * currently, get a double buffered rgba visual that works with Tk and
477  * OpenGL
478  */
479 HIDDEN XVisualInfo *
480 ogl_choose_visual(struct dm_internal *dmp, Tk_Window tkwin)
481 {
482  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
483  XVisualInfo *vip, vitemp, *vibase, *maxvip;
484  int tries, baddepth;
485  int num, i, j;
486  int fail;
487  int *good = NULL;
488 
489  /* requirements */
490  int screen;
491  int use;
492  int rgba;
493  int dbfr;
494 
495  /* desires */
496  int m_zbuffer = 1; /* m_zbuffer - try to get zbuffer */
497  int zbuffer;
498 
499  int m_stereo; /* m_stereo - try to get stereo */
500  int stereo;
501 
502  if (dmp->dm_stereo) {
503  m_stereo = 1;
504  } else {
505  m_stereo = 0;
506  }
507 
508  memset((void *)&vitemp, 0, sizeof(XVisualInfo));
509  /* Try to satisfy the above desires with a color visual of the
510  * greatest depth */
511 
512  vibase = XGetVisualInfo(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
513  0, &vitemp, &num);
514  screen = DefaultScreen(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy);
515 
516  good = (int *)bu_malloc(sizeof(int)*num, "alloc good visuals");
517 
518  while (1) {
519  for (i=0, j=0, vip=vibase; i<num; i++, vip++) {
520  /* requirements */
521  if (vip->screen != screen)
522  continue;
523 
524  fail = glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
525  vip, GLX_USE_GL, &use);
526  if (fail || !use)
527  continue;
528 
529  fail = glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
530  vip, GLX_RGBA, &rgba);
531  if (fail || !rgba)
532  continue;
533 
534  fail = glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
535  vip, GLX_DOUBLEBUFFER, &dbfr);
536  if (fail || !dbfr)
537  continue;
538 
539  /* desires */
540  if (m_zbuffer) {
541  fail = glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
542  vip, GLX_DEPTH_SIZE, &zbuffer);
543  if (fail || !zbuffer)
544  continue;
545  }
546 
547  if (m_stereo) {
548  fail = glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
549  vip, GLX_STEREO, &stereo);
550  if (fail || !stereo) {
551  bu_log("ogl_choose_visual: failed visual - GLX_STEREO\n");
552  continue;
553  }
554  }
555 
556  /* this visual meets criteria */
557  good[j++] = i;
558  }
559 
560  /* j = number of acceptable visuals under consideration */
561  if (j >= 1) {
562  baddepth = 1000;
563  for (tries = 0; tries < j; ++tries) {
564  maxvip = vibase + good[0];
565  for (i=1; i<j; i++) {
566  vip = vibase + good[i];
567  if ((vip->depth > maxvip->depth)&&(vip->depth < baddepth)) {
568  maxvip = vip;
569  }
570  }
571 
572  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap =
573  XCreateColormap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
574  RootWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
575  maxvip->screen), maxvip->visual, AllocNone);
576 
577  if (Tk_SetWindowVisual(tkwin,
578  maxvip->visual, maxvip->depth,
579  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap)) {
580 
581  glXGetConfig(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
582  maxvip, GLX_DEPTH_SIZE,
583  &mvars->depth);
584  if (mvars->depth > 0)
585  mvars->zbuf = 1;
586 
587  bu_free(good, "dealloc good visuals");
588  return maxvip; /* success */
589  } else {
590  /* retry with lesser depth */
591  baddepth = maxvip->depth;
592  XFreeColormap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
593  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap);
594  }
595  }
596  }
597 
598  /* if no success at this point, relax a desire and try again */
599 
600  if (m_stereo) {
601  m_stereo = 0;
602  bu_log("Stereo not available.\n");
603  continue;
604  }
605 
606  if (m_zbuffer) {
607  m_zbuffer = 0;
608  continue;
609  }
610 
611  /* ran out of visuals, give up */
612  break;
613  }
614 
615  bu_free(good, "dealloc good visuals");
616  return (XVisualInfo *)NULL; /* failure */
617 }
618 
619 
620 /*
621  * Gracefully release the display.
622  */
623 HIDDEN int
624 ogl_close(struct dm_internal *dmp)
625 {
626  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy) {
627  if (((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc) {
628  glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy, None, NULL);
629  glXDestroyContext(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
630  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc);
631  }
632 
633  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap)
634  XFreeColormap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
635  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap);
636 
637  if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin)
638  Tk_DestroyWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
639  }
640 
641  bu_vls_free(&dmp->dm_pathName);
642  bu_vls_free(&dmp->dm_tkName);
643  bu_vls_free(&dmp->dm_dName);
644  bu_free(dmp->dm_vars.priv_vars, "ogl_close: ogl_vars");
645  bu_free(dmp->dm_vars.pub_vars, "ogl_close: dm_xvars");
646  bu_free(dmp, "ogl_close: dmp");
647 
648  return TCL_OK;
649 }
650 
651 
652 /*
653  * Fire up the display manager, and the display processor.
654  *
655  */
656 struct dm_internal *
657 ogl_open(Tcl_Interp *interp, int argc, char **argv)
658 {
659  static int count = 0;
660  GLfloat backgnd[4];
661  int j, k;
662  int make_square = -1;
663  int ndevices;
664  int nclass = 0;
665  int unused;
666  XDeviceInfoPtr olist = NULL, list = NULL;
667  XDevice *dev = NULL;
668  XEventClass e_class[15];
669  XInputClassInfo *cip;
670  struct bu_vls str = BU_VLS_INIT_ZERO;
671  struct bu_vls init_proc_vls = BU_VLS_INIT_ZERO;
672  Display *tmp_dpy = (Display *)NULL;
673  struct dm_internal *dmp = (struct dm_internal *)NULL;
674  struct modifiable_ogl_vars *mvars = NULL;
675  Tk_Window tkwin = (Tk_Window)NULL;
676  int screen_number = -1;
677 
678  struct dm_xvars *pubvars = NULL;
679  struct ogl_vars *privvars = NULL;
680 
681  if ((tkwin = Tk_MainWindow(interp)) == NULL) {
682  return DM_NULL;
683  }
684 
685  BU_GET(dmp, struct dm_internal);
686 
687  *dmp = dm_ogl; /* struct copy */
688  dmp->dm_interp = interp;
689  dmp->dm_lineWidth = 1;
690  dmp->dm_light = 1;
691  dmp->dm_bytes_per_pixel = sizeof(GLuint);
692  dmp->dm_bits_per_channel = 8;
693  bu_vls_init(&(dmp->dm_log));
694 
695  BU_ALLOC(dmp->dm_vars.pub_vars, struct dm_xvars);
696  if (dmp->dm_vars.pub_vars == (void *)NULL) {
697  bu_free(dmp, "ogl_open: dmp");
698  return DM_NULL;
699  }
700  pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
701 
702  BU_ALLOC(dmp->dm_vars.priv_vars, struct ogl_vars);
703  if (dmp->dm_vars.priv_vars == (void *)NULL) {
704  bu_free(dmp->dm_vars.pub_vars, "ogl_open: dmp->dm_vars.pub_vars");
705  bu_free(dmp, "ogl_open: dmp");
706  return DM_NULL;
707  }
708  privvars = (struct ogl_vars *)dmp->dm_vars.priv_vars;
709 
710  dmp->dm_get_internal(dmp);
711  mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
712 
713  dmp->dm_vp = &default_viewscale;
714 
715  bu_vls_init(&dmp->dm_pathName);
716  bu_vls_init(&dmp->dm_tkName);
717  bu_vls_init(&dmp->dm_dName);
718 
719  dm_processOptions(dmp, &init_proc_vls, --argc, ++argv);
720 
721  if (bu_vls_strlen(&dmp->dm_pathName) == 0)
722  bu_vls_printf(&dmp->dm_pathName, ".dm_ogl%d", count);
723  ++count;
724  if (bu_vls_strlen(&dmp->dm_dName) == 0) {
725  char *dp;
726 
727  dp = getenv("DISPLAY");
728  if (dp)
729  bu_vls_strcpy(&dmp->dm_dName, dp);
730  else
731  bu_vls_strcpy(&dmp->dm_dName, ":0.0");
732  }
733  if (bu_vls_strlen(&init_proc_vls) == 0)
734  bu_vls_strcpy(&init_proc_vls, "bind_dm");
735 
736  /* initialize dm specific variables */
737  pubvars->devmotionnotify = LASTEvent;
738  pubvars->devbuttonpress = LASTEvent;
739  pubvars->devbuttonrelease = LASTEvent;
740  dmp->dm_aspect = 1.0;
741 
742  /* initialize modifiable variables */
743  mvars->rgb = 1;
744  mvars->doublebuffer = 1;
745  mvars->fastfog = 1;
746  mvars->fogdensity = 1.0;
747  mvars->lighting_on = dmp->dm_light;
748  mvars->zbuffer_on = dmp->dm_zbuffer;
749  mvars->zclipping_on = dmp->dm_zclip;
750  mvars->debug = dmp->dm_debugLevel;
751  mvars->bound = dmp->dm_bound;
752  mvars->boundFlag = dmp->dm_boundFlag;
753 
754  /* this is important so that ogl_configureWin knows to set the font */
755  pubvars->fontstruct = NULL;
756 
757  if ((tmp_dpy = XOpenDisplay(bu_vls_addr(&dmp->dm_dName))) == NULL) {
758  bu_vls_free(&init_proc_vls);
759  (void)ogl_close(dmp);
760  return DM_NULL;
761  }
762 
763 #ifdef HAVE_XQUERYEXTENSION
764  {
765  int return_val;
766 
767  if (!XQueryExtension(tmp_dpy, "GLX", &return_val, &return_val, &return_val)) {
768  bu_vls_free(&init_proc_vls);
769  (void)ogl_close(dmp);
770  return DM_NULL;
771  }
772  }
773 #endif
774 
775  screen_number = XDefaultScreen(tmp_dpy);
776  if (screen_number < 0)
777  bu_log("WARNING: screen number is [%d]\n", screen_number);
778 
779  if (dmp->dm_width == 0) {
780  dmp->dm_width = XDisplayWidth(tmp_dpy, screen_number) - 30;
781  ++make_square;
782  }
783  if (dmp->dm_height == 0) {
784  dmp->dm_height = XDisplayHeight(tmp_dpy, screen_number) - 30;
785  ++make_square;
786  }
787 
788  if (make_square > 0) {
789  /* Make window square */
790  if (dmp->dm_height <
791  dmp->dm_width)
792  dmp->dm_width =
793  dmp->dm_height;
794  else
795  dmp->dm_height =
796  dmp->dm_width;
797  }
798 
799  XCloseDisplay(tmp_dpy);
800 
801  if (dmp->dm_top) {
802  /* Make xtkwin a toplevel window */
803  pubvars->xtkwin =
804  Tk_CreateWindowFromPath(interp,
805  tkwin,
806  bu_vls_addr(&dmp->dm_pathName),
807  bu_vls_addr(&dmp->dm_dName));
808  pubvars->top = pubvars->xtkwin;
809  } else {
810  char *cp;
811 
812  cp = strrchr(bu_vls_addr(&dmp->dm_pathName), (int)'.');
813  if (cp == bu_vls_addr(&dmp->dm_pathName)) {
814  pubvars->top = tkwin;
815  } else {
816  struct bu_vls top_vls = BU_VLS_INIT_ZERO;
817 
818  bu_vls_strncpy(&top_vls, (const char *)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
819 
820  pubvars->top =
821  Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
822  bu_vls_free(&top_vls);
823  }
824 
825  /* Make xtkwin an embedded window */
826  pubvars->xtkwin =
827  Tk_CreateWindow(interp, pubvars->top,
828  cp + 1, (char *)NULL);
829  }
830 
831  if (pubvars->xtkwin == NULL) {
832  bu_log("dm-Ogl: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
833  bu_vls_free(&init_proc_vls);
834  (void)ogl_close(dmp);
835  return DM_NULL;
836  }
837 
838  bu_vls_printf(&dmp->dm_tkName, "%s",
839  (char *)Tk_Name(pubvars->xtkwin));
840 
841  bu_vls_printf(&str, "_init_dm %s %s\n",
842  bu_vls_addr(&init_proc_vls),
843  bu_vls_addr(&dmp->dm_pathName));
844 
845  if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
846  bu_vls_free(&init_proc_vls);
847  bu_vls_free(&str);
848  (void)ogl_close(dmp);
849  return DM_NULL;
850  }
851 
852  bu_vls_free(&init_proc_vls);
853  bu_vls_free(&str);
854 
855  pubvars->dpy =
856  Tk_Display(pubvars->top);
857 
858  /* make sure there really is a display before proceeding. */
859  if (!(pubvars->dpy)) {
860  bu_vls_free(&init_proc_vls);
861  bu_vls_free(&str);
862  (void)ogl_close(dmp);
863  return DM_NULL;
864  }
865 
866  Tk_GeometryRequest(pubvars->xtkwin,
867  dmp->dm_width,
868  dmp->dm_height);
869 
870  /* must do this before MakeExist */
871  if ((pubvars->vip=ogl_choose_visual(dmp, pubvars->xtkwin)) == NULL) {
872  bu_log("ogl_open: Can't get an appropriate visual.\n");
873  (void)ogl_close(dmp);
874  return DM_NULL;
875  }
876 
877  pubvars->depth = mvars->depth;
878 
879  Tk_MakeWindowExist(pubvars->xtkwin);
880 
881  pubvars->win = Tk_WindowId(pubvars->xtkwin);
882  dmp->dm_id = pubvars->win;
883 
884  /* open GLX context */
885  if ((privvars->glxc =
886  glXCreateContext(pubvars->dpy, pubvars->vip, (GLXContext)NULL, GL_TRUE))==NULL) {
887  bu_log("ogl_open: couldn't create glXContext.\n");
888  (void)ogl_close(dmp);
889  return DM_NULL;
890  }
891 
892  /* If we used an indirect context, then as far as sgi is concerned,
893  * gl hasn't been used.
894  */
895  privvars->is_direct = (char) glXIsDirect(pubvars->dpy, privvars->glxc);
896 
897  /*
898  * Take a look at the available input devices. We're looking
899  * for "dial+buttons".
900  */
901  if (XQueryExtension(pubvars->dpy, "XInputExtension", &unused, &unused, &unused)) {
902  olist = list = (XDeviceInfoPtr)XListInputDevices(pubvars->dpy, &ndevices);
903  }
904 
905  if (list == (XDeviceInfoPtr)NULL ||
906  list == (XDeviceInfoPtr)1) goto Done;
907 
908  for (j = 0; j < ndevices; ++j, list++) {
909  if (list->use == IsXExtensionDevice) {
910  if (BU_STR_EQUAL(list->name, "dial+buttons")) {
911  if ((dev = XOpenDevice(pubvars->dpy,
912  list->id)) == (XDevice *)NULL) {
913  bu_log("ogl_open: Couldn't open the dials+buttons\n");
914  goto Done;
915  }
916 
917  for (cip = dev->classes, k = 0; k < dev->num_classes;
918  ++k, ++cip) {
919  switch (cip->input_class) {
920 #ifdef IR_BUTTONS
921  case ButtonClass:
922  DeviceButtonPress(dev, pubvars->devbuttonpress,
923  e_class[nclass]);
924  ++nclass;
925  DeviceButtonRelease(dev, pubvars->devbuttonrelease,
926  e_class[nclass]);
927  ++nclass;
928  break;
929 #endif
930 #ifdef IR_KNOBS
931  case ValuatorClass:
932  DeviceMotionNotify(dev, pubvars->devmotionnotify,
933  e_class[nclass]);
934  ++nclass;
935  break;
936 #endif
937  default:
938  break;
939  }
940  }
941 
942  XSelectExtensionEvent(pubvars->dpy, pubvars->win, e_class, nclass);
943  goto Done;
944  }
945  }
946  }
947 Done:
948  XFreeDeviceList(olist);
949 
950  Tk_MapWindow(pubvars->xtkwin);
951 
952  if (!glXMakeCurrent(pubvars->dpy, pubvars->win, privvars->glxc)) {
953  bu_log("ogl_open: Couldn't make context current\n");
954  (void)ogl_close(dmp);
955  return DM_NULL;
956  }
957 
958  /* display list (fontOffset + char) will display a given ASCII char */
959  if ((privvars->fontOffset = glGenLists(128))==0) {
960  bu_log("dm-ogl: Can't make display lists for font.\n");
961  (void)ogl_close(dmp);
962  return DM_NULL;
963  }
964 
965  /* This is the applications display list offset */
966  dmp->dm_displaylist = privvars->fontOffset + 128;
967 
968  ogl_setBGColor(dmp, 0, 0, 0);
969  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
970 
971  if (mvars->doublebuffer)
972  glDrawBuffer(GL_BACK);
973  else
974  glDrawBuffer(GL_FRONT);
975 
976  /* do viewport, ortho commands and initialize font */
977  (void)ogl_configureWin_guts(dmp, 1);
978 
979  /* Lines will be solid when stippling disabled, dashed when enabled*/
980  glLineStipple(1, 0xCF33);
981  glDisable(GL_LINE_STIPPLE);
982 
983  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
984  glFogi(GL_FOG_MODE, GL_LINEAR);
985  glFogf(GL_FOG_START, 0.0);
986  glFogf(GL_FOG_END, 2.0);
987  glFogfv(GL_FOG_COLOR, backgnd);
988 
989  /*XXX Need to do something about VIEWFACTOR */
990  glFogf(GL_FOG_DENSITY, VIEWFACTOR);
991 
992  /* Initialize matrices */
993  /* Leave it in model_view mode normally */
994  glMatrixMode(GL_PROJECTION);
995  glLoadIdentity();
996  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
997  glGetDoublev(GL_PROJECTION_MATRIX, privvars->faceplate_mat);
998  glPushMatrix();
999  glMatrixMode(GL_MODELVIEW);
1000  glLoadIdentity();
1001  glPushMatrix();
1002  glLoadIdentity();
1003  privvars->face_flag = 1; /* faceplate matrix is on top of stack */
1004 
1005  ogl_setZBuffer(dmp, dmp->dm_zbuffer);
1006  ogl_setLight(dmp, dmp->dm_light);
1007 
1008  return dmp;
1009 }
1010 
1011 
1012 int
1013 ogl_share_dlist(struct dm_internal *dmp1, struct dm_internal *dmp2)
1014 {
1015  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp1->m_vars;
1016  GLfloat backgnd[4];
1017  GLfloat vf;
1018  GLXContext old_glxContext;
1019 
1020  if (dmp1 == (struct dm_internal *)NULL)
1021  return TCL_ERROR;
1022 
1023  if (dmp2 == (struct dm_internal *)NULL) {
1024  /* create a new graphics context for dmp1 with private display lists */
1025 
1026  old_glxContext = ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc;
1027 
1028  if ((((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc =
1029  glXCreateContext(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy,
1030  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->vip,
1031  (GLXContext)NULL, GL_TRUE))==NULL) {
1032  bu_log("ogl_share_dlist: couldn't create glXContext.\nUsing old context\n.");
1033  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
1034 
1035  return TCL_ERROR;
1036  }
1037 
1038  if (!glXMakeCurrent(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy,
1039  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->win,
1040  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc)) {
1041  bu_log("ogl_share_dlist: Couldn't make context current\nUsing old context\n.");
1042  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
1043 
1044  return TCL_ERROR;
1045  }
1046 
1047  /* display list (fontOffset + char) will display a given ASCII char */
1048  if ((((struct ogl_vars *)dmp1->dm_vars.priv_vars)->fontOffset = glGenLists(128))==0) {
1049  bu_log("dm-ogl: Can't make display lists for font.\nUsing old context\n.");
1050  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc = old_glxContext;
1051 
1052  return TCL_ERROR;
1053  }
1054 
1055  /* This is the applications display list offset */
1056  dmp1->dm_displaylist = ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->fontOffset + 128;
1057 
1058  ogl_setBGColor(dmp1, 0, 0, 0);
1059  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1060 
1061  if (mvars->doublebuffer)
1062  glDrawBuffer(GL_BACK);
1063  else
1064  glDrawBuffer(GL_FRONT);
1065 
1066  /* this is important so that ogl_configureWin knows to set the font */
1067  ((struct dm_xvars *)dmp1->dm_vars.pub_vars)->fontstruct = NULL;
1068 
1069  /* do viewport, ortho commands and initialize font */
1070  (void)ogl_configureWin_guts(dmp1, 1);
1071 
1072  /* Lines will be solid when stippling disabled, dashed when enabled*/
1073  glLineStipple(1, 0xCF33);
1074  glDisable(GL_LINE_STIPPLE);
1075 
1076  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
1077  glFogi(GL_FOG_MODE, GL_LINEAR);
1078  glFogf(GL_FOG_START, 0.0);
1079  glFogf(GL_FOG_END, 2.0);
1080  glFogfv(GL_FOG_COLOR, backgnd);
1081 
1082  /*XXX Need to do something about VIEWFACTOR */
1083  vf = 1.0/(*dmp1->dm_vp);
1084  glFogf(GL_FOG_DENSITY, vf);
1085 
1086  /* Initialize matrices */
1087  /* Leave it in model_view mode normally */
1088  glMatrixMode(GL_PROJECTION);
1089  glLoadIdentity();
1090  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
1091  glGetDoublev(GL_PROJECTION_MATRIX, ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->faceplate_mat);
1092  glPushMatrix();
1093  glMatrixMode(GL_MODELVIEW);
1094  glLoadIdentity();
1095  glPushMatrix();
1096  glLoadIdentity();
1097  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->face_flag = 1; /* faceplate matrix is on top of stack */
1098 
1099  /* destroy old context */
1100  glXMakeCurrent(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy, None, NULL);
1101  glXDestroyContext(((struct dm_xvars *)dmp1->dm_vars.pub_vars)->dpy, old_glxContext);
1102  } else {
1103  /* dmp1 will share its display lists with dmp2 */
1104 
1105  old_glxContext = ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->glxc;
1106 
1107  if ((((struct ogl_vars *)dmp2->dm_vars.priv_vars)->glxc =
1108  glXCreateContext(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy,
1109  ((struct dm_xvars *)dmp2->dm_vars.pub_vars)->vip,
1110  ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->glxc,
1111  GL_TRUE))==NULL) {
1112  bu_log("ogl_share_dlist: couldn't create glXContext.\nUsing old context\n.");
1113  ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->glxc = old_glxContext;
1114 
1115  return TCL_ERROR;
1116  }
1117 
1118  if (!glXMakeCurrent(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy,
1119  ((struct dm_xvars *)dmp2->dm_vars.pub_vars)->win,
1120  ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->glxc)) {
1121  bu_log("ogl_share_dlist: Couldn't make context current\nUsing old context\n.");
1122  ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->glxc = old_glxContext;
1123 
1124  return TCL_ERROR;
1125  }
1126 
1127  ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->fontOffset = ((struct ogl_vars *)dmp1->dm_vars.priv_vars)->fontOffset;
1128  dmp2->dm_displaylist = dmp1->dm_displaylist;
1129 
1130  ogl_setBGColor(dmp2, 0, 0, 0);
1131  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1132 
1133  if (mvars->doublebuffer)
1134  glDrawBuffer(GL_BACK);
1135  else
1136  glDrawBuffer(GL_FRONT);
1137 
1138  /* do viewport, ortho commands and initialize font */
1139  (void)ogl_configureWin_guts(dmp2, 1);
1140 
1141  /* Lines will be solid when stippling disabled, dashed when enabled*/
1142  glLineStipple(1, 0xCF33);
1143  glDisable(GL_LINE_STIPPLE);
1144 
1145  backgnd[0] = backgnd[1] = backgnd[2] = backgnd[3] = 0.0;
1146  glFogi(GL_FOG_MODE, GL_LINEAR);
1147  glFogf(GL_FOG_START, 0.0);
1148  glFogf(GL_FOG_END, 2.0);
1149  glFogfv(GL_FOG_COLOR, backgnd);
1150 
1151  /*XXX Need to do something about VIEWFACTOR */
1152  vf = 1.0/(*dmp2->dm_vp);
1153  glFogf(GL_FOG_DENSITY, vf);
1154 
1155  /* Initialize matrices */
1156  /* Leave it in model_view mode normally */
1157  glMatrixMode(GL_PROJECTION);
1158  glLoadIdentity();
1159  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, 0.0, 2.0);
1160  glGetDoublev(GL_PROJECTION_MATRIX, ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->faceplate_mat);
1161  glPushMatrix();
1162  glMatrixMode(GL_MODELVIEW);
1163  glLoadIdentity();
1164  glPushMatrix();
1165  glLoadIdentity();
1166  ((struct ogl_vars *)dmp2->dm_vars.priv_vars)->face_flag = 1; /* faceplate matrix is on top of stack */
1167 
1168  /* destroy old context */
1169  glXMakeCurrent(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy, None, NULL);
1170  glXDestroyContext(((struct dm_xvars *)dmp2->dm_vars.pub_vars)->dpy, old_glxContext);
1171  }
1172 
1173  return TCL_OK;
1174 }
1175 
1176 
1177 /*
1178  * There are global variables which are parameters to this routine.
1179  */
1180 HIDDEN int
1181 ogl_drawBegin(struct dm_internal *dmp)
1182 {
1183  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
1184  GLfloat fogdepth;
1185 
1186  if (dmp->dm_debugLevel) {
1187  bu_log("ogl_drawBegin\n");
1188  }
1189 
1190  if (dmp->dm_debugLevel == 3) {
1191  GLfloat m[16];
1192  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1193 
1194  bu_vls_printf(&tmp_vls, "initial view matrix = \n");
1195 
1196  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1197  ogl_printglmat(&tmp_vls, m);
1198  bu_vls_printf(&tmp_vls, "initial projection matrix = \n");
1199  glGetFloatv (GL_PROJECTION_MATRIX, m);
1200  ogl_printglmat(&tmp_vls, m);
1201 
1202  bu_log("%s", bu_vls_addr(&tmp_vls));
1203  bu_vls_free(&tmp_vls);
1204  }
1205 
1206 
1207 
1208  if (!glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
1209  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
1210  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc)) {
1211  bu_log("ogl_drawBegin: Couldn't make context current\n");
1212  return TCL_ERROR;
1213  }
1214 
1215  /* clear back buffer */
1216  if (!dmp->dm_clearBufferAfter && mvars->doublebuffer) {
1217  glClearColor(((struct ogl_vars *)dmp->dm_vars.priv_vars)->r,
1218  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g,
1219  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b,
1220  0.0);
1221  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1222  }
1223 
1224  if (((struct ogl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
1225  glMatrixMode(GL_PROJECTION);
1226  glPopMatrix();
1227  glMatrixMode(GL_MODELVIEW);
1228  glPopMatrix();
1229  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->face_flag = 0;
1230  if (mvars->cueing_on) {
1231  glEnable(GL_FOG);
1232  /*XXX Need to do something with Viewscale */
1233  fogdepth = 2.2 * (*dmp->dm_vp); /* 2.2 is heuristic */
1234  glFogf(GL_FOG_END, fogdepth);
1235  fogdepth = (GLfloat) (0.5*mvars->fogdensity/
1236  (*dmp->dm_vp));
1237  glFogf(GL_FOG_DENSITY, fogdepth);
1238  glFogi(GL_FOG_MODE, dmp->dm_perspective ? GL_EXP : GL_LINEAR);
1239  }
1240  if (dmp->dm_light) {
1241  glEnable(GL_LIGHTING);
1242  }
1243  }
1244 
1245  if (dmp->dm_debugLevel == 3) {
1246  GLfloat m[16];
1247  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1248 
1249  bu_vls_printf(&tmp_vls, "after begin view matrix = \n");
1250 
1251  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1252  ogl_printglmat(&tmp_vls, m);
1253  bu_vls_printf(&tmp_vls, "after begin projection matrix = \n");
1254  glGetFloatv (GL_PROJECTION_MATRIX, m);
1255  ogl_printglmat(&tmp_vls, m);
1256 
1257  bu_log("%s", bu_vls_addr(&tmp_vls));
1258  bu_vls_free(&tmp_vls);
1259  }
1260 
1261 
1262  return TCL_OK;
1263 }
1264 
1265 
1266 HIDDEN int
1267 ogl_drawEnd(struct dm_internal *dmp)
1268 {
1269  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
1270  if (dmp->dm_debugLevel)
1271  bu_log("ogl_drawEnd\n");
1272 
1273  if (dmp->dm_debugLevel == 3) {
1274  GLfloat m[16];
1275  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1276  bu_vls_printf(&tmp_vls, "beginning of end view matrix = \n");
1277  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1278  ogl_printglmat(&tmp_vls, m);
1279  bu_vls_printf(&tmp_vls, "beginning of end projection matrix = \n");
1280  glGetFloatv (GL_PROJECTION_MATRIX, m);
1281  ogl_printglmat(&tmp_vls, m);
1282  bu_log("%s", bu_vls_addr(&tmp_vls));
1283  bu_vls_free(&tmp_vls);
1284  }
1285 
1286 
1287  if (dmp->dm_light) {
1288  glMatrixMode(GL_MODELVIEW);
1289  glLoadIdentity();
1290  glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
1291  }
1292 
1293  if (mvars->doublebuffer) {
1294  glXSwapBuffers(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
1295  ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win);
1296 
1297  if (dmp->dm_clearBufferAfter) {
1298  /* give Graphics pipe time to work */
1299  glClearColor(((struct ogl_vars *)dmp->dm_vars.priv_vars)->r,
1300  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g,
1301  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b,
1302  0.0);
1303  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1304  }
1305  }
1306 
1307  if (dmp->dm_debugLevel) {
1308  int error;
1309  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1310 
1311  bu_vls_printf(&tmp_vls, "ANY ERRORS?\n");
1312 
1313  while ((error = glGetError())!=0) {
1314  bu_vls_printf(&tmp_vls, "Error: %x\n", error);
1315  }
1316 
1317  bu_log("%s", bu_vls_addr(&tmp_vls));
1318  bu_vls_free(&tmp_vls);
1319  }
1320 
1321  if (dmp->dm_debugLevel == 3) {
1322  GLfloat m[16];
1323  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1324  bu_vls_printf(&tmp_vls, "end of drawend view matrix = \n");
1325  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1326  ogl_printglmat(&tmp_vls, m);
1327  bu_vls_printf(&tmp_vls, "end of drawend projection matrix = \n");
1328  glGetFloatv (GL_PROJECTION_MATRIX, m);
1329  ogl_printglmat(&tmp_vls, m);
1330  bu_log("%s", bu_vls_addr(&tmp_vls));
1331  bu_vls_free(&tmp_vls);
1332  }
1333 
1334 
1335  return TCL_OK;
1336 }
1337 
1338 
1339 /*
1340  * Load a new transformation matrix. This will be followed by
1341  * many calls to ogl_draw().
1342  */
1343 HIDDEN int
1344 ogl_loadMatrix(struct dm_internal *dmp, fastf_t *mat, int which_eye)
1345 {
1346  fastf_t *mptr;
1347  GLfloat gtmat[16];
1348 
1349  if (dmp->dm_debugLevel == 1)
1350  bu_log("ogl_loadMatrix()\n");
1351 
1352  if (dmp->dm_debugLevel == 3) {
1353  GLfloat m[16];
1354  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1355  bu_vls_printf(&tmp_vls, "beginning of loadMatrix view matrix = \n");
1356  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1357  ogl_printglmat(&tmp_vls, m);
1358  bu_vls_printf(&tmp_vls, "beginning of loadMatrix projection matrix = \n");
1359  glGetFloatv (GL_PROJECTION_MATRIX, m);
1360  ogl_printglmat(&tmp_vls, m);
1361  bu_log("%s", bu_vls_addr(&tmp_vls));
1362  bu_vls_free(&tmp_vls);
1363  }
1364 
1365 
1366  if (dmp->dm_debugLevel == 3) {
1367  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1368 
1369  bu_vls_printf(&tmp_vls, "transformation matrix = \n");
1370  ogl_printmat(&tmp_vls, mat);
1371 
1372  bu_log("%s", bu_vls_addr(&tmp_vls));
1373  bu_vls_free(&tmp_vls);
1374  }
1375 
1376  switch (which_eye) {
1377  case 0:
1378  /* Non-stereo */
1379  break;
1380  case 1:
1381  /* R eye */
1382  glViewport(0, 0, (XMAXSCREEN)+1, (YSTEREO)+1);
1383  glScissor(0, 0, (XMAXSCREEN)+1, (YSTEREO)+1);
1384  ogl_drawString2D(dmp, "R", 0.986, 0.0, 0, 1);
1385  break;
1386  case 2:
1387  /* L eye */
1388  glViewport(0, 0+YOFFSET_LEFT, (XMAXSCREEN)+1,
1389  (YSTEREO+YOFFSET_LEFT)-(YOFFSET_LEFT)+1);
1390  glScissor(0, 0+YOFFSET_LEFT, (XMAXSCREEN)+1,
1391  (YSTEREO+YOFFSET_LEFT)-(YOFFSET_LEFT)+1);
1392  break;
1393  }
1394 
1395  mptr = mat;
1396 
1397  gtmat[0] = *(mptr++);
1398  gtmat[4] = *(mptr++);
1399  gtmat[8] = *(mptr++);
1400  gtmat[12] = *(mptr++);
1401 
1402  gtmat[1] = *(mptr++) * dmp->dm_aspect;
1403  gtmat[5] = *(mptr++) * dmp->dm_aspect;
1404  gtmat[9] = *(mptr++) * dmp->dm_aspect;
1405  gtmat[13] = *(mptr++) * dmp->dm_aspect;
1406 
1407  gtmat[2] = *(mptr++);
1408  gtmat[6] = *(mptr++);
1409  gtmat[10] = *(mptr++);
1410  gtmat[14] = *(mptr++);
1411 
1412  gtmat[3] = *(mptr++);
1413  gtmat[7] = *(mptr++);
1414  gtmat[11] = *(mptr++);
1415  gtmat[15] = *(mptr++);
1416 
1417  glMatrixMode(GL_MODELVIEW);
1418  glLoadIdentity();
1419  glLoadMatrixf(gtmat);
1420 
1421  if (dmp->dm_debugLevel == 3) {
1422  GLfloat m[16];
1423  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1424  bu_vls_printf(&tmp_vls, "end of loadMatrix view matrix = \n");
1425  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1426  ogl_printglmat(&tmp_vls, m);
1427  bu_vls_printf(&tmp_vls, "end of loadMatrix projection matrix = \n");
1428  glGetFloatv (GL_PROJECTION_MATRIX, m);
1429  ogl_printglmat(&tmp_vls, m);
1430  bu_log("%s", bu_vls_addr(&tmp_vls));
1431  bu_vls_free(&tmp_vls);
1432  }
1433 
1434  return TCL_OK;
1435 }
1436 
1437 
1438 /*
1439  * Load a new projection matrix.
1440  *
1441  */
1442 HIDDEN int
1443 ogl_loadPMatrix(struct dm_internal *dmp, fastf_t *mat)
1444 {
1445  fastf_t *mptr;
1446  GLfloat gtmat[16];
1447 
1448  glMatrixMode(GL_PROJECTION);
1449 
1450  if (mat == (fastf_t *)NULL) {
1451  if (((struct ogl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
1452  glPopMatrix();
1453  glLoadIdentity();
1454  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1455  glPushMatrix();
1456  glLoadMatrixd(((struct ogl_vars *)dmp->dm_vars.priv_vars)->faceplate_mat);
1457  } else {
1458  glLoadIdentity();
1459  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
1460  }
1461 
1462  return TCL_OK;
1463  }
1464 
1465  mptr = mat;
1466 
1467  gtmat[0] = *(mptr++);
1468  gtmat[4] = *(mptr++);
1469  gtmat[8] = *(mptr++);
1470  gtmat[12] = *(mptr++);
1471 
1472  gtmat[1] = *(mptr++);
1473  gtmat[5] = *(mptr++);
1474  gtmat[9] = *(mptr++);
1475  gtmat[13] = *(mptr++);
1476 
1477  gtmat[2] = *(mptr++);
1478  gtmat[6] = *(mptr++);
1479  gtmat[10] = -*(mptr++);
1480  gtmat[14] = -*(mptr++);
1481 
1482  gtmat[3] = *(mptr++);
1483  gtmat[7] = *(mptr++);
1484  gtmat[11] = *(mptr++);
1485  gtmat[15] = *(mptr++);
1486 
1487  glLoadIdentity();
1488  glLoadMatrixf(gtmat);
1489 
1490  return TCL_OK;
1491 }
1492 
1493 
1494 HIDDEN int
1495 ogl_drawVListHiddenLine(struct dm_internal *dmp, register struct bn_vlist *vp)
1496 {
1497  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
1498  register struct bn_vlist *tvp;
1499  register int first;
1500 
1501  if (dmp->dm_debugLevel == 1)
1502  bu_log("ogl_drawVList()\n");
1503 
1504 
1505  /* First, draw polygons using background color. */
1506 
1507  if (dmp->dm_light) {
1508  glDisable(GL_LIGHTING);
1509  }
1510 
1511  glDisable(GL_BLEND);
1512  glDepthMask(GL_TRUE);
1513  glEnable(GL_DEPTH_TEST);
1514  glDepthFunc(GL_LEQUAL);
1515  glEnable(GL_POLYGON_OFFSET_FILL);
1516  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1517  glPolygonOffset(1.0, 1.0);
1518 
1519  /* Set color to background color for drawing polygons. */
1520  glColor3f(((struct ogl_vars *)dmp->dm_vars.priv_vars)->r,
1521  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->g,
1522  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->b);
1523 
1524  /* Viewing region is from -1.0 to +1.0 */
1525  first = 1;
1526  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1527  register int i;
1528  register int nused = tvp->nused;
1529  register int *cmd = tvp->cmd;
1530  point_t *pt = tvp->pt;
1531  for (i = 0; i < nused; i++, cmd++, pt++) {
1532  GLdouble dpt[3];
1533  VMOVE(dpt, *pt); /* fastf_t-to-double */
1534 /*
1535  if (dmp->dm_debugLevel > 2)
1536  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1537 
1538  switch (*cmd) {
1539  case BN_VLIST_LINE_MOVE:
1540  case BN_VLIST_LINE_DRAW:
1541  break;
1542  case BN_VLIST_POLY_START:
1543  /* Start poly marker & normal */
1544  if (first == 0)
1545  glEnd();
1546  first = 0;
1547 
1548  glBegin(GL_POLYGON);
1549  /* Set surface normal (vl_pnt points outward) */
1550  glNormal3dv(dpt);
1551  break;
1552  case BN_VLIST_POLY_MOVE:
1553  case BN_VLIST_POLY_DRAW:
1554  case BN_VLIST_TRI_MOVE:
1555  case BN_VLIST_TRI_DRAW:
1556  glVertex3dv(dpt);
1557  break;
1558  case BN_VLIST_POLY_END:
1559  /* Draw, End Polygon */
1560  glEnd();
1561  first = 1;
1562  break;
1564  case BN_VLIST_TRI_VERTNORM:
1565  /* Set per-vertex normal. Given before vert. */
1566  glNormal3dv(dpt);
1567  break;
1568  case BN_VLIST_TRI_START:
1569  if (first)
1570  glBegin(GL_TRIANGLES);
1571 
1572  first = 0;
1573 
1574  /* Set surface normal (vl_pnt points outward) */
1575  glNormal3dv(dpt);
1576 
1577  break;
1578  case BN_VLIST_TRI_END:
1579  break;
1580  }
1581  }
1582  }
1583 
1584  if (first == 0)
1585  glEnd();
1586 
1587  /* Last, draw wireframe/edges. */
1588 
1589  /* Set color to wireColor for drawing wireframe/edges */
1590  glColor3f(wireColor[0], wireColor[1], wireColor[2]);
1591 
1592  /* Viewing region is from -1.0 to +1.0 */
1593  first = 1;
1594  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1595  register int i;
1596  register int nused = tvp->nused;
1597  register int *cmd = tvp->cmd;
1598  point_t *pt = tvp->pt;
1599 
1600  for (i = 0; i < nused; i++, cmd++, pt++) {
1601  GLdouble dpt[3];
1602  VMOVE(dpt, *pt); /* fastf_t-to-double */
1603 /*
1604  if (dmp->dm_debugLevel > 2)
1605  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1606 
1607  switch (*cmd) {
1608  case BN_VLIST_LINE_MOVE:
1609  /* Move, start line */
1610  if (first == 0)
1611  glEnd();
1612  first = 0;
1613 
1614  glBegin(GL_LINE_STRIP);
1615  glVertex3dv(dpt);
1616  break;
1617  case BN_VLIST_POLY_START:
1618  case BN_VLIST_TRI_START:
1619  /* Start poly marker & normal */
1620  if (first == 0)
1621  glEnd();
1622  first = 0;
1623 
1624  glBegin(GL_LINE_STRIP);
1625  break;
1626  case BN_VLIST_LINE_DRAW:
1627  case BN_VLIST_POLY_MOVE:
1628  case BN_VLIST_POLY_DRAW:
1629  case BN_VLIST_TRI_MOVE:
1630  case BN_VLIST_TRI_DRAW:
1631  glVertex3dv(dpt);
1632  break;
1633  case BN_VLIST_POLY_END:
1634  case BN_VLIST_TRI_END:
1635  /* Draw, End Polygon */
1636  glVertex3dv(dpt);
1637  glEnd();
1638  first = 1;
1639  break;
1641  case BN_VLIST_TRI_VERTNORM:
1642  /* Set per-vertex normal. Given before vert. */
1643  glNormal3dv(dpt);
1644  break;
1645  }
1646  }
1647  }
1648 
1649  if (first == 0)
1650  glEnd();
1651 
1652  if (dmp->dm_light) {
1653  glEnable(GL_LIGHTING);
1654  }
1655 
1656  if (!mvars->zbuffer_on)
1657  glDisable(GL_DEPTH_TEST);
1658 
1659  if (!dmp->dm_depthMask)
1660  glDepthMask(GL_FALSE);
1661 
1662  glDisable(GL_POLYGON_OFFSET_FILL);
1663 
1664  return TCL_OK;
1665 }
1666 
1667 
1668 HIDDEN int
1669 ogl_drawVList(struct dm_internal *dmp, struct bn_vlist *vp)
1670 {
1671  struct bn_vlist *tvp;
1672  register int first;
1673  register int mflag = 1;
1674  static float black[4] = {0.0, 0.0, 0.0, 0.0};
1675  GLfloat originalPointSize, originalLineWidth;
1676 
1677  glGetFloatv(GL_POINT_SIZE, &originalPointSize);
1678  glGetFloatv(GL_LINE_WIDTH, &originalLineWidth);
1679 
1680  if (dmp->dm_debugLevel == 1)
1681  bu_log("ogl_drawVList()\n");
1682 
1683  /* Viewing region is from -1.0 to +1.0 */
1684  first = 1;
1685  for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
1686  int i;
1687  int nused = tvp->nused;
1688  int *cmd = tvp->cmd;
1689  point_t *pt = tvp->pt;
1690  for (i = 0; i < nused; i++, cmd++, pt++) {
1691  GLdouble dpt[3];
1692  VMOVE(dpt, *pt);
1693 /*
1694  if (dmp->dm_debugLevel > 2)
1695  bu_log(" %d (%g %g %g)\n", *cmd, V3ARGS(dpt));*/
1696 
1697  switch (*cmd) {
1698  case BN_VLIST_LINE_MOVE:
1699  /* Move, start line */
1700  if (first == 0)
1701  glEnd();
1702  first = 0;
1703 
1704  if (dmp->dm_light && mflag) {
1705  mflag = 0;
1706  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, wireColor);
1707  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black);
1708  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
1709  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black);
1710 
1711  if (dmp->dm_transparency)
1712  glDisable(GL_BLEND);
1713  }
1714 
1715  glBegin(GL_LINE_STRIP);
1716  glVertex3dv(dpt);
1717  break;
1718  case BN_VLIST_POLY_START:
1719  case BN_VLIST_TRI_START:
1720  /* Start poly marker & normal */
1721 
1722  if (dmp->dm_light && mflag) {
1723  mflag = 0;
1724  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
1725  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
1726  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
1727  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
1728 
1729  switch (dmp->dm_light) {
1730  case 1:
1731  break;
1732  case 2:
1733  glMaterialfv(GL_BACK, GL_DIFFUSE, diffuseColor);
1734  break;
1735  case 3:
1736  glMaterialfv(GL_BACK, GL_DIFFUSE, backDiffuseColorDark);
1737  break;
1738  default:
1739  glMaterialfv(GL_BACK, GL_DIFFUSE, backDiffuseColorLight);
1740  break;
1741  }
1742 
1743  if (dmp->dm_transparency)
1744  glEnable(GL_BLEND);
1745  }
1746 
1747  if (*cmd == BN_VLIST_POLY_START) {
1748  if (first == 0)
1749  glEnd();
1750 
1751  glBegin(GL_POLYGON);
1752  } else if (first)
1753  glBegin(GL_TRIANGLES);
1754 
1755  /* Set surface normal (vl_pnt points outward) */
1756  glNormal3dv(dpt);
1757 
1758  first = 0;
1759 
1760  break;
1761  case BN_VLIST_LINE_DRAW:
1762  case BN_VLIST_POLY_MOVE:
1763  case BN_VLIST_POLY_DRAW:
1764  case BN_VLIST_TRI_MOVE:
1765  case BN_VLIST_TRI_DRAW:
1766  glVertex3dv(dpt);
1767  break;
1768  case BN_VLIST_POLY_END:
1769  /* Draw, End Polygon */
1770  glEnd();
1771  first = 1;
1772  break;
1773  case BN_VLIST_TRI_END:
1774  break;
1776  case BN_VLIST_TRI_VERTNORM:
1777  /* Set per-vertex normal. Given before vert. */
1778  glNormal3dv(dpt);
1779  break;
1780  case BN_VLIST_POINT_DRAW:
1781  if (first == 0)
1782  glEnd();
1783  first = 0;
1784  glBegin(GL_POINTS);
1785  glVertex3dv(dpt);
1786  break;
1787  case BN_VLIST_LINE_WIDTH: {
1788  GLfloat lineWidth = (GLfloat)(*pt)[0];
1789  if (lineWidth > 0.0) {
1790  glLineWidth(lineWidth);
1791  }
1792  break;
1793  }
1794  case BN_VLIST_POINT_SIZE: {
1795  GLfloat pointSize = (GLfloat)(*pt)[0];
1796  if (pointSize > 0.0) {
1797  glPointSize(pointSize);
1798  }
1799  break;
1800  }
1801  }
1802  }
1803  }
1804 
1805  if (first == 0)
1806  glEnd();
1807 
1808  if (dmp->dm_light && dmp->dm_transparency)
1809  glDisable(GL_BLEND);
1810 
1811  glPointSize(originalPointSize);
1812  glLineWidth(originalLineWidth);
1813 
1814  return TCL_OK;
1815 }
1816 
1817 
1818 HIDDEN int
1819 ogl_draw(struct dm_internal *dmp, struct bn_vlist *(*callback_function)(void *), void **data)
1820 {
1821  struct bn_vlist *vp;
1822  if (!callback_function) {
1823  if (data) {
1824  vp = (struct bn_vlist *)data;
1825  ogl_drawVList(dmp, vp);
1826  }
1827  } else {
1828  if (!data) {
1829  return TCL_ERROR;
1830  } else {
1831  (void)callback_function(data);
1832  }
1833  }
1834  return TCL_OK;
1835 }
1836 
1837 
1838 /*
1839  * Restore the display processor to a normal mode of operation
1840  * (i.e., not scaled, rotated, displaced, etc.).
1841  */
1842 HIDDEN int
1843 ogl_normal(struct dm_internal *dmp)
1844 {
1845  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
1846  if (dmp->dm_debugLevel)
1847  bu_log("ogl_normal\n");
1848 
1849  if (dmp->dm_debugLevel == 3) {
1850  GLfloat m[16];
1851  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1852  bu_vls_printf(&tmp_vls, "beginning of ogl_normal view matrix = \n");
1853  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1854  ogl_printglmat(&tmp_vls, m);
1855  bu_vls_printf(&tmp_vls, "beginning of ogl_normal projection matrix = \n");
1856  glGetFloatv (GL_PROJECTION_MATRIX, m);
1857  ogl_printglmat(&tmp_vls, m);
1858  bu_log("%s", bu_vls_addr(&tmp_vls));
1859  bu_vls_free(&tmp_vls);
1860  }
1861 
1862  if (!((struct ogl_vars *)dmp->dm_vars.priv_vars)->face_flag) {
1863  glMatrixMode(GL_PROJECTION);
1864  glPushMatrix();
1865  glLoadMatrixd(((struct ogl_vars *)dmp->dm_vars.priv_vars)->faceplate_mat);
1866  glMatrixMode(GL_MODELVIEW);
1867  glPushMatrix();
1868  glLoadIdentity();
1869  ((struct ogl_vars *)dmp->dm_vars.priv_vars)->face_flag = 1;
1870  if (mvars->cueing_on)
1871  glDisable(GL_FOG);
1872  if (dmp->dm_light)
1873  glDisable(GL_LIGHTING);
1874  }
1875 
1876  if (dmp->dm_debugLevel == 3) {
1877  GLfloat m[16];
1878  struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;
1879  bu_vls_printf(&tmp_vls, "end of ogl_normal view matrix = \n");
1880  glGetFloatv (GL_MODELVIEW_MATRIX, m);
1881  ogl_printglmat(&tmp_vls, m);
1882  bu_vls_printf(&tmp_vls, "end of ogl_normal projection matrix = \n");
1883  glGetFloatv (GL_PROJECTION_MATRIX, m);
1884  ogl_printglmat(&tmp_vls, m);
1885  bu_log("%s", bu_vls_addr(&tmp_vls));
1886  bu_vls_free(&tmp_vls);
1887  }
1888 
1889  return TCL_OK;
1890 }
1891 
1892 
1893 /*
1894  * Output a string.
1895  * The starting position of the beam is as specified.
1896  */
1897 HIDDEN int
1898 ogl_drawString2D(struct dm_internal *dmp, const char *str, fastf_t x, fastf_t y, int UNUSED(size), int use_aspect)
1899 {
1900  if (dmp->dm_debugLevel)
1901  bu_log("ogl_drawString2D()\n");
1902 
1903  if (use_aspect)
1904  glRasterPos2f(x, y * dmp->dm_aspect);
1905  else
1906  glRasterPos2f(x, y);
1907 
1908  glListBase(((struct ogl_vars *)dmp->dm_vars.priv_vars)->fontOffset);
1909  glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
1910 
1911  return TCL_OK;
1912 }
1913 
1914 
1915 HIDDEN int
1916 ogl_drawLine2D(struct dm_internal *dmp, fastf_t X1, fastf_t Y1, fastf_t X2, fastf_t Y2)
1917 {
1918  return drawLine2D(dmp, X1, Y1, X2, Y2, "ogl_drawLine2D()\n");
1919 }
1920 
1921 
1922 HIDDEN int
1923 ogl_drawLine3D(struct dm_internal *dmp, point_t pt1, point_t pt2)
1924 {
1925  return drawLine3D(dmp, pt1, pt2, "ogl_drawLine3D()\n", wireColor);
1926 }
1927 
1928 
1929 HIDDEN int
1930 ogl_drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int sflag)
1931 {
1932  return drawLines3D(dmp, npoints, points, sflag, "ogl_drawLine3D()\n", wireColor);
1933 }
1934 
1935 
1936 HIDDEN int
1937 ogl_drawPoint2D(struct dm_internal *dmp, fastf_t x, fastf_t y)
1938 {
1939  if (dmp->dm_debugLevel) {
1940  bu_log("ogl_drawPoint2D():\n");
1941  bu_log("\tdmp: %p\tx - %lf\ty - %lf\n", (void *)dmp, x, y);
1942  }
1943 
1944  glBegin(GL_POINTS);
1945  glVertex2f(x, y);
1946  glEnd();
1947 
1948  return TCL_OK;
1949 }
1950 
1951 
1952 HIDDEN int
1953 ogl_drawPoint3D(struct dm_internal *dmp, point_t point)
1954 {
1955  GLdouble dpt[3];
1956 
1957  if (!dmp || !point)
1958  return TCL_ERROR;
1959 
1960  if (dmp->dm_debugLevel) {
1961  bu_log("ogl_drawPoint3D():\n");
1962  bu_log("\tdmp: %p\tpt - %lf %lf %lf\n", (void*)dmp, V3ARGS(point));
1963  }
1964 
1965  /* fastf_t to double */
1966  VMOVE(dpt, point);
1967 
1968  glBegin(GL_POINTS);
1969  glVertex3dv(dpt);
1970  glEnd();
1971 
1972  return TCL_OK;
1973 }
1974 
1975 
1976 HIDDEN int
1977 ogl_drawPoints3D(struct dm_internal *dmp, int npoints, point_t *points)
1978 {
1979  GLdouble dpt[3];
1980  register int i;
1981 
1982  if (!dmp || npoints < 0 || !points)
1983  return TCL_ERROR;
1984 
1985  if (dmp->dm_debugLevel) {
1986  bu_log("ogl_drawPoint3D():\n");
1987  }
1988 
1989 
1990  glBegin(GL_POINTS);
1991  for (i = 0; i < npoints; ++i) {
1992  /* fastf_t to double */
1993  VMOVE(dpt, points[i]);
1994  glVertex3dv(dpt);
1995  }
1996  glEnd();
1997 
1998  return TCL_OK;
1999 }
2000 
2001 
2002 HIDDEN int
2003 ogl_setFGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency)
2004 {
2005  /*if (dmp->dm_debugLevel)
2006  bu_log("ogl_setFGColor()\n");*/
2007 
2008  dmp->dm_fg[0] = r;
2009  dmp->dm_fg[1] = g;
2010  dmp->dm_fg[2] = b;
2011 
2012  /* wireColor gets the full rgb */
2013  wireColor[0] = r / 255.0;
2014  wireColor[1] = g / 255.0;
2015  wireColor[2] = b / 255.0;
2016  wireColor[3] = transparency;
2017 
2018  if (strict) {
2019  glColor3ub((GLubyte)r, (GLubyte)g, (GLubyte)b);
2020  } else {
2021 
2022  if (dmp->dm_light) {
2023  /* Ambient = .2, Diffuse = .6, Specular = .2 */
2024 
2025  ambientColor[0] = wireColor[0] * 0.2;
2026  ambientColor[1] = wireColor[1] * 0.2;
2027  ambientColor[2] = wireColor[2] * 0.2;
2028  ambientColor[3] = wireColor[3];
2029 
2030  specularColor[0] = ambientColor[0];
2031  specularColor[1] = ambientColor[1];
2032  specularColor[2] = ambientColor[2];
2033  specularColor[3] = ambientColor[3];
2034 
2035  diffuseColor[0] = wireColor[0] * 0.6;
2036  diffuseColor[1] = wireColor[1] * 0.6;
2037  diffuseColor[2] = wireColor[2] * 0.6;
2038  diffuseColor[3] = wireColor[3];
2039 
2040  backDiffuseColorDark[0] = wireColor[0] * 0.3;
2041  backDiffuseColorDark[1] = wireColor[1] * 0.3;
2042  backDiffuseColorDark[2] = wireColor[2] * 0.3;
2043  backDiffuseColorDark[3] = wireColor[3];
2044 
2045  backDiffuseColorLight[0] = wireColor[0] * 0.9;
2046  backDiffuseColorLight[1] = wireColor[1] * 0.9;
2047  backDiffuseColorLight[2] = wireColor[2] * 0.9;
2048  backDiffuseColorLight[3] = wireColor[3];
2049 
2050  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
2051  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
2052  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
2053  } else {
2054  glColor3ub((GLubyte)r, (GLubyte)g, (GLubyte)b);
2055  }
2056  }
2057 
2058  return TCL_OK;
2059 }
2060 
2061 
2062 HIDDEN int
2063 ogl_setLineAttr(struct dm_internal *dmp, int width, int style)
2064 {
2065  /*if (dmp->dm_debugLevel)
2066  bu_log("ogl_setLineAttr()\n");*/
2067 
2068  dmp->dm_lineWidth = width;
2069  dmp->dm_lineStyle = style;
2070 
2071  glLineWidth((GLfloat) width);
2072 
2073  if (style == DM_DASHED_LINE)
2074  glEnable(GL_LINE_STIPPLE);
2075  else
2076  glDisable(GL_LINE_STIPPLE);
2077 
2078  return TCL_OK;
2079 }
2080 
2081 
2082 HIDDEN int
2083 ogl_debug(struct dm_internal *dmp, int lvl)
2084 {
2085  dmp->dm_debugLevel = lvl;
2086 
2087  return TCL_OK;
2088 }
2089 
2090 HIDDEN int
2091 ogl_logfile(struct dm_internal *dmp, const char *filename)
2092 {
2093  bu_vls_sprintf(&dmp->dm_log, "%s", filename);
2094 
2095  return TCL_OK;
2096 }
2097 
2098 HIDDEN int
2099 ogl_setWinBounds(struct dm_internal *dmp, fastf_t *w)
2100 {
2101  GLint mm;
2102 
2103  if (dmp->dm_debugLevel)
2104  bu_log("ogl_setWinBounds()\n");
2105 
2106  dmp->dm_clipmin[0] = w[0];
2107  dmp->dm_clipmin[1] = w[2];
2108  dmp->dm_clipmin[2] = w[4];
2109  dmp->dm_clipmax[0] = w[1];
2110  dmp->dm_clipmax[1] = w[3];
2111  dmp->dm_clipmax[2] = w[5];
2112 
2113  glGetIntegerv(GL_MATRIX_MODE, &mm);
2114  glMatrixMode(GL_PROJECTION);
2115  glPopMatrix();
2116  glLoadIdentity();
2117  glOrtho(-xlim_view, xlim_view, -ylim_view, ylim_view, dmp->dm_clipmin[2], dmp->dm_clipmax[2]);
2118  glPushMatrix();
2119  glMatrixMode(mm);
2120 
2121  return TCL_OK;
2122 }
2123 
2124 
2125 HIDDEN int
2126 ogl_setTransparency(struct dm_internal *dmp,
2127  int transparency_on)
2128 {
2129  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
2130  if (dmp->dm_debugLevel)
2131  bu_log("ogl_setTransparency()\n");
2132 
2133  dmp->dm_transparency = transparency_on;
2134  mvars->transparency_on = dmp->dm_transparency;
2135 
2136  if (transparency_on) {
2137  /* Turn it on */
2138  glEnable(GL_BLEND);
2139  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2140  } else {
2141  /* Turn it off */
2142  glDisable(GL_BLEND);
2143  }
2144 
2145  return TCL_OK;
2146 }
2147 
2148 
2149 HIDDEN int
2150 ogl_setDepthMask(struct dm_internal *dmp,
2151  int enable) {
2152  if (dmp->dm_debugLevel)
2153  bu_log("ogl_setDepthMask()\n");
2154 
2155  dmp->dm_depthMask = enable;
2156 
2157  if (enable)
2158  glDepthMask(GL_TRUE);
2159  else
2160  glDepthMask(GL_FALSE);
2161 
2162  return TCL_OK;
2163 }
2164 
2165 
2166 HIDDEN int
2167 ogl_setZBuffer(struct dm_internal *dmp, int zbuffer_on)
2168 {
2169  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
2170  if (dmp->dm_debugLevel)
2171  bu_log("ogl_setZBuffer:\n");
2172 
2173  dmp->dm_zbuffer = zbuffer_on;
2174  mvars->zbuffer_on = dmp->dm_zbuffer;
2175 
2176  if (mvars->zbuf == 0) {
2177  dmp->dm_zbuffer = 0;
2178  mvars->zbuffer_on = dmp->dm_zbuffer;
2179  }
2180 
2181  if (mvars->zbuffer_on) {
2182  glDepthFunc(GL_LEQUAL);
2183  glEnable(GL_DEPTH_TEST);
2184  } else {
2185  glDisable(GL_DEPTH_TEST);
2186  }
2187 
2188  return TCL_OK;
2189 }
2190 
2191 
2192 HIDDEN int
2193 ogl_beginDList(struct dm_internal *dmp, unsigned int list)
2194 {
2195  if (dmp->dm_debugLevel)
2196  bu_log("ogl_beginDList()\n");
2197 
2198  glNewList((GLuint)list, GL_COMPILE);
2199  return TCL_OK;
2200 }
2201 
2202 
2203 HIDDEN int
2204 ogl_endDList(struct dm_internal *dmp)
2205 {
2206  if (dmp->dm_debugLevel)
2207  bu_log("ogl_endDList()\n");
2208 
2209  glEndList();
2210  return TCL_OK;
2211 }
2212 
2213 
2214 HIDDEN void
2215 ogl_drawDList(unsigned int list)
2216 {
2217  glCallList((GLuint)list);
2218 }
2219 
2220 
2221 HIDDEN int
2222 ogl_freeDLists(struct dm_internal *dmp, unsigned int list, int range)
2223 {
2224  if (dmp->dm_debugLevel)
2225  bu_log("ogl_freeDLists()\n");
2226 
2227  glDeleteLists((GLuint)list, (GLsizei)range);
2228  return TCL_OK;
2229 }
2230 
2231 
2232 HIDDEN int
2233 ogl_genDLists(struct dm_internal *dmp, size_t range)
2234 {
2235  if (dmp->dm_debugLevel)
2236  bu_log("ogl_freeDLists()\n");
2237 
2238  return glGenLists((GLsizei)range);
2239 }
2240 
2241 HIDDEN int
2242 ogl_draw_obj(struct dm_internal *dmp, struct display_list *obj)
2243 {
2244  struct solid *sp;
2245  FOR_ALL_SOLIDS(sp, &obj->dl_headSolid) {
2246  if (sp->s_dlist == 0)
2247  sp->s_dlist = dm_gen_dlists(dmp, 1);
2248 
2249  (void)dm_make_current(dmp);
2250  (void)dm_begin_dlist(dmp, sp->s_dlist);
2251  if (sp->s_iflag == UP)
2252  (void)dm_set_fg(dmp, 255, 255, 255, 0, sp->s_transparency);
2253  else
2254  (void)dm_set_fg(dmp,
2255  (unsigned char)sp->s_color[0],
2256  (unsigned char)sp->s_color[1],
2257  (unsigned char)sp->s_color[2], 0, sp->s_transparency);
2258  (void)dm_draw_vlist(dmp, (struct bn_vlist *)&sp->s_vlist);
2259  (void)dm_end_dlist(dmp);
2260  }
2261  return 0;
2262 }
2263 
2264 HIDDEN int
2265 ogl_getDisplayImage(struct dm_internal *dmp, unsigned char **image)
2266 {
2267  unsigned char *idata = NULL;
2268  int width = 0;
2269  int height = 0;
2270  int bytes_per_pixel = 3; /*rgb no alpha for raw pix */
2271  GLuint *pixels;
2272  unsigned int pixel;
2273  unsigned int red_mask = 0xff000000;
2274  unsigned int green_mask = 0x00ff0000;
2275  unsigned int blue_mask = 0x0000ff00;
2276  int h, w;
2277 #if defined(DM_WGL)
2278  unsigned int alpha_mask = 0x000000ff;
2279  int big_endian;
2280  int swap_bytes;
2281 
2282  if ((bu_byteorder() == BU_BIG_ENDIAN))
2283  big_endian = 1;
2284  else
2285  big_endian = 0;
2286 
2287  /* WTF */
2288  swap_bytes = !big_endian;
2289 #endif
2290 
2291  if (dmp->dm_type == DM_TYPE_WGL || dmp->dm_type == DM_TYPE_OGL) {
2292  width = dmp->dm_width;
2293  height = dmp->dm_height;
2294 
2295  pixels = (GLuint *)bu_calloc(width * height, sizeof(GLuint), "pixels");
2296 
2297  {
2298  glReadBuffer(GL_FRONT);
2299 #if defined(DM_WGL)
2300  /* XXX GL_UNSIGNED_INT_8_8_8_8 is currently not
2301  * available on windows. Need to update when it
2302  * becomes available.
2303  */
2304  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2305 #else
2306  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels);
2307 #endif
2308 
2309  idata = (unsigned char *)bu_calloc(height * width * bytes_per_pixel, sizeof(unsigned char), "rgb data");
2310  *image = idata;
2311 
2312  for (h = 0; h < height; h++) {
2313  for (w = 0; w < width; w++) {
2314  int i = h*width + w;
2315  int i_h_inv = (height - h - 1)*width + w;
2316  int j = i*bytes_per_pixel;
2317  unsigned char *value = (unsigned char *)(idata + j);
2318 #if defined(DM_WGL)
2319  unsigned char alpha;
2320 #endif
2321 
2322  pixel = pixels[i_h_inv];
2323 
2324  value[0] = (pixel & red_mask) >> 24;
2325  value[1] = (pixel & green_mask) >> 16;
2326  value[2] = (pixel & blue_mask) >> 8;
2327 
2328 #if defined(DM_WGL)
2329  alpha = pixel & alpha_mask;
2330  if (swap_bytes) {
2331  unsigned char tmp_byte;
2332 
2333  value[0] = alpha;
2334  /* swap byte1 and byte2 */
2335  tmp_byte = value[1];
2336  value[1] = value[2];
2337  value[2] = tmp_byte;
2338  }
2339 #endif
2340  }
2341 
2342  }
2343 
2344  bu_free(pixels, "pixels");
2345  }
2346  } else {
2347  bu_log("ogl_getDisplayImage: Display type not set as OGL or WGL\n");
2348  return TCL_ERROR;
2349  }
2350 
2351  return TCL_OK; /* caller will need to bu_free(idata, "image data"); */
2352 }
2353 
2354 int
2355 ogl_openFb(struct dm_internal *dmp)
2356 {
2357  struct fb_platform_specific *fb_ps;
2358  struct ogl_fb_info *ofb_ps;
2359  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
2360  struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
2361  struct ogl_vars *privars = (struct ogl_vars *)dmp->dm_vars.priv_vars;
2362 
2364  ofb_ps = (struct ogl_fb_info *)fb_ps->data;
2365  ofb_ps->dpy = pubvars->dpy;
2366  ofb_ps->win = pubvars->win;
2367  ofb_ps->cmap = pubvars->cmap;
2368  ofb_ps->vip = pubvars->vip;
2369  ofb_ps->glxc = privars->glxc;
2370  ofb_ps->double_buffer = mvars->doublebuffer;
2371  ofb_ps->soft_cmap = 0;
2372  dmp->fbp = fb_open_existing("ogl", dm_get_width(dmp), dm_get_height(dmp), fb_ps);
2373  fb_put_platform_specific(fb_ps);
2374  return 0;
2375 }
2376 
2377 void
2378 ogl_get_internal(struct dm_internal *dmp)
2379 {
2380  struct modifiable_ogl_vars *mvars = NULL;
2381  if (!dmp->m_vars) {
2382  BU_GET(dmp->m_vars, struct modifiable_ogl_vars);
2383  mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
2384  mvars->this_dm = dmp;
2385  bu_vls_init(&(mvars->log));
2386  }
2387 }
2388 
2389 void
2390 ogl_put_internal(struct dm_internal *dmp)
2391 {
2392  struct modifiable_ogl_vars *mvars = NULL;
2393  if (dmp->m_vars) {
2394  mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
2395  bu_vls_free(&(mvars->log));
2396  BU_PUT(dmp->m_vars, struct modifiable_ogl_vars);
2397  }
2398 }
2399 
2400 void
2401 Ogl_colorchange(const struct bu_structparse *sdp,
2402  const char *name,
2403  void *base,
2404  const char *value,
2405  void *data)
2406 {
2407  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2408  if (mvars->cueing_on) {
2409  glEnable(GL_FOG);
2410  } else {
2411  glDisable(GL_FOG);
2412  }
2413 
2414  dm_generic_hook(sdp, name, base, value, data);
2415 }
2416 
2417 static void
2418 ogl_zclip_hook(const struct bu_structparse *sdp,
2419  const char *name,
2420  void *base,
2421  const char *value,
2422  void *data)
2423 {
2424  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2425  dm *dmp = mvars->this_dm;
2426  fastf_t bounds[6] = { GED_MIN, GED_MAX, GED_MIN, GED_MAX, GED_MIN, GED_MAX };
2427 
2428  dmp->dm_zclip = mvars->zclipping_on;
2429 
2430  if (dmp->dm_zclip) {
2431  bounds[4] = -1.0;
2432  bounds[5] = 1.0;
2433  }
2434 
2435  (void)dm_make_current(dmp);
2436  (void)dm_set_win_bounds(dmp, bounds);
2437 
2438  dm_generic_hook(sdp, name, base, value, data);
2439 }
2440 
2441 static void
2442 ogl_debug_hook(const struct bu_structparse *sdp,
2443  const char *name,
2444  void *base,
2445  const char *value,
2446  void *data)
2447 {
2448  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2449  dm *dmp = mvars->this_dm;
2450 
2451  dm_debug(dmp, mvars->debug);
2452 
2453  dm_generic_hook(sdp, name, base, value, data);
2454 }
2455 
2456 
2457 static void
2458 ogl_logfile_hook(const struct bu_structparse *sdp,
2459  const char *name,
2460  void *base,
2461  const char *value,
2462  void *data)
2463 {
2464  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2465  dm *dmp = mvars->this_dm;
2466 
2467  dm_logfile(dmp, bu_vls_addr(&mvars->log));
2468 
2469  dm_generic_hook(sdp, name, base, value, data);
2470 }
2471 
2472 static void
2473 ogl_bound_hook(const struct bu_structparse *sdp,
2474  const char *name,
2475  void *base,
2476  const char *value,
2477  void *data)
2478 {
2479  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2480  dm *dmp = mvars->this_dm;
2481 
2482  dmp->dm_bound = mvars->bound;
2483 
2484  dm_generic_hook(sdp, name, base, value, data);
2485 }
2486 
2487 static void
2488 ogl_bound_flag_hook(const struct bu_structparse *sdp,
2489  const char *name,
2490  void *base,
2491  const char *value,
2492  void *data)
2493 {
2494  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2495  dm *dmp = mvars->this_dm;
2496 
2497  dmp->dm_boundFlag = mvars->boundFlag;
2498 
2499  dm_generic_hook(sdp, name, base, value, data);
2500 }
2501 
2502 static void
2503 ogl_zbuffer_hook(const struct bu_structparse *sdp,
2504  const char *name,
2505  void *base,
2506  const char *value,
2507  void *data)
2508 {
2509  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2510  dm *dmp = mvars->this_dm;
2511 
2512  (void)dm_make_current(dmp);
2513  (void)dm_set_zbuffer(dmp, mvars->zbuffer_on);
2514 
2515  dm_generic_hook(sdp, name, base, value, data);
2516 }
2517 
2518 static void
2519 ogl_lighting_hook(const struct bu_structparse *sdp,
2520  const char *name,
2521  void *base,
2522  const char *value,
2523  void *data)
2524 {
2525  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2526  dm *dmp = mvars->this_dm;
2527 
2528  (void)dm_make_current(dmp);
2529  (void)dm_set_light(dmp, mvars->lighting_on);
2530 
2531  dm_generic_hook(sdp, name, base, value, data);
2532 }
2533 
2534 static void
2535 ogl_transparency_hook(const struct bu_structparse *sdp,
2536  const char *name,
2537  void *base,
2538  const char *value,
2539  void *data)
2540 {
2541  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2542  dm *dmp = mvars->this_dm;
2543 
2544  (void)dm_make_current(dmp);
2545  (void)dm_set_transparency(dmp, mvars->transparency_on);
2546 
2547  dm_generic_hook(sdp, name, base, value, data);
2548 }
2549 
2550 static void
2551 ogl_fog_hook(const struct bu_structparse *sdp,
2552  const char *name,
2553  void *base,
2554  const char *value,
2555  void *data)
2556 {
2557  struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars *)base;
2558  dm *dmp = mvars->this_dm;
2559 
2560  dm_fogHint(dmp, mvars->fastfog);
2561 
2562  dm_generic_hook(sdp, name, base, value, data);
2563 }
2564 
2565 struct bu_structparse Ogl_vparse[] = {
2566  {"%d", 1, "depthcue", Ogl_MV_O(cueing_on), Ogl_colorchange, NULL, NULL },
2567  {"%d", 1, "zclip", Ogl_MV_O(zclipping_on), ogl_zclip_hook, NULL, NULL },
2568  {"%d", 1, "zbuffer", Ogl_MV_O(zbuffer_on), ogl_zbuffer_hook, NULL, NULL },
2569  {"%d", 1, "lighting", Ogl_MV_O(lighting_on), ogl_lighting_hook, NULL, NULL },
2570  {"%d", 1, "transparency", Ogl_MV_O(transparency_on), ogl_transparency_hook, NULL, NULL },
2571  {"%d", 1, "fastfog", Ogl_MV_O(fastfog), ogl_fog_hook, NULL, NULL },
2572  {"%g", 1, "density", Ogl_MV_O(fogdensity), dm_generic_hook, NULL, NULL },
2573  {"%d", 1, "has_zbuf", Ogl_MV_O(zbuf), dm_generic_hook, NULL, NULL },
2574  {"%d", 1, "has_rgb", Ogl_MV_O(rgb), dm_generic_hook, NULL, NULL },
2575  {"%d", 1, "has_doublebuffer", Ogl_MV_O(doublebuffer), dm_generic_hook, NULL, NULL },
2576  {"%d", 1, "depth", Ogl_MV_O(depth), dm_generic_hook, NULL, NULL },
2577  {"%d", 1, "debug", Ogl_MV_O(debug), ogl_debug_hook, NULL, NULL },
2578  {"%V", 1, "log", Ogl_MV_O(log), ogl_logfile_hook, NULL, NULL },
2579  {"%g", 1, "bound", Ogl_MV_O(bound), ogl_bound_hook, NULL, NULL },
2580  {"%d", 1, "useBound", Ogl_MV_O(boundFlag), ogl_bound_flag_hook, NULL, NULL },
2581  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
2582 };
2583 
2584 struct dm_internal dm_ogl = {
2585  ogl_close,
2586  ogl_drawBegin,
2587  ogl_drawEnd,
2588  ogl_normal,
2589  ogl_loadMatrix,
2590  ogl_loadPMatrix,
2591  ogl_drawString2D,
2592  ogl_drawLine2D,
2593  ogl_drawLine3D,
2594  ogl_drawLines3D,
2595  ogl_drawPoint2D,
2596  ogl_drawPoint3D,
2597  ogl_drawPoints3D,
2598  ogl_drawVList,
2599  ogl_drawVListHiddenLine,
2600  ogl_draw,
2601  ogl_setFGColor,
2602  ogl_setBGColor,
2603  ogl_setLineAttr,
2604  ogl_configureWin,
2605  ogl_setWinBounds,
2606  ogl_setLight,
2607  ogl_setTransparency,
2608  ogl_setDepthMask,
2609  ogl_setZBuffer,
2610  ogl_debug,
2611  ogl_logfile,
2612  ogl_beginDList,
2613  ogl_endDList,
2614  ogl_drawDList,
2615  ogl_freeDLists,
2616  ogl_genDLists,
2617  ogl_draw_obj,
2618  ogl_getDisplayImage, /* display to image function */
2619  ogl_reshape,
2620  ogl_makeCurrent,
2621  ogl_openFb,
2622  ogl_get_internal,
2623  ogl_put_internal,
2624  0,
2625  1, /* has displaylist */
2626  0, /* no stereo by default */
2627  1.0, /* zoom-in limit */
2628  1, /* bound flag */
2629  "ogl",
2630  "X Windows with OpenGL graphics",
2631  DM_TYPE_OGL,
2632  1,
2633  0,
2634  0,
2635  0, /* bytes per pixel */
2636  0, /* bits per channel */
2637  0,
2638  0,
2639  1.0, /* aspect ratio */
2640  0,
2641  {0, 0},
2642  NULL,
2643  NULL,
2644  BU_VLS_INIT_ZERO, /* bu_vls path name*/
2645  BU_VLS_INIT_ZERO, /* bu_vls full name drawing window */
2646  BU_VLS_INIT_ZERO, /* bu_vls short name drawing window */
2647  {0, 0, 0}, /* bg color */
2648  {0, 0, 0}, /* fg color */
2649  {GED_MIN, GED_MIN, GED_MIN}, /* clipmin */
2650  {GED_MAX, GED_MAX, GED_MAX}, /* clipmax */
2651  0, /* no debugging */
2652  BU_VLS_INIT_ZERO, /* bu_vls logfile */
2653  0, /* no perspective */
2654  0, /* no lighting */
2655  0, /* no transparency */
2656  1, /* depth buffer is writable */
2657  1, /* zbuffer */
2658  0, /* no zclipping */
2659  0, /* clear back buffer after drawing and swap */
2660  0, /* not overriding the auto font size */
2661  Ogl_vparse,
2662  FB_NULL,
2663  0 /* Tcl interpreter */
2664 };
2665 
2666 
2667 #endif /* DM_OGL */
2668 
2669 /*
2670  * Local Variables:
2671  * mode: C
2672  * tab-width: 8
2673  * indent-tabs-mode: t
2674  * c-file-style: "stroustrup"
2675  * End:
2676  * ex: shiftwidth=4 tabstop=8
2677  */
#define FONT5
Definition: dm.h:75
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
GLXContext glxc
Definition: dm-ogl.h:47
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
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
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
int depth
Definition: dm_xvars.h:66
#define DM_TYPE_WGL
Definition: dm.h:99
#define FB_OGL_MAGIC
Definition: magic.h:182
#define FONT9
Definition: dm.h:79
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
#define FONT6
Definition: dm.h:76
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
void ogl_fogHint()
long Display
Definition: dm_xvars.h:49
int dm_logfile(dm *dmp, const char *filename)
Definition: dm-generic.c:802
Header file for the BRL-CAD common definitions.
#define DM_VALID_FONT_SIZE(_size)
Definition: dm.h:86
int dm_bits_per_channel
Definition: dm_private.h:94
int dm_light
!0 means lighting on
Definition: dm_private.h:112
#define DM_FONT_SIZE_TO_NAME(_size)
Definition: dm.h:87
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
#define BN_VLIST_POLY_MOVE
move to first poly vertex
Definition: vlist.h:85
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
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
int dm_bytes_per_pixel
Definition: dm_private.h:93
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
COMPLEX data[64]
Definition: fftest.c:34
Colormap cmap
Definition: dm_xvars.h:67
GLdouble faceplate_mat[16]
Definition: dm-ogl.h:48
int face_flag
Definition: dm-ogl.h:49
#define DM_NULL
Definition: dm.h:43
void * memset(void *s, int c, size_t n)
#define FONT12
Definition: dm.h:81
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 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
#define FONT7
Definition: dm.h:77
char is_direct
Definition: dm-ogl.h:53
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_stereo
stereo flag
Definition: dm_private.h:84
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 FONT8
Definition: dm.h:78
#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_fontsize
!0 override's the auto font size
Definition: dm_private.h:118
#define FONT10
Definition: dm.h:80
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
#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
int fontOffset
Definition: dm-ogl.h:51
#define FONTBACK
Definition: dm.h:74
#define BN_VLIST_TRI_DRAW
subsequent triangle vertex
Definition: vlist.h:91
double dm_bound
zoom-in limit
Definition: dm_private.h:85
unsigned char dm_bg[3]
background color
Definition: dm_private.h:105
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 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
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
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 DM_TYPE_OGL
Definition: dm.h:96
#define BN_VLIST_POINT_DRAW
Draw a single point.
Definition: vlist.h:94
dm dm_ogl
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126
#define BN_VLIST_TRI_MOVE
move to first triangle vertex
Definition: vlist.h:90