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;
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();


+ 29
- 0
example/example_gl3.c View File

@@ -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);


+ 1
- 0
example/example_gles2.c View File

@@ -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"



+ 1
- 0
example/example_gles3.c View File

@@ -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"



+ 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->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);


+ 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 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

Loading…
Cancel
Save