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