- fixed flags setup in nvglCreateImageFromHandle - changed frame buffer to only compile on GL3 - changed nvgluCreateFramebuffer() to return FBO struct instead of filling existing one (for consistency)shared-context
| @@ -57,10 +57,8 @@ int main() | |||
| GLFWwindow* window; | |||
| struct DemoData data; | |||
| struct NVGcontext* vg = NULL; | |||
| struct NVGLUframebuffer fb; | |||
| struct PerfGraph fps; | |||
| double prevt = 0; | |||
| int hasFBO; | |||
| if (!glfwInit()) { | |||
| printf("Failed to init GLFW."); | |||
| @@ -112,8 +110,6 @@ int main() | |||
| glfwSetTime(0); | |||
| prevt = glfwGetTime(); | |||
| hasFBO = nvgluCreateFramebuffer(vg, &fb, 600, 600); | |||
| while (!glfwWindowShouldClose(window)) | |||
| { | |||
| double mx, my, t, dt; | |||
| @@ -121,20 +117,6 @@ int main() | |||
| int fbWidth, fbHeight; | |||
| float pxRatio; | |||
| if (hasFBO) { | |||
| int fboWidth, fboHeight; | |||
| nvgImageSize(vg, fb.image, &fboWidth, &fboHeight); | |||
| // Draw some stull to an FBO as a test | |||
| glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo); | |||
| glViewport(0, 0, fboWidth, fboHeight); | |||
| glClearColor(0, 0, 0, 0); | |||
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | |||
| nvgBeginFrame(vg, fboWidth, fboHeight, pxRatio, NVG_PREMULTIPLIED_ALPHA); | |||
| renderDemo(vg, mx, my, fboWidth, fboHeight, t, blowup, &data); | |||
| nvgEndFrame(vg); | |||
| glBindFramebuffer(GL_FRAMEBUFFER, 0); | |||
| } | |||
| t = glfwGetTime(); | |||
| dt = t - prevt; | |||
| prevt = t; | |||
| @@ -160,15 +142,6 @@ int main() | |||
| renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||
| renderGraph(vg, 5,5, &fps); | |||
| if (hasFBO) { | |||
| struct NVGpaint img = nvgImagePattern(vg, 0, 0, 150, 150, 0, fb.image, 0); | |||
| nvgBeginPath(vg); | |||
| nvgTranslate(vg, 540, 300); | |||
| nvgRect(vg, 0, 0, 150, 150); | |||
| nvgFillPaint(vg, img); | |||
| nvgFill(vg); | |||
| } | |||
| nvgEndFrame(vg); | |||
| if (screenshot) { | |||
| @@ -182,7 +155,6 @@ int main() | |||
| freeDemoData(vg, &data); | |||
| nvgluDeleteFramebuffer(vg, &fb); | |||
| nvgDeleteGL2(vg); | |||
| glfwTerminate(); | |||
| @@ -27,6 +27,7 @@ | |||
| #include "nanovg.h" | |||
| #define NANOVG_GL3_IMPLEMENTATION | |||
| #include "nanovg_gl.h" | |||
| #include "nanovg_gl_utils.h" | |||
| #include "demo.h" | |||
| #include "perf.h" | |||
| @@ -61,6 +62,7 @@ int main() | |||
| struct GPUtimer gpuTimer; | |||
| struct PerfGraph fps, cpuGraph, gpuGraph; | |||
| double prevt = 0, cpuTime = 0; | |||
| struct NVGLUframebuffer* fb = NULL; | |||
| if (!glfwInit()) { | |||
| printf("Failed to init GLFW."); | |||
| @@ -122,6 +124,8 @@ int main() | |||
| glfwSetTime(0); | |||
| prevt = glfwGetTime(); | |||
| fb = nvgluCreateFramebuffer(vg, 600, 600); | |||
| while (!glfwWindowShouldClose(window)) | |||
| { | |||
| double mx, my, t, dt; | |||
| @@ -143,6 +147,20 @@ int main() | |||
| // Calculate pixel ration for hi-dpi devices. | |||
| pxRatio = (float)fbWidth / (float)winWidth; | |||
| if (fb != NULL) { | |||
| int fboWidth, fboHeight; | |||
| nvgImageSize(vg, fb->image, &fboWidth, &fboHeight); | |||
| // Draw some stull to an FBO as a test | |||
| nvgluBindFramebuffer(fb); | |||
| glViewport(0, 0, fboWidth, fboHeight); | |||
| glClearColor(0, 0, 0, 0); | |||
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | |||
| nvgBeginFrame(vg, fboWidth, fboHeight, pxRatio, NVG_PREMULTIPLIED_ALPHA); | |||
| renderDemo(vg, mx, my, fboWidth, fboHeight, t, blowup, &data); | |||
| nvgEndFrame(vg); | |||
| nvgluBindFramebuffer(NULL); | |||
| } | |||
| // Update and render | |||
| glViewport(0, 0, fbWidth, fbHeight); | |||
| if (premult) | |||
| @@ -160,6 +178,15 @@ int main() | |||
| if (gpuTimer.supported) | |||
| renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); | |||
| if (fb != NULL) { | |||
| struct NVGpaint img = nvgImagePattern(vg, 0, 0, 150, 150, 0, fb->image, 0); | |||
| nvgBeginPath(vg); | |||
| nvgTranslate(vg, 540, 300); | |||
| nvgRect(vg, 0, 0, 150, 150); | |||
| nvgFillPaint(vg, img); | |||
| nvgFill(vg); | |||
| } | |||
| nvgEndFrame(vg); | |||
| // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) | |||
| @@ -184,6 +211,8 @@ int main() | |||
| freeDemoData(vg, &data); | |||
| nvgluDeleteFramebuffer(vg, fb); | |||
| nvgDeleteGL3(vg); | |||
| printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f); | |||
| @@ -22,6 +22,7 @@ | |||
| #include "nanovg.h" | |||
| #define NANOVG_GLES2_IMPLEMENTATION | |||
| #include "nanovg_gl.h" | |||
| #include "nanovg_gl_utils.h" | |||
| #include "demo.h" | |||
| #include "perf.h" | |||
| @@ -22,6 +22,7 @@ | |||
| #include "nanovg.h" | |||
| #define NANOVG_GLES3_IMPLEMENTATION | |||
| #include "nanovg_gl.h" | |||
| #include "nanovg_gl_utils.h" | |||
| #include "demo.h" | |||
| #include "perf.h" | |||
| @@ -1324,7 +1324,7 @@ int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int flag | |||
| tex->tex = textureId; | |||
| tex->type = NVG_TEXTURE_RGBA; | |||
| tex->flags = 0; | |||
| tex->flags = flags; | |||
| glBindTexture(GL_TEXTURE_2D, tex->tex); | |||
| glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex->width); | |||
| glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex->height); | |||
| @@ -1,49 +1,91 @@ | |||
| #ifndef gl_utils_h | |||
| #define gl_utils_h | |||
| // | |||
| // Copyright (c) 2009-2013 Mikko Mononen memon@inside.org | |||
| // | |||
| // This software is provided 'as-is', without any express or implied | |||
| // warranty. In no event will the authors be held liable for any damages | |||
| // arising from the use of this software. | |||
| // Permission is granted to anyone to use this software for any purpose, | |||
| // including commercial applications, and to alter it and redistribute it | |||
| // freely, subject to the following restrictions: | |||
| // 1. The origin of this software must not be misrepresented; you must not | |||
| // claim that you wrote the original software. If you use this software | |||
| // in a product, an acknowledgment in the product documentation would be | |||
| // appreciated but is not required. | |||
| // 2. Altered source versions must be plainly marked as such, and must not be | |||
| // misrepresented as being the original software. | |||
| // 3. This notice may not be removed or altered from any source distribution. | |||
| // | |||
| #ifndef NANOVG_GL_UTILS_H | |||
| #define NANOVG_GL_UTILS_H | |||
| struct NVGLUframebuffer { | |||
| struct NVGcontext* ctx; | |||
| GLuint fbo; | |||
| GLuint rbo; | |||
| GLuint texture; | |||
| int image; | |||
| struct NVGcontext* ctx; | |||
| GLuint fbo; | |||
| GLuint rbo; | |||
| GLuint texture; | |||
| int image; | |||
| }; | |||
| int nvgluCreateFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb, int w, int h); | |||
| // Helper function to create GL frame buffer to render to. | |||
| struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, int h); | |||
| void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb); | |||
| #endif /* gl_utils_h */ | |||
| #endif // NANOVG_GL_UTILS_H | |||
| #ifdef NANOVG_GL_IMPLEMENTATION | |||
| int nvgluCreateFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb, int w, int h) { | |||
| struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, int h) | |||
| { | |||
| #ifdef NANOVG_GL3 | |||
| struct NVGLUframebuffer* fb = NULL; | |||
| fb = (struct NVGLUframebuffer*)malloc(sizeof(struct NVGLUframebuffer)); | |||
| if (fb == NULL) goto error; | |||
| memset(fb, 0, sizeof(struct NVGLUframebuffer)); | |||
| fb->image = nvgCreateImageRGBA(ctx, w, h, NULL); | |||
| fb->texture = nvglImageHandle(ctx, fb->image); | |||
| nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y); | |||
| /* frame buffer object */ | |||
| // frame buffer object | |||
| glGenFramebuffers(1, &fb->fbo); | |||
| glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo); | |||
| /* render buffer object */ | |||
| // render buffer object | |||
| glGenRenderbuffers(1, &fb->rbo); | |||
| glBindRenderbuffer(GL_RENDERBUFFER, fb->rbo); | |||
| glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); | |||
| /* combine all */ | |||
| // combine all | |||
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0); | |||
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo); | |||
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | |||
| nvgluDeleteFramebuffer(ctx, fb); | |||
| return 0; | |||
| } | |||
| return 1; | |||
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) goto error; | |||
| return fb; | |||
| error: | |||
| nvgluDeleteFramebuffer(ctx, fb); | |||
| return NULL; | |||
| #else | |||
| NVG_NOTUSED(ctx); | |||
| NVG_NOTUSED(w); | |||
| NVG_NOTUSED(h); | |||
| return NULL; | |||
| #endif | |||
| } | |||
| void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb) { | |||
| void nvgluBindFramebuffer(struct NVGLUframebuffer* fb) | |||
| { | |||
| #ifdef NANOVG_GL3 | |||
| glBindFramebuffer(GL_FRAMEBUFFER, fb != NULL ? fb->fbo : 0); | |||
| #else | |||
| NVG_NOTUSED(fb); | |||
| #endif | |||
| } | |||
| void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb) | |||
| { | |||
| #ifdef NANOVG_GL3 | |||
| if (fb == NULL) return; | |||
| if (fb->fbo != 0) | |||
| glDeleteFramebuffers(1, &fb->fbo); | |||
| if (fb->rbo != 0) | |||
| @@ -54,8 +96,11 @@ void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb) | |||
| fb->rbo = 0; | |||
| fb->texture = 0; | |||
| fb->image = -1; | |||
| free(fb); | |||
| #else | |||
| NVG_NOTUSED(ctx); | |||
| NVG_NOTUSED(fb); | |||
| #endif | |||
| } | |||
| #endif /* NANOVG_GL_IMPLEMENTATION */ | |||
| /* vim: set ft=c nu noet ts=4 sw=4 : */ | |||
| #endif // NANOVG_GL_IMPLEMENTATION | |||