*/}}

nanovg_gl_utils.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. struct NVGLUframebuffer {
  21. NVGcontext* ctx;
  22. GLuint fbo;
  23. GLuint rbo;
  24. GLuint texture;
  25. int image;
  26. };
  27. typedef struct NVGLUframebuffer NVGLUframebuffer;
  28. // Helper function to create GL frame buffer to render to.
  29. void nvgluBindFramebuffer(NVGLUframebuffer* fb);
  30. NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h, int imageFlags);
  31. void nvgluDeleteFramebuffer(NVGLUframebuffer* fb);
  32. #endif // NANOVG_GL_UTILS_H
  33. #ifdef NANOVG_GL_IMPLEMENTATION
  34. #if defined(NANOVG_GL3) || defined(NANOVG_GLES2) || defined(NANOVG_GLES3)
  35. // FBO is core in OpenGL 3>.
  36. # define NANOVG_FBO_VALID 1
  37. #elif defined(NANOVG_GL2)
  38. // On OS X including glext defines FBO on GL2 too.
  39. # ifdef __APPLE__
  40. # include <OpenGL/glext.h>
  41. # define NANOVG_FBO_VALID 1
  42. # endif
  43. #endif
  44. static GLint defaultFBO = -1;
  45. NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h, int imageFlags)
  46. {
  47. #ifdef NANOVG_FBO_VALID
  48. GLint defaultFBO;
  49. GLint defaultRBO;
  50. NVGLUframebuffer* fb = NULL;
  51. glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
  52. glGetIntegerv(GL_RENDERBUFFER_BINDING, &defaultRBO);
  53. fb = (NVGLUframebuffer*)malloc(sizeof(NVGLUframebuffer));
  54. if (fb == NULL) goto error;
  55. memset(fb, 0, sizeof(NVGLUframebuffer));
  56. fb->image = nvgCreateImageRGBA(ctx, w, h, imageFlags | NVG_IMAGE_FLIPY | NVG_IMAGE_PREMULTIPLIED, NULL);
  57. #if defined NANOVG_GL2
  58. fb->texture = nvglImageHandleGL2(ctx, fb->image);
  59. #elif defined NANOVG_GL3
  60. fb->texture = nvglImageHandleGL3(ctx, fb->image);
  61. #elif defined NANOVG_GLES2
  62. fb->texture = nvglImageHandleGLES2(ctx, fb->image);
  63. #elif defined NANOVG_GLES3
  64. fb->texture = nvglImageHandleGLES3(ctx, fb->image);
  65. #endif
  66. fb->ctx = ctx;
  67. // frame buffer object
  68. glGenFramebuffers(1, &fb->fbo);
  69. glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);
  70. // render buffer object
  71. glGenRenderbuffers(1, &fb->rbo);
  72. glBindRenderbuffer(GL_RENDERBUFFER, fb->rbo);
  73. glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, w, h);
  74. // combine all
  75. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0);
  76. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo);
  77. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
  78. #ifdef GL_DEPTH24_STENCIL8
  79. // If GL_STENCIL_INDEX8 is not supported, try GL_DEPTH24_STENCIL8 as a fallback.
  80. // Some graphics cards require a depth buffer along with a stencil.
  81. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
  82. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0);
  83. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo);
  84. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  85. #endif // GL_DEPTH24_STENCIL8
  86. goto error;
  87. }
  88. glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
  89. glBindRenderbuffer(GL_RENDERBUFFER, defaultRBO);
  90. return fb;
  91. error:
  92. glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
  93. glBindRenderbuffer(GL_RENDERBUFFER, defaultRBO);
  94. nvgluDeleteFramebuffer(fb);
  95. return NULL;
  96. #else
  97. NVG_NOTUSED(ctx);
  98. NVG_NOTUSED(w);
  99. NVG_NOTUSED(h);
  100. NVG_NOTUSED(imageFlags);
  101. return NULL;
  102. #endif
  103. }
  104. void nvgluBindFramebuffer(NVGLUframebuffer* fb)
  105. {
  106. #ifdef NANOVG_FBO_VALID
  107. if (defaultFBO == -1) glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
  108. glBindFramebuffer(GL_FRAMEBUFFER, fb != NULL ? fb->fbo : defaultFBO);
  109. #else
  110. NVG_NOTUSED(fb);
  111. #endif
  112. }
  113. void nvgluDeleteFramebuffer(NVGLUframebuffer* fb)
  114. {
  115. #ifdef NANOVG_FBO_VALID
  116. if (fb == NULL) return;
  117. if (fb->fbo != 0)
  118. glDeleteFramebuffers(1, &fb->fbo);
  119. if (fb->rbo != 0)
  120. glDeleteRenderbuffers(1, &fb->rbo);
  121. if (fb->image >= 0)
  122. nvgDeleteImage(fb->ctx, fb->image);
  123. fb->ctx = NULL;
  124. fb->fbo = 0;
  125. fb->rbo = 0;
  126. fb->texture = 0;
  127. fb->image = -1;
  128. free(fb);
  129. #else
  130. NVG_NOTUSED(fb);
  131. #endif
  132. }
  133. #endif // NANOVG_GL_IMPLEMENTATION