diff --git a/example/demo.c b/example/demo.c index 94abc70..944b330 100644 --- a/example/demo.c +++ b/example/demo.c @@ -812,7 +812,7 @@ int loadDemoData(struct NVGcontext* vg, struct DemoData* data) for (i = 0; i < 12; i++) { char file[128]; snprintf(file, 128, "../example/images/image%d.jpg", i+1); - data->images[i] = nvgCreateImage(vg, file); + data->images[i] = nvgCreateImage(vg, file, 0); if (data->images[i] == 0) { printf("Could not load %s.\n", file); return -1; diff --git a/premake4.lua b/premake4.lua index 5bc835e..0880a99 100644 --- a/premake4.lua +++ b/premake4.lua @@ -5,15 +5,15 @@ solution "nanovg" location ( "build" ) configurations { "Debug", "Release" } platforms {"native", "x64", "x32"} - + project "nanovg" language "C" kind "StaticLib" includedirs { "src" } files { "src/*.c" } targetdir("build") - --defines { "FONS_USE_FREETYPE" } -- Uncomment to compile with FreeType support - + defines { "_CRT_SECURE_NO_WARNINGS" } --,"FONS_USE_FREETYPE" } Uncomment to compile with FreeType support + configuration "Debug" defines { "DEBUG" } flags { "Symbols", "ExtraWarnings"} @@ -23,6 +23,7 @@ solution "nanovg" flags { "Optimize", "ExtraWarnings"} project "example_gl2" + kind "ConsoleApp" language "C" files { "example/example_gl2.c", "example/demo.c", "example/perf.c" } @@ -36,8 +37,8 @@ solution "nanovg" defines { "NANOVG_GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -65,8 +66,8 @@ solution "nanovg" defines { "NANOVG_GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -95,8 +96,8 @@ solution "nanovg" defines { "NANOVG_GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -125,8 +126,8 @@ solution "nanovg" defines { "NANOVG_GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -153,8 +154,8 @@ solution "nanovg" links { "GL", "GLU", "m", "GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -181,8 +182,8 @@ solution "nanovg" links { "GL", "GLU", "m", "GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } @@ -209,8 +210,8 @@ solution "nanovg" links { "GL", "GLU", "m", "GLEW" } configuration { "windows" } - links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32" } - defines { "NANOVG_GLEW" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "NANOVG_GLEW", "_CRT_SECURE_NO_WARNINGS" } configuration { "macosx" } links { "glfw3" } diff --git a/src/nanovg.c b/src/nanovg.c index 7223e32..be6dcc6 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -238,7 +238,7 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params) if (ctx->fs == NULL) goto error; // Create font texture - ctx->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, NULL); + ctx->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, 0, NULL); if (ctx->fontImages[0] == 0) goto error; ctx->fontImageIdx = 0; @@ -695,7 +695,7 @@ void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint) nvgTransformMultiply(state->fill.xform, state->xform); } -int nvgCreateImage(struct NVGcontext* ctx, const char* filename) +int nvgCreateImage(struct NVGcontext* ctx, const char* filename, int imageFlags) { int w, h, n, image; unsigned char* img; @@ -706,12 +706,12 @@ int nvgCreateImage(struct NVGcontext* ctx, const char* filename) // printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); return 0; } - image = nvgCreateImageRGBA(ctx, w, h, img); + image = nvgCreateImageRGBA(ctx, w, h, imageFlags, img); stbi_image_free(img); return image; } -int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata) +int nvgCreateImageMem(struct NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata) { int w, h, n, image; unsigned char* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4); @@ -719,14 +719,14 @@ int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata) // printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); return 0; } - image = nvgCreateImageRGBA(ctx, w, h, img); + image = nvgCreateImageRGBA(ctx, w, h, imageFlags, img); stbi_image_free(img); return image; } -int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, const unsigned char* data) +int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data) { - return ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_RGBA, w, h, data); + return ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_RGBA, w, h, imageFlags, data); } void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data) @@ -2209,7 +2209,7 @@ static int nvg__allocTextAtlas(struct NVGcontext* ctx) iw *= 2; if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE) iw = ih = NVG_MAX_FONTIMAGE_SIZE; - ctx->fontImages[ctx->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, NULL); + ctx->fontImages[ctx->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, 0, NULL); } ++ctx->fontImageIdx; fonsResetAtlas(ctx->fs, iw, ih); diff --git a/src/nanovg.h b/src/nanovg.h index a389aab..6487293 100644 --- a/src/nanovg.h +++ b/src/nanovg.h @@ -102,6 +102,9 @@ struct NVGtextRow { float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending. }; +enum NVGimage { + NVG_IMAGE_GENERATE_MIPMAPS = 1 << 0 // Generate mipmaps during creation of the image. +}; // Begin drawing a new frame // Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() @@ -305,15 +308,15 @@ float nvgRadToDeg(float rad); // Creates image by loading it from the disk from specified file name. // Returns handle to the image. -int nvgCreateImage(struct NVGcontext* ctx, const char* filename); +int nvgCreateImage(struct NVGcontext* ctx, const char* filename, int imageFlags); // Creates image by loading it from the specified chunk of memory. // Returns handle to the image. -int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata); +int nvgCreateImageMem(struct NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata); // Creates image from specified image data. // Returns handle to the image. -int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, const unsigned char* data); +int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data); // Updates image data specified by image handle. void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data); @@ -567,7 +570,7 @@ struct NVGparams { void* userPtr; int edgeAntiAlias; int (*renderCreate)(void* uptr); - int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data); + int (*renderCreateTexture)(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data); int (*renderDeleteTexture)(void* uptr, int image); int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); diff --git a/src/nanovg_gl.h b/src/nanovg_gl.h index 044a2b9..a3d7dbf 100644 --- a/src/nanovg_gl.h +++ b/src/nanovg_gl.h @@ -81,7 +81,7 @@ void nvgDeleteGLES3(struct NVGcontext* ctx); enum NVGLtextureflags { NVGL_TEXTURE_FLIP_Y = 0x01, NVGL_TEXTURE_NODELETE = 0x02, - NVGL_TEXTURE_PREMULTIPLIED = 0x04, + NVGL_TEXTURE_PREMULTIPLIED = 0x04 }; int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int w, int h, int flags); @@ -610,7 +610,7 @@ static int glnvg__renderCreate(void* uptr) return 1; } -static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const unsigned char* data) +static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; struct GLNVGtexture* tex = glnvg__allocTexture(gl); @@ -630,6 +630,13 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #endif +#if defined (NANOVG_GL2) + // GL 1.4 and later has support for generating mipmaps using a tex parameter. + if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + } +#endif + if (type == NVG_TEXTURE_RGBA) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); else @@ -641,9 +648,14 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data); #endif - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - + if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); #ifndef NANOVG_GLES2 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); @@ -651,6 +663,13 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #endif + // The new way to build mipmaps on GLES and GL3 +#if !defined(NANOVG_GL2) + if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { + glGenerateMipmap(GL_TEXTURE_2D); + } +#endif + if (glnvg__checkError("create tex")) return 0; diff --git a/src/nanovg_gl_utils.h b/src/nanovg_gl_utils.h index 420ae66..34a2743 100644 --- a/src/nanovg_gl_utils.h +++ b/src/nanovg_gl_utils.h @@ -53,7 +53,7 @@ struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, i if (fb == NULL) goto error; memset(fb, 0, sizeof(struct NVGLUframebuffer)); - fb->image = nvgCreateImageRGBA(ctx, w, h, NULL); + fb->image = nvgCreateImageRGBA(ctx, w, h, 0, NULL); fb->texture = nvglImageHandle(ctx, fb->image); nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y | NVGL_TEXTURE_PREMULTIPLIED);