Signed-off-by: falkTX <falktx@falktx.com>pull/327/head
| @@ -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 | |||
| */ | |||
| @@ -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()); | |||
| @@ -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; | |||
| } | |||
| @@ -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]; | |||
| @@ -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 { | |||