GRASS GIS 7 Programmer's Manual  7.5.svn(2017)-r71769
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
nviz/render.c
Go to the documentation of this file.
1 /*!
2  \file lib/nviz/render.c
3 
4  \brief Nviz library -- GLX context manipulation
5 
6  Based on visualization/nviz/src/togl.c
7 
8  (C) 2008, 2010 by the GRASS Development Team
9  This program is free software under the GNU General Public License
10  (>=v2). Read the file COPYING that comes with GRASS for details.
11 
12  \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
13  */
14 
15 #include <grass/glocale.h>
16 #include <grass/nviz.h>
17 
18 /*!
19  \brief Allocate memory for render window
20 
21  \return pointer to render_window struct
22  \return NULL on failure
23  */
25 {
26  struct render_window *rwin;
27 
28  /* G_malloc() calls G_fatal_error() on failure */
29  rwin = (struct render_window *)G_malloc(sizeof(struct render_window));
30 
31  return rwin;
32 }
33 
34 /*!
35  \brief Initialize render window
36 
37  \param win pointer to render_window struct
38  */
40 {
41 #if defined(OPENGL_X11)
42  rwin->displayId = NULL;
43  rwin->contextId = NULL;
44  rwin->pixmap = 0;
45  rwin->windowId = 0;
46 #elif defined(OPENGL_AQUA)
47  rwin->pixelFmtId = NULL;
48  rwin->contextId = NULL;
49  rwin->windowId = NULL;
50 #elif defined(OPENGL_WINDOWS)
51  rwin->displayId = NULL;
52  rwin->contextId = NULL;
53  rwin->bitmapId = NULL;
54 #endif
55 }
56 
57 /*!
58  \brief Free render window
59 
60  \param win pointer to render_window struct
61  */
63 {
64 #if defined(OPENGL_X11)
65  glXDestroyGLXPixmap(rwin->displayId, rwin->windowId);
66  XFreePixmap(rwin->displayId, rwin->pixmap);
67  glXDestroyContext(rwin->displayId, rwin->contextId);
68  XCloseDisplay(rwin->displayId);
69 #elif defined(OPENGL_AQUA)
70  aglDestroyPixelFormat(rwin->pixelFmtId);
71  aglDestroyContext(rwin->contextId);
72  aglDestroyPBuffer(rwin->windowId);
73  /* TODO FreePixMap */
74 #elif defined(OPENGL_WINDOWS)
75  wglDeleteContext(rwin->contextId);
76  DeleteDC(rwin->displayId);
77  DeleteObject(rwin->bitmapId);
78 #endif
79 
80  G_free((void *)rwin);
81 }
82 
83 /*!
84  \brief Create render window
85 
86  \param rwin pointer to render_window struct
87  \param display display instance (NULL for offscreen)
88  \param width window width
89  \param height window height
90 
91  \return 0 on success
92  \return -1 on error
93  */
94 int Nviz_create_render_window(struct render_window *rwin, void *display,
95  int width, int height)
96 {
97 #if defined(OPENGL_X11)
98  int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1,
99  GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
100  GLX_DEPTH_SIZE, 1, None
101  };
102  XVisualInfo *v;
103 
104  rwin->displayId = XOpenDisplay((char *)display);
105  if (!rwin->displayId) {
106  G_fatal_error(_("Bad server connection"));
107  }
108 
109  v = glXChooseVisual(rwin->displayId,
110  DefaultScreen(rwin->displayId), attributeList);
111  if (!v) {
112  G_warning(_("Unable to get visual info"));
113  return -1;
114  }
115 
116  rwin->contextId = glXCreateContext(rwin->displayId, v, NULL, GL_FALSE);
117 
118  if (!rwin->contextId) {
119  G_warning(_("Unable to create rendering context"));
120  return -1;
121  }
122 
123  /* create win pixmap to render to (same depth as RootWindow) */
124  rwin->pixmap = XCreatePixmap(rwin->displayId,
125  RootWindow(rwin->displayId, v->screen),
126  width, height, v->depth);
127 
128  /* create an off-screen GLX rendering area */
129  rwin->windowId = glXCreateGLXPixmap(rwin->displayId, v, rwin->pixmap);
130 
131  XFree(v);
132 #elif defined(OPENGL_AQUA)
133  int attributeList[] = { AGL_RGBA, AGL_RED_SIZE, 1,
134  AGL_GREEN_SIZE, 1, AGL_BLUE_SIZE, 1,
135  AGL_DEPTH_SIZE, 1, AGL_NONE
136  };
137  /* TODO: open mac display */
138 
139  /* TODO: dev = NULL, ndev = 0 ? */
140  rwin->pixelFmtId = aglChoosePixelFormat(NULL, 0, attributeList);
141 
142  rwin->contextId = aglCreateContext(rwin->pixelFmtId, NULL);
143 
144  /* create an off-screen AGL rendering area */
145  aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &(rwin->windowId));
146 #elif defined(OPENGL_WINDOWS)
147  PIXELFORMATDESCRIPTOR pfd = {
148  sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
149  1, /* version number */
150  PFD_DRAW_TO_WINDOW | /* support window */
151  PFD_SUPPORT_OPENGL | /* support OpenGL */
152  PFD_DOUBLEBUFFER, /* double buffered */
153  PFD_TYPE_RGBA, /* RGBA type */
154  24, /* 24-bit color depth */
155  0, 0, 0, 0, 0, 0, /* color bits ignored */
156  0, /* no alpha buffer */
157  0, /* shift bit ignored */
158  0, /* no accumulation buffer */
159  0, 0, 0, 0, /* accum bits ignored */
160  32, /* 32-bit z-buffer */
161  0, /* no stencil buffer */
162  0, /* no auxiliary buffer */
163  PFD_MAIN_PLANE, /* main layer */
164  0, /* reserved */
165  0, 0, 0 /* layer masks ignored */
166  };
167  int iPixelFormat;
168 
169  rwin->displayId = CreateCompatibleDC(NULL);
170  iPixelFormat = ChoosePixelFormat(rwin->displayId, &pfd);
171  SetPixelFormat(rwin->displayId, iPixelFormat, &pfd);
172  rwin->bitmapId = CreateCompatibleBitmap(rwin->displayId, width, height);
173  SelectObject(rwin->displayId, rwin->bitmapId);
174  rwin->contextId = wglCreateContext(rwin->displayId);
175  /* TODO */
176 #endif
177  return 0;
178 }
179 
180 /*!
181  \brief Make window current for rendering
182 
183  \param win pointer to render_window struct
184 
185  \return 1 on success
186  \return 0 on failure
187  */
189 {
190 #if defined(OPENGL_X11)
191  if (!rwin->displayId || !rwin->contextId)
192  return 0;
193 
194  if (rwin->contextId == glXGetCurrentContext())
195  return 1;
196 
197  glXMakeCurrent(rwin->displayId, rwin->windowId, rwin->contextId);
198 #elif defined(OPENGL_AQUA)
199  if (!rwin->contextId)
200  return 0;
201 
202  if (rwin->contextId == aglGetCurrentContext())
203  return 1;
204 
205  aglSetCurrentContext(rwin->contextId);
206  aglSetPBuffer(rwin->contextId, rwin->windowId, 0, 0, 0);
207 #elif defined(OPENGL_WINDOWS)
208  if (!rwin->displayId || !rwin->contextId)
209  return 0;
210 
211  wglMakeCurrent(rwin->displayId, rwin->contextId);
212 #endif
213 
214  return 1;
215 }
int Nviz_make_current_render_window(const struct render_window *rwin)
Make window current for rendering.
Definition: nviz/render.c:188
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
void Nviz_destroy_render_window(struct render_window *rwin)
Free render window.
Definition: nviz/render.c:62
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
struct render_window * Nviz_new_render_window(void)
Allocate memory for render window.
Definition: nviz/render.c:24
int Nviz_create_render_window(struct render_window *rwin, void *display, int width, int height)
Create render window.
Definition: nviz/render.c:94
#define _(str)
Definition: glocale.h:13
void Nviz_init_render_window(struct render_window *rwin)
Initialize render window.
Definition: nviz/render.c:39
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:203