Add support for the GL_RED format, use it, also rework format detection
- tr_image: rework the alpha detection
- renderer: implement and detect RED and RG images
- renderer: introduce and use IF_NOALPHA
- tr_backend: fix a comment
- tr_image: flag glyph image with IF_ALPHA
- sdl_glimp: fix the EXT/ARB texture_rg confusion
- tr_image: document the GL_RGB format
- tr_image: add some GL format checks and asserts
- tr_image: reshape the cinematic image generation a bit
- tr_image: reshape the default image painting a bit
- tr_image: make some iterators more local
Previous message:
- tr_image: reword the fog generation code That's just beautifying, following patches are written above this
- tr_image: store the fog alpha channel in red one Imported from #1730 but without the colorspace-related HACKs
- renderer: add support for the GL_RED image format Imported from #1730
- tr_image: upload _fog image as GL_RED Imported from #1730
- tr_image: upload _black, _red and _blackCube images as GL_RED
- tr_image: rework the alpha detection
- tr_image: detect RED images
- renderer: introduce and use IF_NOALPHA Useful for when we know in advance an image has no alpha channel
- tr_image: do not rely on previously set data for _cinematic, make sure it cannot be detected as RED
- tr_backend: fix a comment
Actually
GL_COMPRESSED_*formats can be used (they let the driver decide), but we don't use them.
We may also upload standalone height maps as GL_RED too, unfortunately doing that will loose precision since as far as I know the DXT storage is 5:6:5 and then the red component features less bits than the green one.
We may also upload standalone height maps as
GL_REDtoo, unfortunately doing that will loose precision since as far as I know the DXT storage is5:6:5and then the red component features less bits than the green one.
I'm doing the same mistake again… DXT images can't be uploaded as GL_RED. 🤣
The fog image is pretty pointless, all it really does it calculate sqrt(x). We should just do that in GLSL. I think it only exists because someone ported the code from GL1 in an overly mechanical way.
The fog image is pretty pointless, all it really does it calculate
sqrt(x).
Oh, that's interesting! Would you also know what computation to expect when blending the linear way? Or maybe it should have been sqrt() in linear space but the naive blending did garbage and we're accustomed to it?
We should just do that in GLSL. I think it only exists because someone ported the code from GL1 in an overly mechanical way.
If we can that would be nice.
Oh, that's interesting! Would you also know what computation to expect when blending the linear way? Or maybe it should have been
sqrt()in linear space but the naive blending did garbage and we're accustomed to it?
Square root doesn't make much sense as a model for the fog; probably they just tried random functions and picked something that looked OK. Instead of sqrt(a*x), 1 - exp(b*x) would be an obvious model to use (as if the fog is formed from layered alpha blending). a/b is a constant based on the fog density. You can make these functions match up somewhat using appropriate constants: https://www.desmos.com/calculator/abvkogdqzy
That looks ready to me.
I fixed an non-optimal code path, it was testing for RED before testing for ALPHA, meaning a red texture with an opaque alpha channel was only detected as RGB, not as RED. Now fixed:
]/listImages *red*
-------------------------------------------------------------------------
num width height layers mm type format space wrap.t wrap.s name
-------------------------------------------------------------------------
3 8 8 1 no 2D R8 linear t.rept s.rept _red
99 64 64 1 no 2D DXT5 linear t.clmp s.clmp emoticons/featured
119 256 256 1 yes 2D RGB8 linear t.rept s.rept textures/pulse/metal-red.tga
120 256 256 1 yes 2D RGB8 linear t.rept s.rept textures/pulse/metal-red
158 256 256 1 yes 2D RGB8 linear t.rept s.rept textures/pulse/e8base_red
159 256 256 1 yes 2D RGB8 linear t.rept s.rept textures/pulse/e8base_red.tga
233 16 16 1 no 2D R8 linear t.rept s.rept textures/pulse/red16x16.tga
262 16 16 1 yes 2D DXT1 linear t.rept s.rept gfx/buildables/common/redbuild
281 16 256 1 yes 2D RGB8 linear t.rept s.rept gfx/cgrading/red-only
-------------------------------------------------------------------------
0 total texels (not including mipmaps)
1.01 MB total image memory (estimated)
689 total images
-------------------------------------------------------------------------
Unrelated to that branch, but I notice we have both textures/pulse/metal-red.tga and textures/pulse/metal-red loaded… that doesn't look right. That should be investigated separately.
Very good:
2 8 8 1 no 2D R8 linear t.rept s.rept _black
3 8 8 1 no 2D R8 linear t.rept s.rept _red
39 256 32 1 yes 2D R8 linear t.clmp s.clmp _fog
47 32 32 6 no CUBE R8 linear t.eclmp s.eclmp _blackCube
519 32 32 1 yes 2D R8 linear t.rept s.rept textures/atcshd/bulb_red.tga
522 64 64 1 yes 2D R8 linear t.rept s.rept textures/atcshd/black
This now also support and detect RG textures, and use explicit GL_R8 instead of GL_RED when supported.
]/listImages *16x16*
-------------------------------------------------------------------------
num width height layers mm type format space wrap.t wrap.s name
-------------------------------------------------------------------------
205 16 16 1 no 2D R8 linear t.rept s.rept textures/pulse/black16x16.tga
280 16 16 1 yes 2D RGB8 linear t.rept s.rept textures/pulse/white16x16.tga
283 16 16 1 no 2D RGB8 linear t.rept s.rept textures/pulse/white16x16.tga
291 16 16 1 yes 2D R8 linear t.rept s.rept textures/pulse/black16x16.tga
296 16 16 1 no 2D R8 linear t.rept s.rept textures/pulse/red16x16.tga
302 16 16 1 no 2D RG8 linear t.rept s.rept textures/pulse/green16x16.tga
-------------------------------------------------------------------------
0 total texels (not including mipmaps)
0.00 MB total image memory (estimated)
752 total images
-------------------------------------------------------------------------
So yes there was a pre-existing confusion on master related to some RG extension but it was less problematic than what I thought at first, it was just a naming mess.
Detection works well:
]/listImages *shared_colors*
-------------------------------------------------------------------------
num width height layers mm type format space wrap.t wrap.s name
-------------------------------------------------------------------------
614 1 1 1 yes 2D R8 sRGB t.rept s.rept textures/shared_colors_src/black_d
615 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/gray_d
616 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/white_d
617 1 1 1 yes 2D R8 sRGB t.rept s.rept textures/shared_colors_src/red_d
618 1 1 1 yes 2D RG8 sRGB t.rept s.rept textures/shared_colors_src/orange_d
619 1 1 1 yes 2D RG8 sRGB t.rept s.rept textures/shared_colors_src/yellow_d
620 1 1 1 yes 2D RG8 sRGB t.rept s.rept textures/shared_colors_src/chartreuse_d
621 1 1 1 yes 2D RG8 sRGB t.rept s.rept textures/shared_colors_src/green_d
622 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/spring_d
623 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/cyan_d
624 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/azure_d
625 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/blue_d
626 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/violet_d
627 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/magenta_d
628 1 1 1 yes 2D RGB8 sRGB t.rept s.rept textures/shared_colors_src/rose_d
629 1 1 1 yes 2D RGBA8 sRGB t.rept s.rept textures/shared_colors_src/transparent_d
-------------------------------------------------------------------------
0 total texels (not including mipmaps)
0.00 MB total image memory (estimated)
630 total images
-------------------------------------------------------------------------
I found a bug in the code in master where we only iterate the first layer of an image for detecting the format. Now fixed.
I noticed that would modify an undocumented feature of _black, previously it was usable to make a transparent texture:
transparent
{
map _black
blend blend
}
Because all its channels were set to 0, including the alpha one.
But when stored as RED the alpha channel is opaque (so, 1).
But I have seen no map in the whole betaserv corpus that used any _black, *black, $black, $blackimage keywords at all, so even not used as trick with blend to get a fully transparent texture.
Actually it bugged me that the black image was not opaque black.
Fog image stuff can be dropped.
Do we really need to have the _red image at all?
Yes we may purge those color variants.
This PR is expected to be rebased after #1804 is merged:
- https://github.com/DaemonEngine/Daemon/pull/1804
So this PR is currently not in mergeable state.
Detecting the RG images is less needed after we drop all the color image variants that are not white and black, as seen in:
- https://github.com/DaemonEngine/Daemon/pull/1804
- https://github.com/UnvanquishedAssets/tex-common_src.dpkdir/pull/9
Though, this can still be useful for optimizing the upload of legacy images from legacy paks, that are not DXT-compressed, and then for which we can detect if they use their blue channel or not.
This PR actually fixes a bug in detecting the alpha channel presence (it only looked for the first layer of an image).
This also adds IF_NOALPHA to skip the detection of the alpha channel when it is known the image is fully opaque, it already uses it for a bunch of builtin images.
Something not implemented in that PR is to flag images with IF_NOALPHA when they are part of a shader without blend functions, something we can do, but I'm postponing this. Especially, we may need some revamp to be done first, as some images are loaded before the stage is entirely parsed (and then the blending is unknown). But that's likely something I want to do later.
Also something I want to do later is to reimplement the GL compression of non-DXT-compressed images, for use with the legacy assets full of non-crunched JPG or TGA files. I actually have a working branch for that, based on an older version of this branch, but then again that's for later.
Some commits do some beautifying or improve consistency with other parts of the code around to ease the reading.
How much memory do we expect to save from this red image detection?
That's one of my concern. Now that we ditched the color images, and after we will use q3shader code for common colors instead of pixmaps, not only RG detection but also RED detection becomes less useful.
This can still benefit some legacy maps, for example the pulse maps has some plain red and green images for displaying the door closed/open status in the control room, legacy maps may have things like that, pure black, red or green images, the win isn't very big.
Yeah I don't think the complexity is worth it if we are going to only save like 10 KB or something. The color detection code is rather convoluted.