| @@ -812,7 +812,7 @@ int loadDemoData(struct NVGcontext* vg, struct DemoData* data) | |||||
| for (i = 0; i < 12; i++) { | for (i = 0; i < 12; i++) { | ||||
| char file[128]; | char file[128]; | ||||
| snprintf(file, 128, "../example/images/image%d.jpg", i+1); | 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) { | if (data->images[i] == 0) { | ||||
| printf("Could not load %s.\n", file); | printf("Could not load %s.\n", file); | ||||
| return -1; | return -1; | ||||
| @@ -5,15 +5,15 @@ solution "nanovg" | |||||
| location ( "build" ) | location ( "build" ) | ||||
| configurations { "Debug", "Release" } | configurations { "Debug", "Release" } | ||||
| platforms {"native", "x64", "x32"} | platforms {"native", "x64", "x32"} | ||||
| project "nanovg" | project "nanovg" | ||||
| language "C" | language "C" | ||||
| kind "StaticLib" | kind "StaticLib" | ||||
| includedirs { "src" } | includedirs { "src" } | ||||
| files { "src/*.c" } | files { "src/*.c" } | ||||
| targetdir("build") | 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" | configuration "Debug" | ||||
| defines { "DEBUG" } | defines { "DEBUG" } | ||||
| flags { "Symbols", "ExtraWarnings"} | flags { "Symbols", "ExtraWarnings"} | ||||
| @@ -23,6 +23,7 @@ solution "nanovg" | |||||
| flags { "Optimize", "ExtraWarnings"} | flags { "Optimize", "ExtraWarnings"} | ||||
| project "example_gl2" | project "example_gl2" | ||||
| kind "ConsoleApp" | kind "ConsoleApp" | ||||
| language "C" | language "C" | ||||
| files { "example/example_gl2.c", "example/demo.c", "example/perf.c" } | files { "example/example_gl2.c", "example/demo.c", "example/perf.c" } | ||||
| @@ -36,8 +37,8 @@ solution "nanovg" | |||||
| defines { "NANOVG_GLEW" } | defines { "NANOVG_GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -65,8 +66,8 @@ solution "nanovg" | |||||
| defines { "NANOVG_GLEW" } | defines { "NANOVG_GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -95,8 +96,8 @@ solution "nanovg" | |||||
| defines { "NANOVG_GLEW" } | defines { "NANOVG_GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -125,8 +126,8 @@ solution "nanovg" | |||||
| defines { "NANOVG_GLEW" } | defines { "NANOVG_GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -153,8 +154,8 @@ solution "nanovg" | |||||
| links { "GL", "GLU", "m", "GLEW" } | links { "GL", "GLU", "m", "GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -181,8 +182,8 @@ solution "nanovg" | |||||
| links { "GL", "GLU", "m", "GLEW" } | links { "GL", "GLU", "m", "GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -209,8 +210,8 @@ solution "nanovg" | |||||
| links { "GL", "GLU", "m", "GLEW" } | links { "GL", "GLU", "m", "GLEW" } | ||||
| configuration { "windows" } | 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" } | configuration { "macosx" } | ||||
| links { "glfw3" } | links { "glfw3" } | ||||
| @@ -238,7 +238,7 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params) | |||||
| if (ctx->fs == NULL) goto error; | if (ctx->fs == NULL) goto error; | ||||
| // Create font texture | // 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; | if (ctx->fontImages[0] == 0) goto error; | ||||
| ctx->fontImageIdx = 0; | ctx->fontImageIdx = 0; | ||||
| @@ -695,7 +695,7 @@ void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint) | |||||
| nvgTransformMultiply(state->fill.xform, state->xform); | 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; | int w, h, n, image; | ||||
| unsigned char* img; | 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()); | // printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| image = nvgCreateImageRGBA(ctx, w, h, img); | |||||
| image = nvgCreateImageRGBA(ctx, w, h, imageFlags, img); | |||||
| stbi_image_free(img); | stbi_image_free(img); | ||||
| return image; | 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; | int w, h, n, image; | ||||
| unsigned char* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4); | 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()); | // printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| image = nvgCreateImageRGBA(ctx, w, h, img); | |||||
| image = nvgCreateImageRGBA(ctx, w, h, imageFlags, img); | |||||
| stbi_image_free(img); | stbi_image_free(img); | ||||
| return image; | 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) | void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data) | ||||
| @@ -2209,7 +2209,7 @@ static int nvg__allocTextAtlas(struct NVGcontext* ctx) | |||||
| iw *= 2; | iw *= 2; | ||||
| if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE) | if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE) | ||||
| iw = 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; | ++ctx->fontImageIdx; | ||||
| fonsResetAtlas(ctx->fs, iw, ih); | fonsResetAtlas(ctx->fs, iw, ih); | ||||
| @@ -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. | 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 | // Begin drawing a new frame | ||||
| // Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() | // 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. | // Creates image by loading it from the disk from specified file name. | ||||
| // Returns handle to the image. | // 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. | // Creates image by loading it from the specified chunk of memory. | ||||
| // Returns handle to the image. | // 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. | // Creates image from specified image data. | ||||
| // Returns handle to the image. | // 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. | // Updates image data specified by image handle. | ||||
| void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data); | void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data); | ||||
| @@ -567,7 +570,7 @@ struct NVGparams { | |||||
| void* userPtr; | void* userPtr; | ||||
| int edgeAntiAlias; | int edgeAntiAlias; | ||||
| int (*renderCreate)(void* uptr); | 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 (*renderDeleteTexture)(void* uptr, int image); | ||||
| int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); | 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); | int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); | ||||
| @@ -81,7 +81,7 @@ void nvgDeleteGLES3(struct NVGcontext* ctx); | |||||
| enum NVGLtextureflags { | enum NVGLtextureflags { | ||||
| NVGL_TEXTURE_FLIP_Y = 0x01, | NVGL_TEXTURE_FLIP_Y = 0x01, | ||||
| NVGL_TEXTURE_NODELETE = 0x02, | 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); | 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; | 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 GLNVGcontext* gl = (struct GLNVGcontext*)uptr; | ||||
| struct GLNVGtexture* tex = glnvg__allocTexture(gl); | 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); | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | ||||
| #endif | #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) | if (type == NVG_TEXTURE_RGBA) | ||||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | ||||
| else | 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); | glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data); | ||||
| #endif | #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); | glPixelStorei(GL_UNPACK_ALIGNMENT, 4); | ||||
| #ifndef NANOVG_GLES2 | #ifndef NANOVG_GLES2 | ||||
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | 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); | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | ||||
| #endif | #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")) | if (glnvg__checkError("create tex")) | ||||
| return 0; | return 0; | ||||
| @@ -53,7 +53,7 @@ struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, i | |||||
| if (fb == NULL) goto error; | if (fb == NULL) goto error; | ||||
| memset(fb, 0, sizeof(struct NVGLUframebuffer)); | 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); | fb->texture = nvglImageHandle(ctx, fb->image); | ||||
| nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y | NVGL_TEXTURE_PREMULTIPLIED); | nvglImageFlags(ctx, fb->image, NVGL_TEXTURE_FLIP_Y | NVGL_TEXTURE_PREMULTIPLIED); | ||||