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