Browse Source

NanoVG: Allow to load raw images of any format, fix size

Signed-off-by: falkTX <falktx@falktx.com>
pull/327/head
falkTX 4 years ago
parent
commit
92dc4eeddc
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
5 changed files with 147 additions and 21 deletions
  1. +16
    -2
      dgl/NanoVG.hpp
  2. +44
    -2
      dgl/src/NanoVG.cpp
  3. +7
    -2
      dgl/src/nanovg/nanovg.c
  4. +12
    -5
      dgl/src/nanovg/nanovg.h
  5. +68
    -10
      dgl/src/nanovg/nanovg_gl.h

+ 16
- 2
dgl/NanoVG.hpp View File

@@ -582,12 +582,26 @@ public:
NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, int imageFlags);

/**
Creates image from specified image data.
Creates image from specified raw format image data.
*/
NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
ImageFlags imageFlags, ImageFormat format);

/**
Creates image from specified raw format image data.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
int imageFlags, ImageFormat format);

/**
Creates image from specified RGBA image data.
*/
NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags);

/**
Creates image from specified image data.
Creates image from specified RGBA image data.
Overloaded function for convenience.
@see ImageFlags
*/


+ 44
- 2
dgl/src/NanoVG.cpp View File

@@ -215,6 +215,7 @@ NanoImage& NanoImage::operator=(const Handle& handle)

fHandle.context = handle.context;
fHandle.imageId = handle.imageId;
_updateSize();

return *this;
}
@@ -631,6 +632,45 @@ NanoImage::Handle NanoVG::createImageFromMemory(uchar* data, uint dataSize, int
return NanoImage::Handle(fContext, nvgCreateImageMem(fContext, imageFlags, data,static_cast<int>(dataSize)));
}

NanoImage::Handle NanoVG::createImageFromRawMemory(uint w, uint h, const uchar* data,
ImageFlags imageFlags, ImageFormat format)
{
return createImageFromRawMemory(w, h, data, static_cast<int>(imageFlags), format);
}

NanoImage::Handle NanoVG::createImageFromRawMemory(uint w, uint h, const uchar* data,
int imageFlags, ImageFormat format)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, NanoImage::Handle());

NVGtexture nvgformat;
switch (format)
{
case kImageFormatGrayscale:
nvgformat = NVG_TEXTURE_ALPHA;
break;
case kImageFormatBGR:
nvgformat = NVG_TEXTURE_BGR;
break;
case kImageFormatBGRA:
nvgformat = NVG_TEXTURE_BGRA;
break;
case kImageFormatRGB:
nvgformat = NVG_TEXTURE_RGB;
break;
case kImageFormatRGBA:
nvgformat = NVG_TEXTURE_RGBA;
break;
default:
return NanoImage::Handle();
}

return NanoImage::Handle(fContext, nvgCreateImageRaw(fContext,
static_cast<int>(w),
static_cast<int>(h), imageFlags, nvgformat, data));
}

NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags)
{
return createImageFromRGBA(w, h, data, static_cast<int>(imageFlags));
@@ -646,12 +686,14 @@ NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data,
static_cast<int>(h), imageFlags, data));
}

NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture)
NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h,
ImageFlags imageFlags, bool deleteTexture)
{
return createImageFromTextureHandle(textureId, w, h, static_cast<int>(imageFlags), deleteTexture);
}

NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture)
NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h,
int imageFlags, bool deleteTexture)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(textureId != 0, NanoImage::Handle());


+ 7
- 2
dgl/src/nanovg/nanovg.c View File

@@ -817,9 +817,14 @@ int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int
return image;
}

int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data)
{
return ctx->params.renderCreateTexture(ctx->params.userPtr, format, w, h, imageFlags, data);
}

int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data)
{
return ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_RGBA, w, h, imageFlags, data);
return nvgCreateImageRaw(ctx, w, h, imageFlags, NVG_TEXTURE_RGBA, data);
}

void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data)
@@ -948,7 +953,7 @@ NVGpaint nvgImagePattern(NVGcontext* ctx,

p.image = image;

p.innerColor = p.outerColor = nvgRGBAf(1,1,1,alpha);
p.innerColor = p.outerColor = nvgRGBAf(123,244,1,alpha);

return p;
}


+ 12
- 5
dgl/src/nanovg/nanovg.h View File

@@ -144,6 +144,14 @@ enum NVGimageFlags {
NVG_IMAGE_NEAREST = 1<<5, // Image interpolation is Nearest instead Linear
};

enum NVGtexture {
NVG_TEXTURE_ALPHA,
NVG_TEXTURE_BGR,
NVG_TEXTURE_BGRA,
NVG_TEXTURE_RGB,
NVG_TEXTURE_RGBA,
};

// Begin drawing a new frame
// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame()
// nvgBeginFrame() defines the size of the window to render to in relation currently
@@ -375,6 +383,10 @@ int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags);
// Returns handle to the image.
int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata);

// Creates image from specified image data and texture format.
// Returns handle to the image.
int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data);

// Creates image from specified image data.
// Returns handle to the image.
int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data);
@@ -627,11 +639,6 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa
//
// Internal Render API
//
enum NVGtexture {
NVG_TEXTURE_ALPHA = 0x01,
NVG_TEXTURE_RGBA = 0x02,
};

struct NVGscissor {
float xform[6];
float extent[2];


+ 68
- 10
dgl/src/nanovg/nanovg_gl.h View File

@@ -761,9 +761,21 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im
}
#endif

if (type == NVG_TEXTURE_RGBA)
switch (type)
{
case NVG_TEXTURE_BGR:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_BGRA:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGB:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGBA:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
break;
default:
#if defined(NANOVG_GLES2) || defined (NANOVG_GL2)
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
#elif defined(NANOVG_GLES3)
@@ -771,6 +783,8 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
#endif
break;
}

if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) {
if (imageFlags & NVG_IMAGE_NEAREST) {
@@ -845,22 +859,50 @@ static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
#else
// No support for all of skip, need to update a whole row at a time.
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
data += y*tex->width*3;
break;
case NVG_TEXTURE_BGRA:
data += y*tex->width*4;
else
break;
case NVG_TEXTURE_RGB:
data += y*tex->width*3;
break;
case NVG_TEXTURE_RGBA:
data += y*tex->width*4;
break;
default:
data += y*tex->width;
break;
}
x = 0;
w = tex->width;
#endif

if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGR, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_BGRA:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGB:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGB, GL_UNSIGNED_BYTE, data);
break;
case NVG_TEXTURE_RGBA:
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
break;
default:
#if defined(NANOVG_GLES2) || defined(NANOVG_GL2)
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data);
#endif
break;
}

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
#ifndef NANOVG_GLES2
@@ -956,15 +998,31 @@ static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpai
frag->type = NSVG_SHADER_FILLIMG;

#if NANOVG_GL_USE_UNIFORMBUFFER
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
case NVG_TEXTURE_BGRA:
case NVG_TEXTURE_RGB:
case NVG_TEXTURE_RGBA:
frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0 : 1;
else
break;
default:
frag->texType = 2;
break;
}
#else
if (tex->type == NVG_TEXTURE_RGBA)
switch (tex->type)
{
case NVG_TEXTURE_BGR:
case NVG_TEXTURE_BGRA:
case NVG_TEXTURE_RGB:
case NVG_TEXTURE_RGBA:
frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0.0f : 1.0f;
else
break;
default:
frag->texType = 2.0f;
break;
}
#endif
// printf("frag->texType = %d\n", frag->texType);
} else {


Loading…
Cancel
Save