mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Added LoadEXR using tinyexr, LoadHDR using stb_image
This commit is contained in:
parent
7598bae2d4
commit
779534626f
15 changed files with 33402 additions and 92 deletions
|
@ -489,6 +489,12 @@ file(GLOB IRRXML_SOURCES libs/irrxml/src/*.cpp)
|
|||
file(GLOB IMGUI_INCLUDES libs/imgui/*.h)
|
||||
file(GLOB IMGUI_SOURCES libs/imgui/*.cpp)
|
||||
|
||||
file(GLOB STB_INCLUDES libs/stb/*.h)
|
||||
|
||||
file(GLOB MESA_INCLUDES libs/mesa/*.h)
|
||||
|
||||
file(GLOB TINYEXR_INCLUDES libs/tinyexr/*.h)
|
||||
|
||||
file(GLOB MIKKTSPACE_INCLUDES libs/mikktspace/*.h)
|
||||
file(GLOB MIKKTSPACE_SOURCES libs/mikktspace/*.c)
|
||||
|
||||
|
@ -708,7 +714,6 @@ file(GLOB UI_SOURCES ui/*.cpp)
|
|||
file(GLOB SWF_INCLUDES swf/*.h)
|
||||
file(GLOB SWF_SOURCES swf/*.cpp)
|
||||
|
||||
|
||||
set(GAMED3XP_INCLUDES
|
||||
d3xp/Achievements.h
|
||||
d3xp/Actor.h
|
||||
|
@ -1111,6 +1116,12 @@ source_group("libs\\irrxml" FILES ${IRRXML_SOURCES})
|
|||
source_group("libs\\imgui" FILES ${IMGUI_INCLUDES})
|
||||
source_group("libs\\imgui" FILES ${IMGUI_SOURCES})
|
||||
|
||||
source_group("libs\\stb" FILES ${STB_INCLUDES})
|
||||
|
||||
source_group("libs\\mesa" FILES ${MESA_INCLUDES})
|
||||
|
||||
source_group("libs\\tinyexr" FILES ${TINYEXR_INCLUDES})
|
||||
|
||||
source_group("libs\\mikktspace" FILES ${MIKKTSPACE_INCLUDES})
|
||||
source_group("libs\\mikktspace" FILES ${MIKKTSPACE_SOURCES})
|
||||
|
||||
|
@ -1300,6 +1311,9 @@ set(RBDOOM3_INCLUDES
|
|||
${IRRXML_INCLUDES}
|
||||
${FRAMEWORK_IMGUI_INCLUDES}
|
||||
${IMGUI_INCLUDES}
|
||||
${STB_INCLUDES}
|
||||
${MESA_INCLUDES}
|
||||
${TINYEXR_INCLUDES}
|
||||
${MIKKTSPACE_INCLUDES}
|
||||
${JPEG_INCLUDES}
|
||||
${PNG_INCLUDES}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
astyle.exe -v --formatted --options=astyle-options.ini --exclude="libs" --exclude="extern" --recursive *.h
|
||||
astyle.exe -v --formatted --options=astyle-options.ini --exclude="libs" --exclude="extern" --exclude="d3xp/gamesys/SysCvar.cpp" --exclude="d3xp/gamesys/Callbacks.cpp" --exclude="sys/win32/win_cpu.cpp" --exclude="sys/win32/win_main.cpp" --recursive *.cpp
|
||||
|
||||
astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.h
|
||||
astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.cpp
|
||||
REM astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.h
|
||||
REM astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.cpp
|
||||
|
||||
REM astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/stb/*.h
|
||||
REM astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/tinyexr/*.h
|
||||
|
||||
astyle.exe -v -Q --options=astyle-options.ini --recursive ../base/renderprogs/*.hlsl
|
||||
|
||||
|
|
277
neo/libs/mesa/format_r11g11b10f.h
Normal file
277
neo/libs/mesa/format_r11g11b10f.h
Normal file
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Based on code from The OpenGL Programming Guide / 7th Edition, Appendix J.
|
||||
* Available here: http://www.opengl-redbook.com/appendices/
|
||||
* The algorithm in the book contains a bug though, which is fixed in the code
|
||||
* below.
|
||||
*/
|
||||
|
||||
#ifndef FORMAT_R11G11B10F_H
|
||||
#define FORMAT_R11G11B10F_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define UF11(e, m) ((e << 6) | (m))
|
||||
#define UF11_EXPONENT_BIAS 15
|
||||
#define UF11_EXPONENT_BITS 0x1F
|
||||
#define UF11_EXPONENT_SHIFT 6
|
||||
#define UF11_MANTISSA_BITS 0x3F
|
||||
#define UF11_MANTISSA_SHIFT (23 - UF11_EXPONENT_SHIFT)
|
||||
#define UF11_MAX_EXPONENT (UF11_EXPONENT_BITS << UF11_EXPONENT_SHIFT)
|
||||
|
||||
#define UF10(e, m) ((e << 5) | (m))
|
||||
#define UF10_EXPONENT_BIAS 15
|
||||
#define UF10_EXPONENT_BITS 0x1F
|
||||
#define UF10_EXPONENT_SHIFT 5
|
||||
#define UF10_MANTISSA_BITS 0x1F
|
||||
#define UF10_MANTISSA_SHIFT (23 - UF10_EXPONENT_SHIFT)
|
||||
#define UF10_MAX_EXPONENT (UF10_EXPONENT_BITS << UF10_EXPONENT_SHIFT)
|
||||
|
||||
#define F32_INFINITY 0x7f800000
|
||||
|
||||
static inline uint32_t f32_to_uf11( float val )
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
uint32_t ui;
|
||||
} f32 = {val};
|
||||
|
||||
uint16_t uf11 = 0;
|
||||
|
||||
/* Decode little-endian 32-bit floating-point value */
|
||||
int sign = ( f32.ui >> 16 ) & 0x8000;
|
||||
/* Map exponent to the range [-127,128] */
|
||||
int exponent = ( ( f32.ui >> 23 ) & 0xff ) - 127;
|
||||
int mantissa = f32.ui & 0x007fffff;
|
||||
|
||||
if( exponent == 128 ) /* Infinity or NaN */
|
||||
{
|
||||
/* From the GL_EXT_packed_float spec:
|
||||
*
|
||||
* "Additionally: negative infinity is converted to zero; positive
|
||||
* infinity is converted to positive infinity; and both positive and
|
||||
* negative NaN are converted to positive NaN."
|
||||
*/
|
||||
uf11 = UF11_MAX_EXPONENT;
|
||||
if( mantissa )
|
||||
{
|
||||
uf11 |= 1; /* NaN */
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sign )
|
||||
{
|
||||
uf11 = 0; /* 0.0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( sign )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if( val > 65024.0f )
|
||||
{
|
||||
/* From the GL_EXT_packed_float spec:
|
||||
*
|
||||
* "Likewise, finite positive values greater than 65024 (the maximum
|
||||
* finite representable unsigned 11-bit floating-point value) are
|
||||
* converted to 65024."
|
||||
*/
|
||||
uf11 = UF11( 30, 63 );
|
||||
}
|
||||
else if( exponent > -15 ) /* Representable value */
|
||||
{
|
||||
exponent += UF11_EXPONENT_BIAS;
|
||||
mantissa >>= UF11_MANTISSA_SHIFT;
|
||||
uf11 = exponent << UF11_EXPONENT_SHIFT | mantissa;
|
||||
}
|
||||
|
||||
return uf11;
|
||||
}
|
||||
|
||||
static inline float uf11_to_f32( uint16_t val )
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
uint32_t ui;
|
||||
} f32;
|
||||
|
||||
int exponent = ( val & 0x07c0 ) >> UF11_EXPONENT_SHIFT;
|
||||
int mantissa = ( val & 0x003f );
|
||||
|
||||
f32.f = 0.0;
|
||||
|
||||
if( exponent == 0 )
|
||||
{
|
||||
if( mantissa != 0 )
|
||||
{
|
||||
const float scale = 1.0 / ( 1 << 20 );
|
||||
f32.f = scale * mantissa;
|
||||
}
|
||||
}
|
||||
else if( exponent == 31 )
|
||||
{
|
||||
f32.ui = F32_INFINITY | mantissa;
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale, decimal;
|
||||
exponent -= 15;
|
||||
if( exponent < 0 )
|
||||
{
|
||||
scale = 1.0f / ( 1 << -exponent );
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = ( float )( 1 << exponent );
|
||||
}
|
||||
decimal = 1.0f + ( float ) mantissa / 64;
|
||||
f32.f = scale * decimal;
|
||||
}
|
||||
|
||||
return f32.f;
|
||||
}
|
||||
|
||||
static inline uint32_t f32_to_uf10( float val )
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
uint32_t ui;
|
||||
} f32 = {val};
|
||||
|
||||
uint16_t uf10 = 0;
|
||||
|
||||
/* Decode little-endian 32-bit floating-point value */
|
||||
int sign = ( f32.ui >> 16 ) & 0x8000;
|
||||
/* Map exponent to the range [-127,128] */
|
||||
int exponent = ( ( f32.ui >> 23 ) & 0xff ) - 127;
|
||||
int mantissa = f32.ui & 0x007fffff;
|
||||
|
||||
if( exponent == 128 )
|
||||
{
|
||||
/* From the GL_EXT_packed_float spec:
|
||||
*
|
||||
* "Additionally: negative infinity is converted to zero; positive
|
||||
* infinity is converted to positive infinity; and both positive and
|
||||
* negative NaN are converted to positive NaN."
|
||||
*/
|
||||
uf10 = UF10_MAX_EXPONENT;
|
||||
if( mantissa )
|
||||
{
|
||||
uf10 |= 1; /* NaN */
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sign )
|
||||
{
|
||||
uf10 = 0; /* 0.0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( sign )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if( val > 64512.0f )
|
||||
{
|
||||
/* From the GL_EXT_packed_float spec:
|
||||
*
|
||||
* "Likewise, finite positive values greater than 64512 (the maximum
|
||||
* finite representable unsigned 10-bit floating-point value) are
|
||||
* converted to 64512."
|
||||
*/
|
||||
uf10 = UF10( 30, 31 );
|
||||
}
|
||||
else if( exponent > -15 ) /* Representable value */
|
||||
{
|
||||
exponent += UF10_EXPONENT_BIAS;
|
||||
mantissa >>= UF10_MANTISSA_SHIFT;
|
||||
uf10 = exponent << UF10_EXPONENT_SHIFT | mantissa;
|
||||
}
|
||||
|
||||
return uf10;
|
||||
}
|
||||
|
||||
static inline float uf10_to_f32( uint16_t val )
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
uint32_t ui;
|
||||
} f32;
|
||||
|
||||
int exponent = ( val & 0x03e0 ) >> UF10_EXPONENT_SHIFT;
|
||||
int mantissa = ( val & 0x001f );
|
||||
|
||||
f32.f = 0.0;
|
||||
|
||||
if( exponent == 0 )
|
||||
{
|
||||
if( mantissa != 0 )
|
||||
{
|
||||
const float scale = 1.0 / ( 1 << 19 );
|
||||
f32.f = scale * mantissa;
|
||||
}
|
||||
}
|
||||
else if( exponent == 31 )
|
||||
{
|
||||
f32.ui = F32_INFINITY | mantissa;
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale, decimal;
|
||||
exponent -= 15;
|
||||
if( exponent < 0 )
|
||||
{
|
||||
scale = 1.0f / ( 1 << -exponent );
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = ( float )( 1 << exponent );
|
||||
}
|
||||
decimal = 1.0f + ( float ) mantissa / 32;
|
||||
f32.f = scale * decimal;
|
||||
}
|
||||
|
||||
return f32.f;
|
||||
}
|
||||
|
||||
static inline uint32_t float3_to_r11g11b10f( const float rgb[3] )
|
||||
{
|
||||
return ( f32_to_uf11( rgb[0] ) & 0x7ff ) |
|
||||
( ( f32_to_uf11( rgb[1] ) & 0x7ff ) << 11 ) |
|
||||
( ( f32_to_uf10( rgb[2] ) & 0x3ff ) << 22 );
|
||||
}
|
||||
|
||||
static inline void r11g11b10f_to_float3( uint32_t rgb, float retval[3] )
|
||||
{
|
||||
retval[0] = uf11_to_f32( rgb & 0x7ff );
|
||||
retval[1] = uf11_to_f32( ( rgb >> 11 ) & 0x7ff );
|
||||
retval[2] = uf10_to_f32( ( rgb >> 22 ) & 0x3ff );
|
||||
}
|
||||
|
||||
#endif /* FORMAT_R11G11B10F_H */
|
10242
neo/libs/stb/stb_image.h
Normal file
10242
neo/libs/stb/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
2863
neo/libs/stb/stb_image_resize.h
Normal file
2863
neo/libs/stb/stb_image_resize.h
Normal file
File diff suppressed because it is too large
Load diff
2010
neo/libs/stb/stb_image_write.h
Normal file
2010
neo/libs/stb/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load diff
17730
neo/libs/tinyexr/tinyexr.h
Normal file
17730
neo/libs/tinyexr/tinyexr.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -249,6 +249,15 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
|
|||
img.data[ i ] = pic[ i ];
|
||||
}
|
||||
}
|
||||
else if( textureFormat == FMT_R11G11B10F )
|
||||
{
|
||||
// RB: copy it as it was a RGBA8 because of the same size
|
||||
img.Alloc( scaledWidth * scaledHeight * 4 );
|
||||
for( int i = 0; i < img.dataSize; i++ )
|
||||
{
|
||||
img.data[ i ] = pic[ i ];
|
||||
}
|
||||
}
|
||||
else if( textureFormat == FMT_RGBA16F )
|
||||
{
|
||||
img.Alloc( scaledWidth * scaledHeight * 8 );
|
||||
|
|
|
@ -100,6 +100,7 @@ enum textureFormat_t
|
|||
FMT_RGBA16F, // 64 bpp
|
||||
FMT_RGBA32F, // 128 bpp
|
||||
FMT_R32F, // 32 bpp
|
||||
FMT_R11G11B10F, // 32 bpp
|
||||
// RB end
|
||||
};
|
||||
|
||||
|
@ -226,6 +227,7 @@ typedef enum
|
|||
TD_RGBA16F,
|
||||
TD_RGBA32F,
|
||||
TD_R32F,
|
||||
TD_R11G11B10F, // memory efficient HDR RGB format with only 32bpp
|
||||
// RB end
|
||||
} textureUsage_t;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2012-2020 Robert Beckebans
|
||||
Copyright (C) 2012-2021 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -30,6 +30,18 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#pragma hdrstop
|
||||
#include "precompiled.h"
|
||||
|
||||
#undef strncmp
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../libs/stb/stb_image.h"
|
||||
|
||||
//#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
//#include "../libs/stb/stb_image_write.h"
|
||||
|
||||
#define TINYEXR_IMPLEMENTATION
|
||||
#include "../libs/tinyexr/tinyexr.h"
|
||||
|
||||
#include "../libs/mesa/format_r11g11b10f.h"
|
||||
|
||||
#include "RenderCommon.h"
|
||||
|
||||
|
@ -755,7 +767,7 @@ static void LoadPNG( const char* filename, unsigned char** pic, int* width, int*
|
|||
|
||||
png_read_update_info( pngPtr, infoPtr );
|
||||
|
||||
byte* out = ( byte* )R_StaticAlloc( pngWidth * pngHeight * 4 );
|
||||
byte* out = ( byte* )R_StaticAlloc( pngWidth * pngHeight * 4, TAG_IMAGE );
|
||||
|
||||
*pic = out;
|
||||
*width = pngWidth;
|
||||
|
@ -878,6 +890,100 @@ void R_WritePNG( const char* filename, const byte* data, int bytesPerPixel, int
|
|||
Mem_Free( buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
EXR LOADING
|
||||
|
||||
Interfaces with tinyexr
|
||||
=========================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=======================
|
||||
LoadEXR
|
||||
=======================
|
||||
*/
|
||||
static void LoadEXR( const char* filename, unsigned char** pic, int* width, int* height, ID_TIME_T* timestamp )
|
||||
{
|
||||
if( !pic )
|
||||
{
|
||||
fileSystem->ReadFile( filename, NULL, timestamp );
|
||||
return; // just getting timestamp
|
||||
}
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
// load the file
|
||||
const byte* fbuffer = NULL;
|
||||
int fileSize = fileSystem->ReadFile( filename, ( void** )&fbuffer, timestamp );
|
||||
if( !fbuffer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float* rgba;
|
||||
const char* err;
|
||||
|
||||
{
|
||||
int ret = LoadEXRFromMemory( &rgba, width, height, fbuffer, fileSize, &err );
|
||||
if( ret != 0 )
|
||||
{
|
||||
common->Error( "LoadEXR( %s ): %s\n", filename, err );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// dump file as .hdr for testing - this works
|
||||
{
|
||||
idStrStatic< MAX_OSPATH > hdrFileName = "test";
|
||||
//hdrFileName.AppendPath( filename );
|
||||
hdrFileName.SetFileExtension( ".hdr" );
|
||||
|
||||
int ret = stbi_write_hdr( hdrFileName.c_str(), *width, *height, 4, rgba );
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
return; // fail
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rgba )
|
||||
{
|
||||
int32 pixelCount = *width * *height;
|
||||
byte* out = ( byte* )R_StaticAlloc( pixelCount * 4, TAG_IMAGE );
|
||||
|
||||
*pic = out;
|
||||
|
||||
// convert to packed R11G11B10F as uint32 for each pixel
|
||||
|
||||
const float* src = rgba;
|
||||
byte* dst = out;
|
||||
for( int i = 0; i < pixelCount; i++ )
|
||||
{
|
||||
// read 3 floats and ignore the alpha channel
|
||||
float p[3];
|
||||
|
||||
p[0] = src[0];
|
||||
p[1] = src[1];
|
||||
p[2] = src[2];
|
||||
|
||||
// convert
|
||||
uint32_t value = float3_to_r11g11b10f( p );
|
||||
*( uint32_t* )dst = value;
|
||||
|
||||
src += 4;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
free( rgba );
|
||||
}
|
||||
|
||||
Mem_Free( ( void* )fbuffer );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_WriteEXR
|
||||
|
@ -1034,6 +1140,85 @@ void R_WriteEXR( const char* filename, const void* rgba16f, int channelsPerPixel
|
|||
}
|
||||
// RB end
|
||||
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
HDR LOADING
|
||||
|
||||
Interfaces with stb_image
|
||||
=========================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
=======================
|
||||
LoadHDR
|
||||
|
||||
RB: load floating point data from memory and convert it into packed R11G11B10F data
|
||||
=======================
|
||||
*/
|
||||
static void LoadHDR( const char* filename, unsigned char** pic, int* width, int* height, ID_TIME_T* timestamp )
|
||||
{
|
||||
if( !pic )
|
||||
{
|
||||
fileSystem->ReadFile( filename, NULL, timestamp );
|
||||
return; // just getting timestamp
|
||||
}
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
// load the file
|
||||
const byte* fbuffer = NULL;
|
||||
int fileSize = fileSystem->ReadFile( filename, ( void** )&fbuffer, timestamp );
|
||||
if( !fbuffer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32 numChannels;
|
||||
|
||||
float* rgba = stbi_loadf_from_memory( ( stbi_uc const* ) fbuffer, fileSize, width, height, &numChannels, 0 );
|
||||
|
||||
if( numChannels != 3 )
|
||||
{
|
||||
common->Error( "LoadHDR( %s ): HDR has not 3 channels\n", filename );
|
||||
}
|
||||
|
||||
if( rgba )
|
||||
{
|
||||
int32 pixelCount = *width * *height;
|
||||
byte* out = ( byte* )R_StaticAlloc( pixelCount * 4, TAG_IMAGE );
|
||||
|
||||
*pic = out;
|
||||
|
||||
// convert to packed R11G11B10F as uint32 for each pixel
|
||||
|
||||
const float* src = rgba;
|
||||
byte* dst = out;
|
||||
for( int i = 0; i < pixelCount; i++ )
|
||||
{
|
||||
// read 3 floats and ignore the alpha channel
|
||||
float p[3];
|
||||
|
||||
p[0] = src[0];
|
||||
p[1] = src[1];
|
||||
p[2] = src[2];
|
||||
|
||||
// convert
|
||||
uint32_t value = float3_to_r11g11b10f( p );
|
||||
*( uint32_t* )dst = value;
|
||||
|
||||
src += 4;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
free( rgba );
|
||||
}
|
||||
|
||||
Mem_Free( ( void* )fbuffer );
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
|
@ -1048,6 +1233,8 @@ static imageExtToLoader_t imageLoaders[] =
|
|||
{"png", LoadPNG},
|
||||
{"tga", LoadTGA},
|
||||
{"jpg", LoadJPG},
|
||||
{"exr", LoadEXR},
|
||||
{"hdr", LoadHDR},
|
||||
};
|
||||
|
||||
static const int numImageLoaders = sizeof( imageLoaders ) / sizeof( imageLoaders[0] );
|
||||
|
|
|
@ -1055,8 +1055,9 @@ void idImageManager::CreateIntrinsicImages()
|
|||
hellLoadingIconImage = ImageFromFile( "textures/loadingicon3", TF_DEFAULT, TR_CLAMP, TD_DEFAULT, CF_2D );
|
||||
|
||||
// RB begin
|
||||
defaultUACIrradianceCube = ImageFromFile( "env/UAC2_amb", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
defaultUACRadianceCube = ImageFromFile( "env/UAC2_spec", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
// FIXME change back to TF_DEFAULT
|
||||
defaultUACIrradianceCube = ImageFromFile( "env/UAC3_amb", TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
|
||||
defaultUACRadianceCube = ImageFromFile( "env/UAC3_spec", TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
|
||||
// RB end
|
||||
|
||||
release_assert( loadingIconImage->referencedOutsideLevelLoad );
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2020 Robert Beckebans
|
||||
Copyright (C) 2013-2021 Robert Beckebans
|
||||
Copyright (C) 2014-2016 Kot in Action Creative Artel
|
||||
Copyright (C) 2016-2017 Dustin Land
|
||||
|
||||
|
@ -77,6 +77,8 @@ int BitsForFormat( textureFormat_t format )
|
|||
return 128;
|
||||
case FMT_R32F:
|
||||
return 32;
|
||||
case FMT_R11G11B10F:
|
||||
return 8;
|
||||
// RB end
|
||||
case FMT_DEPTH:
|
||||
return 32;
|
||||
|
@ -132,6 +134,10 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
opts.format = FMT_R32F;
|
||||
break;
|
||||
|
||||
case TD_R11G11B10F:
|
||||
opts.format = FMT_R11G11B10F;
|
||||
break;
|
||||
|
||||
case TD_DIFFUSE:
|
||||
// TD_DIFFUSE gets only set to when its a diffuse texture for an interaction
|
||||
opts.gammaMips = true;
|
||||
|
|
|
@ -725,6 +725,15 @@ void idImage::AllocImage()
|
|||
dataFormat = GL_LUMINANCE_ALPHA;
|
||||
dataType = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
// see http://what-when-how.com/Tutorial/topic-615ll9ug/Praise-for-OpenGL-ES-30-Programming-Guide-291.html
|
||||
case FMT_R11G11B10F:
|
||||
internalFormat = GL_R11F_G11F_B10F;
|
||||
dataFormat = GL_RGB;
|
||||
dataType = GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||
//dataType = GL_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
idLib::Error( "Unhandled image format %d in %s\n", opts.format, GetName() );
|
||||
}
|
||||
|
|
|
@ -769,10 +769,10 @@ void R_DeriveEnvprobeData( RenderEnvprobeLocal* probe )
|
|||
|
||||
// TODO get preconvolved cubemaps
|
||||
fullname.Format( "env/%s/envprobe%i_amb", basename.c_str(), probeIndex );
|
||||
probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
|
||||
|
||||
fullname.Format( "env/%s/envprobe%i_spec", basename.c_str(), probeIndex );
|
||||
probe->radianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
probe->radianceImage = globalImages->ImageFromFile( fullname, TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
|
||||
|
||||
// ------------------------------------
|
||||
// compute the light projection matrix
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2020 Robert Beckebans
|
||||
Copyright (C) 2020-2021 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -30,6 +30,8 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#pragma hdrstop
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "../libs/mesa/format_r11g11b10f.h"
|
||||
|
||||
#include "RenderCommon.h"
|
||||
|
||||
/*
|
||||
|
@ -225,13 +227,13 @@ void idRenderWorldLocal::AddAreaViewEnvprobes( int areaNum, const portalStack_t*
|
|||
|
||||
/*
|
||||
==================
|
||||
R_SampleCubeMap
|
||||
R_SampleCubeMapHDR
|
||||
==================
|
||||
*/
|
||||
static idMat3 cubeAxis[6];
|
||||
static const char* envDirection[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" };
|
||||
|
||||
void R_SampleCubeMap( const idVec3& dir, int size, byte* buffers[6], byte result[4] )
|
||||
void R_SampleCubeMapHDR( const idVec3& dir, int size, byte* buffers[6], float result[3] )
|
||||
{
|
||||
float adir[3];
|
||||
int axis, x, y;
|
||||
|
@ -289,10 +291,21 @@ void R_SampleCubeMap( const idVec3& dir, int size, byte* buffers[6], byte result
|
|||
y = size - 1;
|
||||
}
|
||||
|
||||
result[0] = buffers[axis][( y * size + x ) * 4 + 0];
|
||||
result[1] = buffers[axis][( y * size + x ) * 4 + 1];
|
||||
result[2] = buffers[axis][( y * size + x ) * 4 + 2];
|
||||
result[3] = buffers[axis][( y * size + x ) * 4 + 3];
|
||||
// unpack RGBA8 to 3 floats
|
||||
union
|
||||
{
|
||||
uint32 i;
|
||||
byte b[4];
|
||||
} tmp;
|
||||
|
||||
tmp.b[0] = buffers[axis][( y * size + x ) * 4 + 0];
|
||||
tmp.b[1] = buffers[axis][( y * size + x ) * 4 + 1];
|
||||
tmp.b[2] = buffers[axis][( y * size + x ) * 4 + 2];
|
||||
tmp.b[3] = buffers[axis][( y * size + x ) * 4 + 3];
|
||||
|
||||
//uint32_t value = ( *( const uint32_t* )buffers[axis][( y * size + x ) * 4 + 0] );
|
||||
|
||||
r11g11b10f_to_float3( tmp.i, result );
|
||||
}
|
||||
|
||||
class CommandlineProgressBar
|
||||
|
@ -655,7 +668,7 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
// read all of the images
|
||||
for( int i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
fullname.Format( "env/%s%s.png", baseName, envDirection[i] );
|
||||
fullname.Format( "env/%s%s.exr", baseName, envDirection[i] );
|
||||
|
||||
const bool captureToImage = false;
|
||||
common->UpdateScreen( captureToImage );
|
||||
|
@ -677,68 +690,10 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
// resample with hemispherical blending
|
||||
int samples = 1000;
|
||||
|
||||
byte* outBuffer = ( byte* )_alloca( outSize * outSize * 4 );
|
||||
//halfFloat_t* outBuffer = ( halfFloat_t* )_alloca( outSize * outSize * 3 * sizeof( halfFloat_t ) );
|
||||
halfFloat_t* outBuffer = ( halfFloat_t* )R_StaticAlloc( outSize * outSize * 3 * sizeof( halfFloat_t ) , TAG_IMAGE );
|
||||
|
||||
#if 0
|
||||
{
|
||||
CommandlineProgressBar progressBar( outSize * outSize * 6 );
|
||||
|
||||
int start = Sys_Milliseconds();
|
||||
|
||||
for( int i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
for( int x = 0 ; x < outSize ; x++ )
|
||||
{
|
||||
for( int y = 0 ; y < outSize ; y++ )
|
||||
{
|
||||
idVec3 dir;
|
||||
float total[3];
|
||||
|
||||
dir = cubeAxis[i][0] + -( -1 + 2.0 * x / ( outSize - 1 ) ) * cubeAxis[i][1] + -( -1 + 2.0 * y / ( outSize - 1 ) ) * cubeAxis[i][2];
|
||||
dir.Normalize();
|
||||
total[0] = total[1] = total[2] = 0;
|
||||
|
||||
//float roughness = map ? 0.1 : 0.95; // small for specular, almost hemisphere for ambient
|
||||
|
||||
for( int s = 0 ; s < samples ; s++ )
|
||||
{
|
||||
idVec2 Xi = Hammersley2D( s, samples );
|
||||
idVec3 test = ImportanceSampleGGX( Xi, dir, roughness );
|
||||
|
||||
byte result[4];
|
||||
//test = dir;
|
||||
R_SampleCubeMap( test, width, buffers, result );
|
||||
total[0] += result[0];
|
||||
total[1] += result[1];
|
||||
total[2] += result[2];
|
||||
}
|
||||
outBuffer[( y * outSize + x ) * 4 + 0] = total[0] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 1] = total[1] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 2] = total[2] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 3] = 255;
|
||||
|
||||
progressBar.Increment();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fullname.Format( "env/%s%s%s.png", baseName, suffix, envDirection[i] );
|
||||
//common->Printf( "writing %s\n", fullname.c_str() );
|
||||
|
||||
const bool captureToImage = false;
|
||||
common->UpdateScreen( captureToImage );
|
||||
|
||||
//R_WriteTGA( fullname, outBuffer, outSize, outSize, false, "fs_basepath" );
|
||||
R_WritePNG( fullname, outBuffer, 4, outSize, outSize, true, "fs_basepath" );
|
||||
}
|
||||
|
||||
int end = Sys_Milliseconds();
|
||||
|
||||
common->Printf( "env/%s convolved in %5.1f seconds\n\n", baseName, ( end - start ) * 0.001f );
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
||||
// output an octahedron probe
|
||||
|
||||
CommandlineProgressBar progressBar( outSize * outSize );
|
||||
|
@ -763,6 +718,7 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
// convert UV coord to 3D direction
|
||||
dir.FromOctahedral( octCoord );
|
||||
|
||||
#if 1
|
||||
total[0] = total[1] = total[2] = 0;
|
||||
|
||||
//float roughness = map ? 0.1 : 0.95; // small for specular, almost hemisphere for ambient
|
||||
|
@ -772,24 +728,23 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
idVec2 Xi = Hammersley2D( s, samples );
|
||||
idVec3 test = ImportanceSampleGGX( Xi, dir, roughness );
|
||||
|
||||
byte result[4];
|
||||
float result[3];
|
||||
//test = dir;
|
||||
R_SampleCubeMap( test, width, buffers, result );
|
||||
|
||||
R_SampleCubeMapHDR( test, width, buffers, result );
|
||||
|
||||
total[0] += result[0];
|
||||
total[1] += result[1];
|
||||
total[2] += result[2];
|
||||
}
|
||||
|
||||
#if 1
|
||||
outBuffer[( y * outSize + x ) * 4 + 0] = total[0] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 1] = total[1] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 2] = total[2] / samples;
|
||||
outBuffer[( y * outSize + x ) * 4 + 3] = 255;
|
||||
outBuffer[( y * outSize + x ) * 3 + 0] = F32toF16( total[0] / samples );
|
||||
outBuffer[( y * outSize + x ) * 3 + 1] = F32toF16( total[1] / samples );
|
||||
outBuffer[( y * outSize + x ) * 3 + 2] = F32toF16( total[2] / samples );
|
||||
#else
|
||||
outBuffer[( y * outSize + x ) * 4 + 0] = byte( ( dir.x * 0.5f + 0.5f ) * 255 );
|
||||
outBuffer[( y * outSize + x ) * 4 + 1] = byte( ( dir.y * 0.5f + 0.5f ) * 255 );
|
||||
outBuffer[( y * outSize + x ) * 4 + 2] = byte( ( dir.z * 0.5f + 0.5f ) * 255 );
|
||||
outBuffer[( y * outSize + x ) * 4 + 3] = 255;
|
||||
outBuffer[( y * outSize + x ) * 3 + 0] = F32toF16( ( dir.x * 0.5f + 0.5f ) );
|
||||
outBuffer[( y * outSize + x ) * 3 + 1] = F32toF16( ( dir.y * 0.5f + 0.5f ) );
|
||||
outBuffer[( y * outSize + x ) * 3 + 2] = F32toF16( ( dir.z * 0.5f + 0.5f ) );
|
||||
#endif
|
||||
|
||||
progressBar.Increment();
|
||||
|
@ -797,20 +752,20 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
}
|
||||
|
||||
|
||||
fullname.Format( "env/%s%s.png", baseName, suffix );
|
||||
fullname.Format( "env/%s%s.exr", baseName, suffix );
|
||||
//common->Printf( "writing %s\n", fullname.c_str() );
|
||||
|
||||
const bool captureToImage = false;
|
||||
common->UpdateScreen( captureToImage );
|
||||
|
||||
//R_WriteTGA( fullname, outBuffer, outSize, outSize, false, "fs_basepath" );
|
||||
R_WritePNG( fullname, outBuffer, 4, outSize, outSize, true, "fs_basepath" );
|
||||
//R_WritePNG( fullname, outBuffer, 4, outSize, outSize, true, "fs_basepath" );
|
||||
R_WriteEXR( fullname, (byte*)outBuffer, 3, outSize, outSize, "fs_basepath" );
|
||||
|
||||
int end = Sys_Milliseconds();
|
||||
|
||||
common->Printf( "env/%s convolved in %5.1f seconds\n\n", baseName, ( end - start ) * 0.001f );
|
||||
}
|
||||
#endif
|
||||
|
||||
for( int i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
|
@ -819,6 +774,8 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl
|
|||
Mem_Free( buffers[i] );
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Free( outBuffer );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue