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