render.c 5.9 KB

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