Browse Source

Fixes and tweaks for frame buffer handling

- 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
Mikko Mononen 11 years ago
parent
commit
7a06c56edb
6 changed files with 101 additions and 53 deletions
  1. +0
    -28
      example/example_gl2.c
  2. +29
    -0
      example/example_gl3.c
  3. +1
    -0
      example/example_gles2.c
  4. +1
    -0
      example/example_gles3.c
  5. +1
    -1
      src/nanovg_gl.h
  6. +69
    -24
      src/nanovg_gl_utils.h

+ 0
- 28
example/example_gl2.c View File

@@ -57,10 +57,8 @@ int main()
GLFWwindow* window; GLFWwindow* window;
struct DemoData data; struct DemoData data;
struct NVGcontext* vg = NULL; struct NVGcontext* vg = NULL;
struct NVGLUframebuffer fb;
struct PerfGraph fps; struct PerfGraph fps;
double prevt = 0; double prevt = 0;
int hasFBO;


if (!glfwInit()) { if (!glfwInit()) {
printf("Failed to init GLFW."); printf("Failed to init GLFW.");
@@ -112,8 +110,6 @@ int main()
glfwSetTime(0); glfwSetTime(0);
prevt = glfwGetTime(); prevt = glfwGetTime();


hasFBO = nvgluCreateFramebuffer(vg, &fb, 600, 600);

while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
double mx, my, t, dt; double mx, my, t, dt;
@@ -121,20 +117,6 @@ int main()
int fbWidth, fbHeight; int fbWidth, fbHeight;
float pxRatio; 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(); t = glfwGetTime();
dt = t - prevt; dt = t - prevt;
prevt = t; prevt = t;
@@ -160,15 +142,6 @@ int main()
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data);
renderGraph(vg, 5,5, &fps); 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); nvgEndFrame(vg);


if (screenshot) { if (screenshot) {
@@ -182,7 +155,6 @@ int main()


freeDemoData(vg, &data); freeDemoData(vg, &data);


nvgluDeleteFramebuffer(vg, &fb);
nvgDeleteGL2(vg); nvgDeleteGL2(vg);


glfwTerminate(); glfwTerminate();


+ 29
- 0
example/example_gl3.c View File

@@ -27,6 +27,7 @@
#include "nanovg.h" #include "nanovg.h"
#define NANOVG_GL3_IMPLEMENTATION #define NANOVG_GL3_IMPLEMENTATION
#include "nanovg_gl.h" #include "nanovg_gl.h"
#include "nanovg_gl_utils.h"
#include "demo.h" #include "demo.h"
#include "perf.h" #include "perf.h"


@@ -61,6 +62,7 @@ int main()
struct GPUtimer gpuTimer; struct GPUtimer gpuTimer;
struct PerfGraph fps, cpuGraph, gpuGraph; struct PerfGraph fps, cpuGraph, gpuGraph;
double prevt = 0, cpuTime = 0; double prevt = 0, cpuTime = 0;
struct NVGLUframebuffer* fb = NULL;


if (!glfwInit()) { if (!glfwInit()) {
printf("Failed to init GLFW."); printf("Failed to init GLFW.");
@@ -122,6 +124,8 @@ int main()
glfwSetTime(0); glfwSetTime(0);
prevt = glfwGetTime(); prevt = glfwGetTime();


fb = nvgluCreateFramebuffer(vg, 600, 600);

while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
double mx, my, t, dt; double mx, my, t, dt;
@@ -143,6 +147,20 @@ int main()
// Calculate pixel ration for hi-dpi devices. // Calculate pixel ration for hi-dpi devices.
pxRatio = (float)fbWidth / (float)winWidth; 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 // Update and render
glViewport(0, 0, fbWidth, fbHeight); glViewport(0, 0, fbWidth, fbHeight);
if (premult) if (premult)
@@ -160,6 +178,15 @@ int main()
if (gpuTimer.supported) if (gpuTimer.supported)
renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); 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); nvgEndFrame(vg);


// Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU)
@@ -184,6 +211,8 @@ int main()


freeDemoData(vg, &data); freeDemoData(vg, &data);


nvgluDeleteFramebuffer(vg, fb);

nvgDeleteGL3(vg); nvgDeleteGL3(vg);


printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f); printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f);


+ 1
- 0
example/example_gles2.c View File

@@ -22,6 +22,7 @@
#include "nanovg.h" #include "nanovg.h"
#define NANOVG_GLES2_IMPLEMENTATION #define NANOVG_GLES2_IMPLEMENTATION
#include "nanovg_gl.h" #include "nanovg_gl.h"
#include "nanovg_gl_utils.h"
#include "demo.h" #include "demo.h"
#include "perf.h" #include "perf.h"




+ 1
- 0
example/example_gles3.c View File

@@ -22,6 +22,7 @@
#include "nanovg.h" #include "nanovg.h"
#define NANOVG_GLES3_IMPLEMENTATION #define NANOVG_GLES3_IMPLEMENTATION
#include "nanovg_gl.h" #include "nanovg_gl.h"
#include "nanovg_gl_utils.h"
#include "demo.h" #include "demo.h"
#include "perf.h" #include "perf.h"




+ 1
- 1
src/nanovg_gl.h View File

@@ -1324,7 +1324,7 @@ int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int flag


tex->tex = textureId; tex->tex = textureId;
tex->type = NVG_TEXTURE_RGBA; tex->type = NVG_TEXTURE_RGBA;
tex->flags = 0;
tex->flags = flags;
glBindTexture(GL_TEXTURE_2D, tex->tex); glBindTexture(GL_TEXTURE_2D, tex->tex);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex->width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex->width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex->height); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex->height);


+ 69
- 24
src/nanovg_gl_utils.h View File

@@ -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 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); void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb);



#endif /* gl_utils_h */
#endif // NANOVG_GL_UTILS_H


#ifdef NANOVG_GL_IMPLEMENTATION #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->image = nvgCreateImageRGBA(ctx, w, h, NULL);
fb->texture = nvglImageHandle(ctx, fb->image); fb->texture = nvglImageHandle(ctx, fb->image);
nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y); nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y);


/* frame buffer object */
// frame buffer object
glGenFramebuffers(1, &fb->fbo); glGenFramebuffers(1, &fb->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo); glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);


/* render buffer object */
// render buffer object
glGenRenderbuffers(1, &fb->rbo); glGenRenderbuffers(1, &fb->rbo);
glBindRenderbuffer(GL_RENDERBUFFER, fb->rbo); glBindRenderbuffer(GL_RENDERBUFFER, fb->rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);


/* combine all */
// combine all
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->rbo); 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) if (fb->fbo != 0)
glDeleteFramebuffers(1, &fb->fbo); glDeleteFramebuffers(1, &fb->fbo);
if (fb->rbo != 0) if (fb->rbo != 0)
@@ -54,8 +96,11 @@ void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb)
fb->rbo = 0; fb->rbo = 0;
fb->texture = 0; fb->texture = 0;
fb->image = -1; 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

Loading…
Cancel
Save