@@ -707,6 +707,99 @@ void GL_VertexAttribPointers( uint32_t attribBits )
707707 }
708708}
709709
710+ static GLint GL_ToSRGB ( GLint internalFormat, bool isSRGB )
711+ {
712+ if ( !isSRGB )
713+ {
714+ return internalFormat;
715+ }
716+
717+ auto convert = []( GLint format )
718+ {
719+ switch ( format )
720+ {
721+ #if 0 // Not used in the code base.
722+ /* EXT_texture_sRGB_R8 extension.
723+ See: https://github.com/KhronosGroup/OpenGL-Registry/blob/main/extensions/EXT/EXT_texture_sRGB_R8.txt */
724+ case GL_RED:
725+ return GL_SR8_EXT;
726+ #endif
727+ case GL_RGB:
728+ return GL_SRGB;
729+ case GL_RGBA:
730+ return GL_SRGB_ALPHA;
731+ case GL_RGB8:
732+ return GL_SRGB8;
733+ case GL_RGBA8:
734+ return GL_SRGB8_ALPHA8;
735+ #if 0 // Internal formats, should not be used directly.
736+ case GL_COMPRESSED_RGB:
737+ return GL_COMPRESSED_SRGB;
738+ case GL_COMPRESSED_RGBA:
739+ return GL_COMPRESSED_SRGB_ALPHA;
740+ #endif
741+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
742+ return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
743+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
744+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
745+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
746+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
747+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
748+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
749+ #if 0 // Not used in the codebase,
750+ /* Core 4.2, ARB_texture_compression_bptc extension.
751+ See: https://github.com/KhronosGroup/OpenGL-Registry/blob/main/extensions/ARB/ARB_texture_compression_bptc.txt */
752+ case GL_COMPRESSED_RGBA_BPTC_UNORM:
753+ return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
754+ #endif
755+ default :
756+ return format;
757+ }
758+ };
759+
760+ GLint finalFormat = convert ( internalFormat );
761+
762+ if ( finalFormat == internalFormat )
763+ {
764+ Log::Warn ( " Missing sRGB conversion for GL format: %0#x" , internalFormat );
765+ }
766+ else
767+ {
768+ Log::Debug ( " Using sRGB GL format: %0#x" , finalFormat );
769+ }
770+
771+ return finalFormat;
772+ }
773+
774+ void GL_TexImage2D ( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *data, bool isSRGB )
775+ {
776+ GLint finalFormat = GL_ToSRGB ( internalFormat, isSRGB );
777+
778+ glTexImage2D ( target, level, finalFormat, width, height, border, format, type, data );
779+
780+ }
781+
782+ void GL_TexImage3D ( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *data, bool isSRGB )
783+ {
784+ GLint finalFormat = GL_ToSRGB ( internalFormat, isSRGB );
785+
786+ glTexImage3D ( target, level, finalFormat, width, height, depth, border, format, type, data );
787+ }
788+
789+ void GL_CompressedTexImage2D ( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data, bool isSRGB )
790+ {
791+ GLint finalFormat = GL_ToSRGB ( internalFormat, isSRGB );
792+
793+ glCompressedTexImage2D ( target, level, finalFormat, width, height, border, imageSize, data );
794+ }
795+
796+ void GL_CompressedTexSubImage3D ( GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLsizei size, const void *data, bool isSRGB )
797+ {
798+ GLint finalFormat = GL_ToSRGB ( internalFormat, isSRGB );
799+
800+ glCompressedTexSubImage3D ( target, level, xOffset, yOffset, zOffset, width, height, depth, finalFormat, size, data );
801+ }
802+
710803/*
711804================
712805RB_Hyperspace
@@ -1535,6 +1628,8 @@ void RB_CameraPostFX() {
15351628
15361629 gl_cameraEffectsShader->SetUniform_InverseGamma ( 1.0 / r_gamma->value );
15371630
1631+ gl_cameraEffectsShader->SetUniform_SRGB ( tr.worldLinearizeTexture );
1632+
15381633 const bool tonemap = r_toneMapping.Get () && r_highPrecisionRendering.Get () && glConfig2.textureFloatAvailable ;
15391634 if ( tonemap ) {
15401635 vec4_t tonemapParms { r_toneMappingContrast.Get (), r_toneMappingHighlightsCompressionSpeed.Get () };
@@ -2668,12 +2763,24 @@ void RE_UploadCinematic( int cols, int rows, const byte *data, int client, bool
26682763 GL_Bind ( tr.cinematicImage [ client ] );
26692764
26702765 // if the scratchImage isn't in the format we want, specify it as a new texture
2766+ /* HACK: This also detects we start playing a video to set the appropriate colorspace
2767+ because this assumes a video cannot have a 1×1 size (the RoQ format expects the size
2768+ to be a multiples of 4). */
26712769 if ( cols != tr.cinematicImage [ client ]->width || rows != tr.cinematicImage [ client ]->height )
26722770 {
26732771 tr.cinematicImage [ client ]->width = tr.cinematicImage [ client ]->uploadWidth = cols;
26742772 tr.cinematicImage [ client ]->height = tr.cinematicImage [ client ]->uploadHeight = rows;
26752773
2676- glTexImage2D ( GL_TEXTURE_2D, 0 , GL_RGB8, cols, rows, 0 , GL_RGBA, GL_UNSIGNED_BYTE, data );
2774+ bool isSRGB = tr.worldLinearizeTexture ;
2775+
2776+ // Makes sure listImages lists the colorspace properly.
2777+ if ( isSRGB )
2778+ {
2779+ tr.cinematicImage [ client ]->bits |= IF_SRGB;
2780+ }
2781+ // No need to delete the bit otherwise because R_InitImages() is called at every map load.
2782+
2783+ GL_TexImage2D ( GL_TEXTURE_2D, 0 , GL_RGB8, cols, rows, 0 , GL_RGBA, GL_UNSIGNED_BYTE, data, isSRGB );
26772784
26782785 glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
26792786 glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -2903,7 +3010,10 @@ const RenderCommand *Poly2dCommand::ExecuteSelf( ) const
29033010 tess.verts [ tess.numVertexes ].texCoords [ 0 ] = verts[ i ].st [ 0 ];
29043011 tess.verts [ tess.numVertexes ].texCoords [ 1 ] = verts[ i ].st [ 1 ];
29053012
2906- tess.verts [ tess.numVertexes ].color = Color::Adapt ( verts[ i ].modulate );
3013+ Color::Color32Bit color = Color::Adapt ( verts[ i ].modulate );
3014+ color = tr.convertColorFromSRGB ( color );
3015+ tess.verts [ tess.numVertexes ].color = color;
3016+
29073017 tess.numVertexes ++;
29083018 }
29093019
@@ -2960,7 +3070,10 @@ const RenderCommand *Poly2dIndexedCommand::ExecuteSelf( ) const
29603070 tess.verts [ tess.numVertexes ].texCoords [ 0 ] = verts[ i ].st [ 0 ];
29613071 tess.verts [ tess.numVertexes ].texCoords [ 1 ] = verts[ i ].st [ 1 ];
29623072
2963- tess.verts [ tess.numVertexes ].color = Color::Adapt ( verts[ i ].modulate );
3073+ Color::Color32Bit color = Color::Adapt ( verts[ i ].modulate );
3074+ color = tr.convertColorFromSRGB ( color );
3075+ tess.verts [ tess.numVertexes ].color = color;
3076+
29643077 tess.numVertexes ++;
29653078 }
29663079
0 commit comments