From 1fcdd29bf9114d796e6a31a7dcee9d34a5e06137 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 15 May 2025 19:23:32 +0100 Subject: [PATCH] OpenGL: Return image BitmapData in JUCE order rather than native order JUCE convention is that BitmapData holds the lines of the image ordered from top to bottom, but OpenGL orders lines in the reverse direction. By returning a negative line stride, we can iterate lines in the expected order as long as we always increment the current pointer position by the line stride after processing each line. --- modules/juce_opengl/opengl/juce_OpenGLImage.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp index 14851d693e..e36d77c5ca 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp @@ -85,11 +85,15 @@ public: auto releaser = std::make_unique (this, Rectangle { x, y, bitmapData.width, bitmapData.height }, mode); - bitmapData.data = (uint8*) releaser->data.get(); - bitmapData.size = (size_t) bitmapData.width - * (size_t) bitmapData.height - * sizeof (PixelARGB); - bitmapData.lineStride = (bitmapData.width * bitmapData.pixelStride + 3) & ~3; + const auto unsignedLineStride = (((size_t) bitmapData.width * (size_t) bitmapData.pixelStride + 3) & ~((size_t) 3)); + bitmapData.lineStride = -((int) unsignedLineStride); + bitmapData.size = (size_t) bitmapData.height * unsignedLineStride; + + // OpenGL mapped textures are stored in lines from bottom-to-top, but JUCE expects lines to + // be ordered top-to-bottom. + // The data pointer points to the beginning of the *last* line, and lineStride steps backwards + // through the lines. + bitmapData.data = (uint8*) releaser->data.get() + (ptrdiff_t) bitmapData.size + (ptrdiff_t) bitmapData.lineStride; bitmapData.dataReleaser = std::move (releaser);