You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.5KB

  1. //
  2. // Copyright (c) 2009-2013 Mikko Mononen memon@inside.org
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. // Permission is granted to anyone to use this software for any purpose,
  8. // including commercial applications, and to alter it and redistribute it
  9. // freely, subject to the following restrictions:
  10. // 1. The origin of this software must not be misrepresented; you must not
  11. // claim that you wrote the original software. If you use this software
  12. // in a product, an acknowledgment in the product documentation would be
  13. // appreciated but is not required.
  14. // 2. Altered source versions must be plainly marked as such, and must not be
  15. // misrepresented as being the original software.
  16. // 3. This notice may not be removed or altered from any source distribution.
  17. //
  18. #ifndef NANOVG_GL_UTILS_H
  19. #define NANOVG_GL_UTILS_H
  20. #include <stdio.h>
  21. struct NVGLUframebuffer {
  22. NVGcontext* ctx;
  23. GLuint fbo;
  24. GLuint rbo;
  25. GLuint texture;
  26. int image;
  27. };
  28. typedef struct NVGLUframebuffer NVGLUframebuffer;
  29. // Helper function to create GL frame buffer to render to.
  30. void nvgluBindFramebuffer(NVGLUframebuffer* fb);
  31. NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h, int imageFlags);
  32. void nvgluDeleteFramebuffer(NVGLUframebuffer* fb);
  33. #endif // NANOVG_GL_UTILS_H
  34. #ifdef NANOVG_GL_IMPLEMENTATION
  35. #if defined(NANOVG_GL3) || defined(NANOVG_GLES2) || defined(NANOVG_GLES3)
  36. // FBO is core in OpenGL 3>.
  37. # define NANOVG_FBO_VALID 1
  38. #elif defined(NANOVG_GL2)
  39. // On OS X including glext defines FBO on GL2 too.
  40. # ifdef __APPLE__
  41. # include <OpenGL/glext.h>
  42. # define NANOVG_FBO_VALID 1
  43. # endif
  44. #endif
  45. static GLint defaultFBO = -1;
  46. NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h, int imageFlags)
  47. {
  48. /* printf("xxx nvgluCreateFramebuffer: ENTER\n"); */
  49. #ifdef NANOVG_FBO_VALID
  50. GLint defaultFBO;
  51. GLint defaultRBO;
  52. NVGLUframebuffer* fb = NULL;
  53. glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
  54. glGetIntegerv(GL_RENDERBUFFER_BINDING, &defaultRBO);
  55. /* printf("xxx nvgluCreateFramebuffer: 2\n"); */
  56. fb = (NVGLUframebuffer*)malloc(sizeof(NVGLUframebuffer));
  57. if (fb == NULL) goto error;
  58. memset(fb, 0, sizeof(NVGLUframebuffer));
  59. /* printf("xxx nvgluCreateFramebuffer: 3 ctx=%p fb=%p\n", ctx, fb); */
  60. fb->image = nvgCreateImageRGBA(ctx, w, h, imageFlags | NVG_IMAGE_FLIPY | NVG_IMAGE_PREMULTIPLIED, NULL);
  61. /* printf("xxx nvgluCreateFramebuffer: 4\n"); */
  62. #if defined NANOVG_GL2
  63. fb->texture = nvglImageHandleGL2(ctx, fb->image);
  64. #elif defined NANOVG_GL3
  65. fb->texture = nvglImageHandleGL3(ctx, fb->image);
  66. #elif defined NANOVG_GLES2
  67. fb->texture = nvglImageHandleGLES2(ctx, fb->image);
  68. #elif defined NANOVG_GLES3
  69. fb->texture = nvglImageHandleGLES3(ctx, fb->image);
  70. #endif
  71. /* printf("xxx nvgluCreateFramebuffer: 5\n"); */
  72. fb->ctx = ctx;
  73. /* printf("xxx nvgluCreateFramebuffer: 5b fb->fbo=%p\n", &fb->fbo); */
  74. // frame buffer object
  75. // (note) crashes when called in DLL (!)
  76. glGenFramebuffers(1, &fb->fbo);
  77. /* printf("xxx nvgluCreateFramebuffer: 5c\n"); */
  78. glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);
  79. /* printf("xxx nvgluCreateFramebuffer: 6\n"); */
  80. // render buffer object
  81. glGenRenderbuffers(1, &fb->rbo);
  82. glBindRenderbuffer(GL_RENDERBUFFER, fb->rbo);
  83. glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, w, h);
  84. /* printf("xxx nvgluCreateFramebuffer: 7\n"); */
  85. // combine all
  86. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0);
  87. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo);
  88. /* printf("xxx nvgluCreateFramebuffer: 8\n"); */
  89. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
  90. #ifdef GL_DEPTH24_STENCIL8
  91. // If GL_STENCIL_INDEX8 is not supported, try GL_DEPTH24_STENCIL8 as a fallback.
  92. // Some graphics cards require a depth buffer along with a stencil.
  93. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
  94. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0);
  95. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo);
  96. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  97. #endif // GL_DEPTH24_STENCIL8
  98. goto error;
  99. }
  100. /* printf("xxx nvgluCreateFramebuffer: 9\n"); */
  101. glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
  102. glBindRenderbuffer(GL_RENDERBUFFER, defaultRBO);
  103. /* printf("xxx nvgluCreateFramebuffer: LEAVE\n"); */
  104. return fb;
  105. error:
  106. /* printf("xxx nvgluCreateFramebuffer: error\n"); */
  107. glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
  108. glBindRenderbuffer(GL_RENDERBUFFER, defaultRBO);
  109. nvgluDeleteFramebuffer(fb);
  110. /* printf("xxx nvgluCreateFramebuffer: error LEAVE\n"); */
  111. return NULL;
  112. #else
  113. NVG_NOTUSED(ctx);
  114. NVG_NOTUSED(w);
  115. NVG_NOTUSED(h);
  116. NVG_NOTUSED(imageFlags);
  117. return NULL;
  118. #endif
  119. }
  120. void nvgluBindFramebuffer(NVGLUframebuffer* fb)
  121. {
  122. #ifdef NANOVG_FBO_VALID
  123. if (defaultFBO == -1) glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
  124. glBindFramebuffer(GL_FRAMEBUFFER, fb != NULL ? fb->fbo : defaultFBO);
  125. #else
  126. NVG_NOTUSED(fb);
  127. #endif
  128. }
  129. void nvgluDeleteFramebuffer(NVGLUframebuffer* fb)
  130. {
  131. #ifdef NANOVG_FBO_VALID
  132. if (fb == NULL) return;
  133. if (fb->fbo != 0)
  134. glDeleteFramebuffers(1, &fb->fbo);
  135. if (fb->rbo != 0)
  136. glDeleteRenderbuffers(1, &fb->rbo);
  137. if (fb->image >= 0)
  138. nvgDeleteImage(fb->ctx, fb->image);
  139. fb->ctx = NULL;
  140. fb->fbo = 0;
  141. fb->rbo = 0;
  142. fb->texture = 0;
  143. fb->image = -1;
  144. free(fb);
  145. #else
  146. NVG_NOTUSED(fb);
  147. #endif
  148. }
  149. #endif // NANOVG_GL_IMPLEMENTATION