SFML/SFML

All `Texture`s loaded from `.bmp` files render only monochrome+transparent, with RGBA colors flipped (on `RectangleShape`s)

metaleap opened this issue · 4 comments

Prerequisite Checklist

Describe your issue here

First described in this forum-thread post: any Texture::loadFromFile-loaded .bmp Textures render colorless (when bound to a RectangleShape — my only scenario here).

It isn't just that bitmap file: I have tried others present in my system (hardly any of course... only ones found were from golang.org/x/image/testdata). It just happens with all of them, and multiple image-viewers on my system all display all of them in the correct RGB coloring.

The issue is quite-possibly this. Doing a repo-wide code search, there's no sight of any GL_BGR in the SFML master branch (and plenty for GL_RGB naturally). Has anyone ever used a (non-B/W) .bmp file successfully? =) It is a rarely-used legacy format after all.

Your Environment

  • OS / distro / window manager: VoidLinux x86_64, i3wm
  • SFML version: 2.6.1 (system-wide distro-provided package)
  • Compiler / toolchain: g++ 12.2.0
  • Special compiler / CMake flags: --debug -std=c++20 -march=native -O0

Steps to reproduce

sf::RectangleShape myRect;
myRect.setSize({512, 256});
myRect.setOrigin(0, 0);
myRect.setPosition(0, 0);
myRect.setFillColor(sf::Color::Green);

sf::Texture myTex;
myTex.loadFromFile("/home/myname/some/local/bitmap.bmp");
myRect.setTexture(&myTex);
const auto size_tex = myTex.getSize();
myRect.setTextureRect(sf::IntRect {0, 0, (int)(size_tex.x), (int)(size_tex.y)});

window.draw(myRect);

Expected behavior

Textured rectangle shows the image in its original RGB colors, as all sorts of locally-installed image viewers do. Example:

screenshot

Actual behavior

Textured rectangle shows the image as transparent-monochrome: the rectangle's background fill color (green) is the backdrop and actual pixels show as black. Like so:
screenshot

We have unit tests that load a BMP image and test a few pixel values, one of which is a non-greyscale pixel. That much is working. That seems to reinforce your theory that the problem lies not in image loading but rather with how images are drawn to the screen.

@binary1248 What do you think of this?

We have unit tests that load a BMP image and test a few pixel values, one of which is a non-greyscale pixel. That much is working.

Good to know, yes indeed that makes the GL_BGR hypothesis most likely I guess.

Btw. I guess it isn't really monochromely rendering, just showed that way to me with the .bmps I did have, plus the Green rect bgcolor. Now with Cyan instead, I can tell that whites show as Cyan (ie. full alpha), blues and greens are preserved, and yellows show as stark over-green, likely blending the Cyan in. (I'll best go with a White rect bgcolor to really analyze the generated .bmps here =)

This is expected because of this: myRect.setFillColor(sf::Color::Green);

See setFillColor documentation

This color is modulated (multiplied) with the shape's texture if any.

True that must be it actually! Since I'm getting correct blues greens and yellows (aka reds) here, it's all just due to the multiplication. Thanks much @kimci86 and @ChrisThrasher . I do remember reading that part of the docs earlier, but it clearly didn't resurface in the here-and-now..