18 #include <grass/glocale.h>
19 #include <grass/nviz.h>
21 #if defined(OPENGL_WINDOWS) && defined(OPENGL_FBO)
22 static int gl_funcs_found = 0;
23 static PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
24 static PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
25 static PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
26 static PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
27 static PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
28 static PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
29 static PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
32 static void *GetAnyGLFuncAddress(
const char *
name)
34 void *p = (
void *)wglGetProcAddress(
name);
36 if (p == 0 || p == (
void *)0x1 || p == (
void *)0x2 || p == (
void *)0x3 ||
38 HMODULE module = LoadLibraryA(
"opengl32.dll");
40 p = (
void *)GetProcAddress(module,
name);
47 static void find_gl_funcs()
53 (PFNGLGENFRAMEBUFFERSPROC)GetAnyGLFuncAddress(
"glGenFramebuffers");
55 (PFNGLBINDFRAMEBUFFERPROC)GetAnyGLFuncAddress(
"glBindFramebuffer");
57 (PFNGLGENRENDERBUFFERSPROC)GetAnyGLFuncAddress(
"glGenRenderbuffers");
59 (PFNGLBINDRENDERBUFFERPROC)GetAnyGLFuncAddress(
"glBindRenderbuffer");
60 glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)GetAnyGLFuncAddress(
61 "glRenderbufferStorage");
62 glFramebufferRenderbuffer =
63 (PFNGLFRAMEBUFFERRENDERBUFFERPROC)GetAnyGLFuncAddress(
64 "glFramebufferRenderbuffer");
65 glCheckFramebufferStatus =
66 (PFNGLCHECKFRAMEBUFFERSTATUSPROC)GetAnyGLFuncAddress(
67 "glCheckFramebufferStatus");
81 struct render_window *rwin;
84 rwin = (
struct render_window *)G_malloc(
sizeof(
struct render_window));
96 #if defined(OPENGL_X11)
97 rwin->displayId =
NULL;
98 rwin->contextId =
NULL;
101 #elif defined(OPENGL_AQUA)
102 #if defined(OPENGL_AGL)
103 rwin->pixelFmtId =
NULL;
104 rwin->contextId =
NULL;
105 rwin->windowId =
NULL;
107 rwin->contextId =
NULL;
109 #elif defined(OPENGL_WINDOWS)
110 rwin->displayId =
NULL;
111 rwin->contextId =
NULL;
125 #if defined(OPENGL_X11)
126 glXDestroyGLXPixmap(rwin->displayId, rwin->windowId);
127 XFreePixmap(rwin->displayId, rwin->pixmap);
128 glXDestroyContext(rwin->displayId, rwin->contextId);
129 XCloseDisplay(rwin->displayId);
130 #elif defined(OPENGL_AQUA)
131 #if defined(OPENGL_AGL)
132 aglDestroyPixelFormat(rwin->pixelFmtId);
133 aglDestroyContext(rwin->contextId);
134 aglDestroyPBuffer(rwin->windowId);
136 CGLDestroyContext(rwin->contextId);
138 #elif defined(OPENGL_WINDOWS)
139 wglDeleteContext(rwin->contextId);
140 DeleteDC(rwin->displayId);
158 int width,
int height)
160 #if defined(OPENGL_X11)
161 int attributeList[] = {GLX_RGBA,
170 #if !defined(OPENGL_FBO)
176 rwin->displayId = XOpenDisplay((
char *)display);
177 if (!rwin->displayId) {
181 v = glXChooseVisual(rwin->displayId, DefaultScreen(rwin->displayId),
184 G_warning(_(
"Unable to get visual info"));
188 rwin->contextId = glXCreateContext(rwin->displayId, v,
NULL, GL_TRUE);
190 if (!rwin->contextId) {
191 G_warning(_(
"Unable to create rendering context"));
197 XCreatePixmap(rwin->displayId, RootWindow(rwin->displayId, v->screen),
198 width, height, v->depth);
201 rwin->windowId = glXCreateGLXPixmap(rwin->displayId, v, rwin->pixmap);
204 #elif defined(OPENGL_AQUA)
205 #if defined(OPENGL_AGL)
206 int attributeList[] = {AGL_RGBA,
215 #if !defined(OPENGL_FBO)
223 rwin->pixelFmtId = aglChoosePixelFormat(
NULL, 0, attributeList);
225 rwin->contextId = aglCreateContext(rwin->pixelFmtId,
NULL);
228 aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0,
230 aglSetPBuffer(rwin->contextId, rwin->windowId, 0, 0, 0);
232 CGLPixelFormatAttribute attributeList[] = {
233 kCGLPFAColorSize, 24, kCGLPFADepthSize, 32, (CGLPixelFormatAttribute)0};
234 CGLPixelFormatObj pix;
238 error = CGLChoosePixelFormat(attributeList, &pix, &nvirt);
240 G_warning(_(
"Unable to choose pixel format (CGL error = %d)"), error);
244 error = CGLCreateContext(pix,
NULL, &rwin->contextId);
246 G_warning(_(
"Unable to create context (CGL error = %d)"), error);
250 CGLDestroyPixelFormat(pix);
252 #elif defined(OPENGL_WINDOWS)
256 PIXELFORMATDESCRIPTOR pfd = {
257 sizeof(PIXELFORMATDESCRIPTOR),
288 wc.lpfnWndProc = DefWindowProc;
289 wc.lpszClassName =
"nviz";
291 if (!RegisterClass(&wc)) {
292 G_warning(_(
"Unable to register window class"));
296 hWnd = CreateWindow(wc.lpszClassName, wc.lpszClassName, WS_POPUP,
297 CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL,
NULL,
305 rwin->displayId = GetDC(hWnd);
306 iPixelFormat = ChoosePixelFormat(rwin->displayId, &pfd);
307 SetPixelFormat(rwin->displayId, iPixelFormat, &pfd);
308 rwin->contextId = wglCreateContext(rwin->displayId);
312 rwin->height = height;
327 #if defined(OPENGL_X11)
328 if (!rwin->displayId || !rwin->contextId)
331 if (rwin->contextId == glXGetCurrentContext())
334 glXMakeCurrent(rwin->displayId, rwin->windowId, rwin->contextId);
335 #elif defined(OPENGL_AQUA)
336 #if defined(OPENGL_AGL)
337 if (!rwin->contextId)
340 if (rwin->contextId == aglGetCurrentContext())
343 aglSetCurrentContext(rwin->contextId);
347 error = CGLSetCurrentContext(rwin->contextId);
349 G_warning(_(
"Unable to set current context (CGL error = %d)"), error);
353 #elif defined(OPENGL_WINDOWS)
354 if (!rwin->displayId || !rwin->contextId)
357 wglMakeCurrent(rwin->displayId, rwin->contextId);
360 #if defined(OPENGL_FBO)
361 #if defined(OPENGL_WINDOWS)
365 GLuint framebuf, renderbuf, depthbuf;
368 glGenFramebuffers(1, &framebuf);
369 glBindFramebuffer(GL_FRAMEBUFFER, framebuf);
371 glGenRenderbuffers(1, &renderbuf);
372 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
373 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rwin->width, rwin->height);
374 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
375 GL_RENDERBUFFER, renderbuf);
377 glGenRenderbuffers(1, &depthbuf);
378 glBindRenderbuffer(GL_RENDERBUFFER, depthbuf);
379 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rwin->width,
381 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
382 GL_RENDERBUFFER, depthbuf);
384 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
385 if (status != GL_FRAMEBUFFER_COMPLETE) {
386 G_warning(_(
"Incomplete framebuffer status (status = %d)"), status);
391 glViewport(0, 0, rwin->width, rwin->height);
void G_free(void *buf)
Free allocated memory.
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
void G_warning(const char *msg,...)
Print a warning message to stderr.
struct render_window * Nviz_new_render_window(void)
Allocate memory for render window.
void Nviz_destroy_render_window(struct render_window *rwin)
Free render window.
void Nviz_init_render_window(struct render_window *rwin)
Initialize render window.
int Nviz_create_render_window(struct render_window *rwin, void *display, int width, int height)
Create render window.
int Nviz_make_current_render_window(const struct render_window *rwin)
Make window current for rendering.