diff --git a/example/example_gl2.c b/example/example_gl2.c index 7500255..0d50dc3 100644 --- a/example/example_gl2.c +++ b/example/example_gl2.c @@ -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(); diff --git a/example/example_gl3.c b/example/example_gl3.c index c5cbe7e..2c1f932 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -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); diff --git a/example/example_gles2.c b/example/example_gles2.c index df2b2c6..5072c88 100644 --- a/example/example_gles2.c +++ b/example/example_gles2.c @@ -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" diff --git a/example/example_gles3.c b/example/example_gles3.c index bd0d54c..754eb2e 100644 --- a/example/example_gles3.c +++ b/example/example_gles3.c @@ -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" diff --git a/src/nanovg_gl.h b/src/nanovg_gl.h index 0f9e2de..fc8905c 100644 --- a/src/nanovg_gl.h +++ b/src/nanovg_gl.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); diff --git a/src/nanovg_gl_utils.h b/src/nanovg_gl_utils.h index e2b6b5f..8368d74 100644 --- a/src/nanovg_gl_utils.h +++ b/src/nanovg_gl_utils.h @@ -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