Browse Source

Merge pull request #56 from dougbinks/NVGcolor

Merged NVGcolor, which implements the color as floats, colors can be > 1.0, allowing HDR rendering when needed.
shared-context
Mikko Mononen 11 years ago
parent
commit
1db6eec59a
6 changed files with 124 additions and 83 deletions
  1. +13
    -3
      example/demo.c
  2. +52
    -28
      src/nanovg.c
  3. +37
    -14
      src/nanovg.h
  4. +9
    -17
      src/nanovg_gl2.h
  5. +9
    -17
      src/nanovg_gl3.h
  6. +4
    -4
      src/nanovg_gl3buf.h

+ 13
- 3
example/demo.c View File

@@ -24,6 +24,16 @@
#define ICON_LOGIN 0xE740
#define ICON_TRASH 0xE729

// Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise
int isBlack( struct NVGcolor col )
{
if( col.r == 0.0f && col.g == 0.0f && col.b == 0.0f && col.a == 0.0f )
{
return 1;
}
return 0;
}

static char* cpToUTF8(int cp, char* str)
{
int n = 0;
@@ -254,17 +264,17 @@ void drawCheckBox(struct NVGcontext* vg, const char* text, float x, float y, flo
nvgText(vg, x+9+2, y+h*0.5f, cpToUTF8(ICON_CHECK,icon), NULL);
}

void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, unsigned int col)
void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, struct NVGcolor col)
{
struct NVGpaint bg;
char icon[8];
float cornerRadius = 4.0f;
float tw = 0, iw = 0;

bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,col==0?16:32), nvgRGBA(0,0,0,col==0?16:32));
bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,isBlack(col)?16:32), nvgRGBA(0,0,0,isBlack(col)?16:32));
nvgBeginPath(vg);
nvgRoundedRect(vg, x+1,y+1, w-2,h-2, cornerRadius-1);
if (col != 0) {
if (!isBlack(col)) {
nvgFillColor(vg, col);
nvgFill(vg);
}


+ 52
- 28
src/nanovg.c View File

@@ -278,35 +278,57 @@ void nvgEndFrame(struct NVGcontext* ctx)
ctx->params.renderFlush(ctx->params.userPtr, ctx->alphaBlend);
}

unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b)
struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b)
{
return nvgRGBA(r,g,b,255);
}

unsigned int nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
struct NVGcolor nvgRGBf(float r, float g, float b)
{
return (r) | (g << 8) | (b << 16) | (a << 24);
return nvgRGBAf(r,g,b,1.0f);
}

unsigned int nvgTransRGBA(unsigned int c, unsigned char a)
struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
int r = (c) & 0xff;
int g = (c>>8) & 0xff;
int b = (c>>16) & 0xff;
return nvgRGBA(r,g,b,a);
struct NVGcolor color = {r/255.0f, g/255.0f, b/255.0f, a/255.0f};
return color;
}

unsigned int nvgLerpRGBA(unsigned int c0, unsigned int c1, float u)
struct NVGcolor nvgRGBAf(float r, float g, float b, float a)
{
int iu = (int)(nvg__clampf(u, 0.0f, 1.0f) * 256.0f);
int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8;
int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8;
int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8;
int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8;
return nvgRGBA(r,g,b,a);
struct NVGcolor color = {r, g, b, a};
return color;
}

unsigned int nvgHSL(float h, float s, float l)
struct NVGcolor nvgTransRGBA(struct NVGcolor c, unsigned char a)
{
c.a = a / 255.0f;
return c;
}

struct NVGcolor nvgTransRGBAf(struct NVGcolor c, float a)
{
c.a = a;
return c;
}

struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u)
{
int i;
float oneminu;
struct NVGcolor cint;

u = nvg__clampf(u, 0.0f, 1.0f);
oneminu = 1.0f - u;
for( i = 0; i <4; ++i )
{
cint.rgba[i] = c0.rgba[i] * oneminu + c1.rgba[i] * u;
}
return cint;
}

struct NVGcolor nvgHSL(float h, float s, float l)
{
return nvgHSLA(h,s,l,255);
}
@@ -324,23 +346,25 @@ static float nvg__hue(float h, float m1, float m2)
return m1;
}

unsigned int nvgHSLA(float h, float s, float l, unsigned char a)
struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a)
{
float m1, m2;
unsigned char r,g,b;
struct NVGcolor col;
h = nvg__modf(h, 1.0f);
if (h < 0.0f) h += 1.0f;
s = nvg__clampf(s, 0.0f, 1.0f);
l = nvg__clampf(l, 0.0f, 1.0f);
m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s);
m1 = 2 * l - m2;
r = (unsigned char)nvg__clampf(nvg__hue(h + 1.0f/3.0f, m1, m2) * 255.0f, 0, 255);
g = (unsigned char)nvg__clampf(nvg__hue(h, m1, m2) * 255.0f, 0, 255);
b = (unsigned char)nvg__clampf(nvg__hue(h - 1.0f/3.0f, m1, m2) * 255.0f, 0, 255);
return nvgRGBA(r,g,b,a);
col.r = nvg__clampf(nvg__hue(h + 1.0f/3.0f, m1, m2), 0.0f, 1.0f);
col.g = nvg__clampf(nvg__hue(h, m1, m2), 0.0f, 1.0f);
col.b = nvg__clampf(nvg__hue(h - 1.0f/3.0f, m1, m2), 0.0f, 1.0f);
col.a = a/255.0f;
return col;
}



static struct NVGstate* nvg__getState(struct NVGcontext* ctx)
{
return &ctx->states[ctx->nstates-1];
@@ -396,7 +420,7 @@ static void nvg__xformPremultiply(float* t, float* s)
memcpy(t, s2, sizeof(float)*6);
}

static void nvg__setPaintColor(struct NVGpaint* p, unsigned int color)
static void nvg__setPaintColor(struct NVGpaint* p, struct NVGcolor color)
{
memset(p, 0, sizeof(*p));
nvg__xformIdentity(p->xform);
@@ -511,7 +535,7 @@ void nvgScale(struct NVGcontext* ctx, float x, float y)
}


void nvgStrokeColor(struct NVGcontext* ctx, unsigned int color)
void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color)
{
struct NVGstate* state = nvg__getState(ctx);
nvg__setPaintColor(&state->stroke, color);
@@ -524,7 +548,7 @@ void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint)
nvg__xformMultiply(state->stroke.xform, state->xform);
}

void nvgFillColor(struct NVGcontext* ctx, unsigned int color)
void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color)
{
struct NVGstate* state = nvg__getState(ctx);
nvg__setPaintColor(&state->fill, color);
@@ -587,7 +611,7 @@ void nvgDeleteImage(struct NVGcontext* ctx, int image)

struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx,
float sx, float sy, float ex, float ey,
unsigned int icol, unsigned int ocol)
struct NVGcolor icol, struct NVGcolor ocol)
{
struct NVGpaint p;
float dx, dy, d;
@@ -626,7 +650,7 @@ struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx,

struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx,
float cx, float cy, float inr, float outr,
unsigned int icol, unsigned int ocol)
struct NVGcolor icol, struct NVGcolor ocol)
{
struct NVGpaint p;
float r = (inr+outr)*0.5f;
@@ -653,7 +677,7 @@ struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx,

struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx,
float x, float y, float w, float h, float r, float f,
unsigned int icol, unsigned int ocol)
struct NVGcolor icol, struct NVGcolor ocol)
{
struct NVGpaint p;



+ 37
- 14
src/nanovg.h View File

@@ -27,14 +27,26 @@ extern "C" {

struct NVGcontext;

struct NVGcolor
{
union
{
float rgba[4];
struct
{
float r,g,b,a;
};
};
};

struct NVGpaint
{
float xform[6];
float extent[2];
float radius;
float feather;
unsigned int innerColor;
unsigned int outerColor;
struct NVGcolor innerColor;
struct NVGcolor outerColor;
int image;
int repeat;
};
@@ -101,25 +113,36 @@ void nvgEndFrame(struct NVGcontext* ctx);
//
// Colors in NanoVG are stored as unsigned ints in ABGR format.

// Returns a color value from red, green, blue values. Alpha will be set to 255.
unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b);
// Returns a color value from red, green, blue values. Alpha will be set to 255 (1.0f).
struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b);

// Returns a color value from red, green, blue values. Alpha will be set to 1.0f.
struct NVGcolor nvgRGBf(float r, float g, float b);


// Returns a color value from red, green, blue and alpha values.
unsigned int nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);

// Returns a color value from red, green, blue and alpha values.
struct NVGcolor nvgRGBAf(float r, float g, float b, float a);


// Linearly interpoaltes from color c0 to c1, and returns resulting color value.
unsigned int nvgLerpRGBA(unsigned int c0, unsigned int c1, float u);
struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u);

// Sets transparency of a color value.
struct NVGcolor nvgTransRGBA(struct NVGcolor c0, unsigned char a);

// Sets transparency of a color value.
unsigned int nvgTransRGBA(unsigned int c0, unsigned char a);
struct NVGcolor nvgTransRGBAf(struct NVGcolor c0, float a);

// Returns color value specified by hue, saturation and lightness.
// HSL values are all in range [0..1], alpha will be set to 255.
unsigned int nvgHSL(float h, float s, float l);
struct NVGcolor nvgHSL(float h, float s, float l);

// Returns color value specified by hue, saturation and lightness and alpha.
// HSL values are all in range [0..1], alpha in range [0..255]
unsigned int nvgHSLA(float h, float s, float l, unsigned char a);
struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a);

//
// State Handling
@@ -148,13 +171,13 @@ void nvgReset(struct NVGcontext* ctx);
// Current render style can be saved and restored using nvgSave() and nvgRestore().

// Sets current stroke style to a solid color.
void nvgStrokeColor(struct NVGcontext* ctx, unsigned int color);
void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color);

// Sets current stroke style to a paint, which can be a one of the gradients or a pattern.
void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint);

// Sets current fill cstyle to a solid color.
void nvgFillColor(struct NVGcontext* ctx, unsigned int color);
void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color);

// Sets current fill style to a paint, which can be a one of the gradients or a pattern.
void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint);
@@ -247,7 +270,7 @@ void nvgDeleteImage(struct NVGcontext* ctx, int image);
// of the linear gradient, icol specifies the start color and ocol the end color.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, float ex, float ey,
unsigned int icol, unsigned int ocol);
struct NVGcolor icol, struct NVGcolor ocol);

// Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering
// drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
@@ -255,13 +278,13 @@ struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, fl
// the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, float x, float y, float w, float h,
float r, float f, unsigned int icol, unsigned int ocol);
float r, float f, struct NVGcolor icol, struct NVGcolor ocol);

// Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify
// the inner and outer radius of the gradient, icol specifies the start color and ocol the end color.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, float inr, float outr,
unsigned int icol, unsigned int ocol);
struct NVGcolor icol, struct NVGcolor ocol);

// Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern,
// (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render,


+ 9
- 17
src/nanovg_gl2.h View File

@@ -516,14 +516,6 @@ static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h)
return 1;
}

static void glnvg__toFloatColor(float* fc, unsigned int c)
{
fc[0] = ((c) & 0xff) / 255.0f;
fc[1] = ((c>>8) & 0xff) / 255.0f;
fc[2] = ((c>>16) & 0xff) / 255.0f;
fc[3] = ((c>>24) & 0xff) / 255.0f;
}

static void glnvg__xformIdentity(float* t)
{
t[0] = 1.0f; t[1] = 0.0f;
@@ -562,15 +554,15 @@ static void glnvg__xformToMat3x3(float* m3, float* t)

static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width, float fringe)
{
float innerCol[4];
float outerCol[4];
struct NVGcolor innerCol;
struct NVGcolor outerCol;
struct GLNVGtexture* tex = NULL;
float invxform[6], paintMat[9], scissorMat[9];
float scissorx = 0, scissory = 0;
float scissorsx = 0, scissorsy = 0;

glnvg__toFloatColor(innerCol, paint->innerColor);
glnvg__toFloatColor(outerCol, paint->outerColor);
innerCol = paint->innerColor;
outerCol = paint->outerColor;

glnvg__xformInverse(invxform, paint->xform);
glnvg__xformToMat3x3(paintMat, invxform);
@@ -618,8 +610,8 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st
glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]);
glUniform1f(gl->shader.loc[GLNVG_LOC_RADIUS], paint->radius);
glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], paint->feather);
glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol);
glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol);
glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol.rgba);
glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol.rgba);
glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe);
glnvg__checkError("grad paint loc");
}
@@ -850,7 +842,7 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV
{
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, paint->image);
float color[4];
struct NVGcolor color;
NVG_NOTUSED(scissor);

if (gl->shader.prog == 0)
@@ -875,8 +867,8 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glnvg__toFloatColor(color, paint->innerColor);
glVertexAttrib4fv(2, color);
color = paint->innerColor;
glVertexAttrib4fv(2, color.rgba);

glDrawArrays(GL_TRIANGLES, 0, nverts);



+ 9
- 17
src/nanovg_gl3.h View File

@@ -522,14 +522,6 @@ static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h)
return 1;
}

static void glnvg__toFloatColor(float* fc, unsigned int c)
{
fc[0] = ((c) & 0xff) / 255.0f;
fc[1] = ((c>>8) & 0xff) / 255.0f;
fc[2] = ((c>>16) & 0xff) / 255.0f;
fc[3] = ((c>>24) & 0xff) / 255.0f;
}

static void glnvg__xformIdentity(float* t)
{
t[0] = 1.0f; t[1] = 0.0f;
@@ -568,15 +560,15 @@ static void glnvg__xformToMat3x3(float* m3, float* t)

static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width, float fringe)
{
float innerCol[4];
float outerCol[4];
struct NVGcolor innerCol;
struct NVGcolor outerCol;
struct GLNVGtexture* tex = NULL;
float invxform[6], paintMat[9], scissorMat[9];
float scissorx = 0, scissory = 0;
float scissorsx = 0, scissorsy = 0;

glnvg__toFloatColor(innerCol, paint->innerColor);
glnvg__toFloatColor(outerCol, paint->outerColor);
innerCol = paint->innerColor;
outerCol = paint->outerColor;

glnvg__xformInverse(invxform, paint->xform);
glnvg__xformToMat3x3(paintMat, invxform);
@@ -624,8 +616,8 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st
glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]);
glUniform1f(gl->shader.loc[GLNVG_LOC_RADIUS], paint->radius);
glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], paint->feather);
glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol);
glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol);
glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol.rgba);
glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol.rgba);
glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe);
glnvg__checkError("grad paint loc");
}
@@ -858,7 +850,7 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV
{
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, paint->image);
float color[4];
struct NVGcolor color;
NVG_NOTUSED(scissor);

if (gl->shader.prog == 0)
@@ -884,8 +876,8 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glnvg__toFloatColor(color, paint->innerColor);
glVertexAttrib4fv(2, color);
color = paint->innerColor;
glVertexAttrib4fv(2, color.rgba);

glDrawArrays(GL_TRIANGLES, 0, nverts);



+ 4
- 4
src/nanovg_gl3buf.h View File

@@ -118,8 +118,8 @@ struct GLNVGpath {
struct GLNVGfragUniforms {
float scissorMat[12]; // matrices are actually 3 vec4s
float paintMat[12];
float innerCol[4];
float outerCol[4];
struct NVGcolor innerCol;
struct NVGcolor outerCol;
float scissorExt[2];
float scissorScale[2];
float extent[2];
@@ -591,8 +591,8 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms
struct GLNVGtexture* tex = NULL;
float invxform[6];

glnvg__toFloatColor(frag->innerCol, paint->innerColor);
glnvg__toFloatColor(frag->outerCol, paint->outerColor);
frag->innerCol = paint->innerColor;
frag->outerCol = paint->outerColor;

glnvg__xformInverse(invxform, paint->xform);
glnvg__xformToMat3x4(frag->paintMat, invxform);


Loading…
Cancel
Save