16 #include <grass/glocale.h>
17 #include <grass/nviz.h>
19 #if defined(OPENGL_WINDOWS) && defined(OPENGL_FBO)
20 static int gl_funcs_found = 0;
21 static PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
22 static PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
23 static PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
24 static PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
25 static PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
26 static PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
27 static PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
30 static void *GetAnyGLFuncAddress(
const char *
name)
32 void *p = (
void *)wglGetProcAddress(
name);
33 if (p == 0 || p == (
void*)0x1 || p == (
void*)0x2 || p == (
void*)0x3 ||
35 HMODULE module = LoadLibraryA(
"opengl32.dll");
36 p = (
void *)GetProcAddress(module,
name);
43 static void find_gl_funcs()
48 glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)GetAnyGLFuncAddress(
"glGenFramebuffers");
49 glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)GetAnyGLFuncAddress(
"glBindFramebuffer");
50 glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)GetAnyGLFuncAddress(
"glGenRenderbuffers");
51 glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)GetAnyGLFuncAddress(
"glBindRenderbuffer");
52 glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)GetAnyGLFuncAddress(
"glRenderbufferStorage");
53 glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)GetAnyGLFuncAddress(
"glFramebufferRenderbuffer");
54 glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)GetAnyGLFuncAddress(
"glCheckFramebufferStatus");
68 struct render_window *rwin;
71 rwin = (
struct render_window *)G_malloc(
sizeof(
struct render_window));
83 #if defined(OPENGL_X11)
84 rwin->displayId =
NULL;
85 rwin->contextId =
NULL;
88 #elif defined(OPENGL_AQUA)
89 #if defined(OPENGL_AGL)
90 rwin->pixelFmtId =
NULL;
91 rwin->contextId =
NULL;
92 rwin->windowId =
NULL;
94 rwin->contextId =
NULL;
96 #elif defined(OPENGL_WINDOWS)
97 rwin->displayId =
NULL;
98 rwin->contextId =
NULL;
112 #if defined(OPENGL_X11)
113 glXDestroyGLXPixmap(rwin->displayId, rwin->windowId);
114 XFreePixmap(rwin->displayId, rwin->pixmap);
115 glXDestroyContext(rwin->displayId, rwin->contextId);
116 XCloseDisplay(rwin->displayId);
117 #elif defined(OPENGL_AQUA)
118 #if defined(OPENGL_AGL)
119 aglDestroyPixelFormat(rwin->pixelFmtId);
120 aglDestroyContext(rwin->contextId);
121 aglDestroyPBuffer(rwin->windowId);
123 CGLDestroyContext(rwin->contextId);
125 #elif defined(OPENGL_WINDOWS)
126 wglDeleteContext(rwin->contextId);
127 DeleteDC(rwin->displayId);
145 int width,
int height)
147 #if defined(OPENGL_X11)
148 int attributeList[] = {
154 #if !defined(OPENGL_FBO)
161 rwin->displayId = XOpenDisplay((
char *)display);
162 if (!rwin->displayId) {
166 v = glXChooseVisual(rwin->displayId,
167 DefaultScreen(rwin->displayId), attributeList);
169 G_warning(_(
"Unable to get visual info"));
173 rwin->contextId = glXCreateContext(rwin->displayId, v,
NULL, GL_TRUE);
175 if (!rwin->contextId) {
176 G_warning(_(
"Unable to create rendering context"));
181 rwin->pixmap = XCreatePixmap(rwin->displayId,
182 RootWindow(rwin->displayId, v->screen),
183 width, height, v->depth);
186 rwin->windowId = glXCreateGLXPixmap(rwin->displayId, v, rwin->pixmap);
189 #elif defined(OPENGL_AQUA)
190 #if defined(OPENGL_AGL)
191 int attributeList[] = {
197 #if !defined(OPENGL_FBO)
206 rwin->pixelFmtId = aglChoosePixelFormat(
NULL, 0, attributeList);
208 rwin->contextId = aglCreateContext(rwin->pixelFmtId,
NULL);
211 aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &(rwin->windowId));
212 aglSetPBuffer(rwin->contextId, rwin->windowId, 0, 0, 0);
214 CGLPixelFormatAttribute attributeList[] = {
215 kCGLPFAColorSize, 24,
216 kCGLPFADepthSize, 32,
217 (CGLPixelFormatAttribute) 0
219 CGLPixelFormatObj pix;
223 error = CGLChoosePixelFormat(attributeList, &pix, &nvirt);
225 G_warning(_(
"Unable to choose pixel format (CGL error = %d)"), error);
229 error = CGLCreateContext(pix,
NULL, &rwin->contextId);
231 G_warning(_(
"Unable to create context (CGL error = %d)"), error);
235 CGLDestroyPixelFormat(pix);
237 #elif defined(OPENGL_WINDOWS)
240 PIXELFORMATDESCRIPTOR pfd = {
241 sizeof(PIXELFORMATDESCRIPTOR),
262 wc.lpfnWndProc = DefWindowProc;
263 wc.lpszClassName =
"nviz";
265 if (!RegisterClass(&wc)) {
266 G_warning(_(
"Unable to register window class"));
270 hWnd = CreateWindow(wc.lpszClassName, wc.lpszClassName, WS_POPUP,
271 CW_USEDEFAULT, CW_USEDEFAULT, width, height,
279 rwin->displayId = GetDC(hWnd);
280 iPixelFormat = ChoosePixelFormat(rwin->displayId, &pfd);
281 SetPixelFormat(rwin->displayId, iPixelFormat, &pfd);
282 rwin->contextId = wglCreateContext(rwin->displayId);
286 rwin->height = height;
301 #if defined(OPENGL_X11)
302 if (!rwin->displayId || !rwin->contextId)
305 if (rwin->contextId == glXGetCurrentContext())
308 glXMakeCurrent(rwin->displayId, rwin->windowId, rwin->contextId);
309 #elif defined(OPENGL_AQUA)
310 #if defined(OPENGL_AGL)
311 if (!rwin->contextId)
314 if (rwin->contextId == aglGetCurrentContext())
317 aglSetCurrentContext(rwin->contextId);
321 error = CGLSetCurrentContext(rwin->contextId);
323 G_warning(_(
"Unable to set current context (CGL error = %d)"), error);
327 #elif defined(OPENGL_WINDOWS)
328 if (!rwin->displayId || !rwin->contextId)
331 wglMakeCurrent(rwin->displayId, rwin->contextId);
334 #if defined(OPENGL_FBO)
335 #if defined(OPENGL_WINDOWS)
339 GLuint framebuf, renderbuf, depthbuf;
342 glGenFramebuffers(1, &framebuf);
343 glBindFramebuffer(GL_FRAMEBUFFER, framebuf);
345 glGenRenderbuffers(1, &renderbuf);
346 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
347 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
348 rwin->width, rwin->height);
349 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
350 GL_RENDERBUFFER, renderbuf);
352 glGenRenderbuffers(1, &depthbuf);
353 glBindRenderbuffer(GL_RENDERBUFFER, depthbuf);
354 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
355 rwin->width, rwin->height);
356 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
357 GL_RENDERBUFFER, depthbuf);
359 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
360 if (status != GL_FRAMEBUFFER_COMPLETE) {
361 G_warning(_(
"Incomplete framebuffer status (status = %d)"), status);
366 glViewport(0, 0, rwin->width, rwin->height);