Browse Source

Fix BGR/BGRA image use under GLES, auto-convert as needed

Signed-off-by: falkTX <falktx@falktx.com>
pull/507/head
falkTX 1 month ago
parent
commit
2a1934940e
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
4 changed files with 117 additions and 4 deletions
  1. +16
    -0
      dgl/OpenGL.hpp
  2. +28
    -0
      dgl/src/OpenGL.cpp
  3. +69
    -0
      dgl/src/OpenGL3.cpp
  4. +4
    -4
      dgl/src/nanovg/nanovg_gl.h

+ 16
- 0
dgl/OpenGL.hpp View File

@@ -249,6 +249,18 @@ public:
*/ */
void drawAt(const GraphicsContext& context, const Point<int>& pos) override; void drawAt(const GraphicsContext& context, const Point<int>& pos) override;


#ifdef DGL_USE_GLES
/**
Get the image format.
*/
ImageFormat getFormat() const noexcept;

/**
Get the raw image data.
*/
const char* getRawData() const noexcept;
#endif

/** /**
TODO document this. TODO document this.
*/ */
@@ -312,6 +324,10 @@ private:
bool setupCalled; bool setupCalled;
bool textureInit; bool textureInit;
GLuint textureId; GLuint textureId;
#ifdef DGL_USE_GLES
mutable char* convertedData;
mutable const char* rawDataLast;
#endif
}; };


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------


+ 28
- 0
dgl/src/OpenGL.cpp View File

@@ -37,6 +37,10 @@ OpenGLImage::OpenGLImage()
setupCalled(false), setupCalled(false),
textureInit(false), textureInit(false),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
} }


@@ -45,6 +49,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, co
setupCalled(false), setupCalled(false),
textureInit(true), textureInit(true),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
DISTRHO_SAFE_ASSERT(textureId != 0); DISTRHO_SAFE_ASSERT(textureId != 0);
@@ -55,6 +63,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const Ima
setupCalled(false), setupCalled(false),
textureInit(true), textureInit(true),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
DISTRHO_SAFE_ASSERT(textureId != 0); DISTRHO_SAFE_ASSERT(textureId != 0);
@@ -65,6 +77,10 @@ OpenGLImage::OpenGLImage(const OpenGLImage& image)
setupCalled(false), setupCalled(false),
textureInit(true), textureInit(true),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
DISTRHO_SAFE_ASSERT(textureId != 0); DISTRHO_SAFE_ASSERT(textureId != 0);
@@ -74,6 +90,10 @@ OpenGLImage::~OpenGLImage()
{ {
if (textureId != 0) if (textureId != 0)
glDeleteTextures(1, &textureId); glDeleteTextures(1, &textureId);

#ifdef DGL_USE_GLES
std::free(convertedData);
#endif
} }


void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept
@@ -111,6 +131,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, co
setupCalled(false), setupCalled(false),
textureInit(true), textureInit(true),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
DISTRHO_SAFE_ASSERT(textureId != 0); DISTRHO_SAFE_ASSERT(textureId != 0);
@@ -121,6 +145,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const GLe
setupCalled(false), setupCalled(false),
textureInit(true), textureInit(true),
textureId(0) textureId(0)
#ifdef DGL_USE_GLES
, convertedData(nullptr)
, rawDataLast(nullptr)
#endif
{ {
glGenTextures(1, &textureId); glGenTextures(1, &textureId);
DISTRHO_SAFE_ASSERT(textureId != 0); DISTRHO_SAFE_ASSERT(textureId != 0);


+ 69
- 0
dgl/src/OpenGL3.cpp View File

@@ -562,6 +562,70 @@ void OpenGLImage::drawAt(const GraphicsContext& context, const Point<int>& pos)
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }


#ifdef DGL_USE_GLES
ImageFormat OpenGLImage::getFormat() const noexcept
{
switch (format)
{
case kImageFormatBGR:
return kImageFormatRGB;
case kImageFormatBGRA:
return kImageFormatRGBA;
default:
return format;
}
}

const char* OpenGLImage::getRawData() const noexcept
{
if (rawDataLast != rawData)
{
if (format == kImageFormatBGR || format == kImageFormatBGRA)
{
const uint w = size.getWidth();
const uint h = size.getHeight();

std::free(convertedData);

if (format == kImageFormatBGR)
{
convertedData = static_cast<char*>(std::malloc(sizeof(char) * 3 * w * h));
for (int i = 0; i < w * h; ++i)
{
convertedData[i * 3 + 0] = rawData[i * 3 + 2];
convertedData[i * 3 + 1] = rawData[i * 3 + 1];
convertedData[i * 3 + 2] = rawData[i * 3 + 0];
}
}
else
{
convertedData = static_cast<char*>(std::malloc(sizeof(char) * 4 * w * h));
for (int i = 0; i < w * h; ++i)
{
convertedData[i * 4 + 0] = rawData[i * 4 + 2];
convertedData[i * 4 + 1] = rawData[i * 4 + 1];
convertedData[i * 4 + 2] = rawData[i * 4 + 0];
convertedData[i * 4 + 3] = rawData[i * 4 + 3];
}
}
}
else
{
std::free(convertedData);
convertedData = nullptr;
}

rawDataLast = rawData;
}

return
#ifdef DGL_USE_GLES
convertedData != nullptr ? convertedData :
#endif
rawData;
}
#endif

#ifdef DGL_ALLOW_DEPRECATED_METHODS #ifdef DGL_ALLOW_DEPRECATED_METHODS
void OpenGLImage::draw() void OpenGLImage::draw()
{ {
@@ -634,6 +698,9 @@ void ImageBaseKnob<OpenGLImage>::onDisplay()
DISTRHO_SAFE_ASSERT_RETURN(imageFormat != kImageFormatBGR && imageFormat != kImageFormatBGRA,); DISTRHO_SAFE_ASSERT_RETURN(imageFormat != kImageFormatBGR && imageFormat != kImageFormatBGRA,);
#endif #endif


glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

const GLfloat color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
glUniform4fv(gl3context.color, 1, color); glUniform4fv(gl3context.color, 1, color);


@@ -748,6 +815,8 @@ void ImageBaseKnob<OpenGLImage>::onDisplay()
glUniform1i(gl3context.usingTexture, 0); glUniform1i(gl3context.usingTexture, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);

glDisable(GL_BLEND);
} }


template class ImageBaseKnob<OpenGLImage>; template class ImageBaseKnob<OpenGLImage>;


+ 4
- 4
dgl/src/nanovg/nanovg_gl.h View File

@@ -834,10 +834,10 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im
tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 4 * w * h); tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 4 * w * h);
for (int i = 0; i < w * h; ++i) for (int i = 0; i < w * h; ++i)
{ {
tex->data[i*3+0] = data[i*3+3];
tex->data[i*3+1] = data[i*3+2];
tex->data[i*3+2] = data[i*3+1];
tex->data[i*3+3] = data[i*3+0];
tex->data[i*4+0] = data[i*4+2];
tex->data[i*4+1] = data[i*4+1];
tex->data[i*4+2] = data[i*4+0];
tex->data[i*4+3] = data[i*4+3];
} }
data = tex->data; data = tex->data;
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);


Loading…
Cancel
Save