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