123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*!
- \file lib/nviz/render.c
- \brief Nviz library -- GLX context manipulation
- Based on visualization/nviz/src/togl.c
-
- (C) 2008, 2010 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
- */
- #include <grass/glocale.h>
- #include <grass/nviz.h>
- /*!
- \brief Allocate memory for render window
- \return pointer to render_window struct
- \return NULL on failure
- */
- struct render_window *Nviz_new_render_window(void)
- {
- struct render_window *rwin;
- /* G_malloc() calls G_fatal_error() on failure */
- rwin = (struct render_window *)G_malloc(sizeof(struct render_window));
- return rwin;
- }
- /*!
- \brief Initialize render window
- \param win pointer to render_window struct
- */
- void Nviz_init_render_window(struct render_window *rwin)
- {
- #if defined(OPENGL_X11)
- rwin->displayId = NULL;
- rwin->contextId = NULL;
- rwin->pixmap = 0;
- rwin->windowId = 0;
- #elif defined(OPENGL_AQUA)
- rwin->pixelFmtId = NULL;
- rwin->contextId = NULL;
- rwin->windowId = NULL;
- #elif defined(OPENGL_WINDOWS)
- rwin->displayId = NULL;
- rwin->contextId = NULL;
- rwin->bitmapId = NULL;
- #endif
- }
- /*!
- \brief Free render window
- \param win pointer to render_window struct
- */
- void Nviz_destroy_render_window(struct render_window *rwin)
- {
- #if defined(OPENGL_X11)
- glXDestroyGLXPixmap(rwin->displayId, rwin->windowId);
- XFreePixmap(rwin->displayId, rwin->pixmap);
- glXDestroyContext(rwin->displayId, rwin->contextId);
- XCloseDisplay(rwin->displayId);
- #elif defined(OPENGL_AQUA)
- aglDestroyPixelFormat(rwin->pixelFmtId);
- aglDestroyContext(rwin->contextId);
- aglDestroyPBuffer(rwin->windowId);
- /* TODO FreePixMap */
- #elif defined(OPENGL_WINDOWS)
- wglDeleteContext(rwin->contextId);
- DeleteDC(rwin->displayId);
- DeleteObject(rwin->bitmapId);
- #endif
- G_free((void *)rwin);
- }
- /*!
- \brief Create render window
- \param rwin pointer to render_window struct
- \param display display instance (NULL for offscreen)
- \param width window width
- \param height window height
- \return 0 on success
- \return -1 on error
- */
- int Nviz_create_render_window(struct render_window *rwin, void *display,
- int width, int height)
- {
- #if defined(OPENGL_X11)
- int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
- GLX_DEPTH_SIZE, 1, None
- };
- XVisualInfo *v;
- rwin->displayId = XOpenDisplay((char *)display);
- if (!rwin->displayId) {
- G_fatal_error(_("Bad server connection"));
- }
- v = glXChooseVisual(rwin->displayId,
- DefaultScreen(rwin->displayId), attributeList);
- if (!v) {
- G_warning(_("Unable to get visual info"));
- return -1;
- }
-
- rwin->contextId = glXCreateContext(rwin->displayId, v, NULL, GL_FALSE);
- if (!rwin->contextId) {
- G_warning(_("Unable to create rendering context"));
- return -1;
- }
- /* create win pixmap to render to (same depth as RootWindow) */
- rwin->pixmap = XCreatePixmap(rwin->displayId,
- RootWindow(rwin->displayId, v->screen),
- width, height, v->depth);
- /* create an off-screen GLX rendering area */
- rwin->windowId = glXCreateGLXPixmap(rwin->displayId, v, rwin->pixmap);
- XFree(v);
- #elif defined(OPENGL_AQUA)
- int attributeList[] = { AGL_RGBA, AGL_RED_SIZE, 1,
- AGL_GREEN_SIZE, 1, AGL_BLUE_SIZE, 1,
- AGL_DEPTH_SIZE, 1, AGL_NONE
- };
- /* TODO: open mac display */
- /* TODO: dev = NULL, ndev = 0 ? */
- rwin->pixelFmtId = aglChoosePixelFormat(NULL, 0, attributeList);
- rwin->contextId = aglCreateContext(rwin->pixelFmtId, NULL);
- /* create an off-screen AGL rendering area */
- aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &(rwin->windowId));
- #elif defined(OPENGL_WINDOWS)
- PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
- 1, /* version number */
- PFD_DRAW_TO_WINDOW | /* support window */
- PFD_SUPPORT_OPENGL | /* support OpenGL */
- PFD_DOUBLEBUFFER, /* double buffered */
- PFD_TYPE_RGBA, /* RGBA type */
- 24, /* 24-bit color depth */
- 0, 0, 0, 0, 0, 0, /* color bits ignored */
- 0, /* no alpha buffer */
- 0, /* shift bit ignored */
- 0, /* no accumulation buffer */
- 0, 0, 0, 0, /* accum bits ignored */
- 32, /* 32-bit z-buffer */
- 0, /* no stencil buffer */
- 0, /* no auxiliary buffer */
- PFD_MAIN_PLANE, /* main layer */
- 0, /* reserved */
- 0, 0, 0 /* layer masks ignored */
- };
- int iPixelFormat;
- rwin->displayId = CreateCompatibleDC(NULL);
- iPixelFormat = ChoosePixelFormat(rwin->displayId, &pfd);
- SetPixelFormat(rwin->displayId, iPixelFormat, &pfd);
- rwin->bitmapId = CreateCompatibleBitmap(rwin->displayId, width, height);
- SelectObject(rwin->displayId, rwin->bitmapId);
- rwin->contextId = wglCreateContext(rwin->displayId);
- /* TODO */
- #endif
- return 0;
- }
- /*!
- \brief Make window current for rendering
- \param win pointer to render_window struct
- \return 1 on success
- \return 0 on failure
- */
- int Nviz_make_current_render_window(const struct render_window *rwin)
- {
- #if defined(OPENGL_X11)
- if (!rwin->displayId || !rwin->contextId)
- return 0;
- if (rwin->contextId == glXGetCurrentContext())
- return 1;
- glXMakeCurrent(rwin->displayId, rwin->windowId, rwin->contextId);
- #elif defined(OPENGL_AQUA)
- if (!rwin->contextId)
- return 0;
- if (rwin->contextId == aglGetCurrentContext())
- return 1;
- aglSetCurrentContext(rwin->contextId);
- aglSetPBuffer(rwin->contextId, rwin->windowId, 0, 0, 0);
- #elif defined(OPENGL_WINDOWS)
- if (!rwin->displayId || !rwin->contextId)
- return 0;
- wglMakeCurrent(rwin->displayId, rwin->contextId);
- #endif
- return 1;
- }
|