mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 02:32:18 +00:00
Added support to load RG16F texture data. Added R_WriteEXR function
This commit is contained in:
parent
9872734f62
commit
c8250b184b
8 changed files with 22063 additions and 369 deletions
|
@ -240,6 +240,23 @@ void idBinaryImage::Load2DFromMemory( int width, int height, const byte* pic_con
|
|||
img.data[ i * 2 + 1 ] = color & 0xFF;
|
||||
}
|
||||
}
|
||||
else if( textureFormat == FMT_RG16F )
|
||||
{
|
||||
// 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 );
|
||||
for( int i = 0; i < img.dataSize; i++ )
|
||||
{
|
||||
img.data[ i ] = pic[ i ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileData.format = textureFormat = FMT_RGBA8;
|
||||
|
|
|
@ -96,7 +96,7 @@ enum textureFormat_t
|
|||
// RB: don't change above for legacy .bimage compatibility
|
||||
FMT_ETC1_RGB8_OES, // 4 bpp
|
||||
FMT_SHADOW_ARRAY, // 32 bpp * 6
|
||||
//FMT_RG16F, // 32 bpp
|
||||
FMT_RG16F, // 32 bpp
|
||||
FMT_RGBA16F, // 64 bpp
|
||||
FMT_RGBA32F, // 128 bpp
|
||||
FMT_R32F, // 32 bpp
|
||||
|
@ -222,6 +222,7 @@ typedef enum
|
|||
TD_HIGHQUALITY_CUBE, // motorsep - Uncompressed cubemap texture (RGB colorspace)
|
||||
TD_LOWQUALITY_CUBE, // motorsep - Compressed cubemap texture (RGB colorspace DXT5)
|
||||
TD_SHADOW_ARRAY, // 2D depth buffer array for shadow mapping
|
||||
TD_RG16F,
|
||||
TD_RGBA16F,
|
||||
TD_RGBA32F,
|
||||
TD_R32F,
|
||||
|
@ -479,6 +480,7 @@ void R_WriteTGA( const char* filename, const byte* data, int width, int height,
|
|||
|
||||
// RB begin
|
||||
void R_WritePNG( const char* filename, const byte* data, int bytesPerPixel, int width, int height, bool flipVertical = false, const char* basePath = "fs_savepath" );
|
||||
void R_WriteEXR( const char* filename, const void* data, int channelsPerPixel, int width, int height, const char* basePath = "fs_savepath" );
|
||||
// RB end
|
||||
|
||||
class idImageManager
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -851,6 +851,161 @@ void R_WritePNG( const char* filename, const byte* data, int bytesPerPixel, int
|
|||
|
||||
Mem_Free( buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_WriteEXR
|
||||
================
|
||||
*/
|
||||
// miniexr.cpp - v0.2 - public domain - 2013 Aras Pranckevicius / Unity Technologies
|
||||
//
|
||||
// Writes OpenEXR RGB files out of half-precision RGBA or RGB data.
|
||||
//
|
||||
// Only tested on Windows (VS2008) and Mac (clang 3.3), little endian.
|
||||
// Testing status: "works for me".
|
||||
//
|
||||
// History:
|
||||
// 0.2 Source data can be RGB or RGBA now.
|
||||
// 0.1 Initial release.
|
||||
|
||||
void R_WriteEXR( const char* filename, const void* rgba16f, int channelsPerPixel, int width, int height, const char* basePath )
|
||||
{
|
||||
const unsigned ww = width - 1;
|
||||
const unsigned hh = height - 1;
|
||||
const unsigned char kHeader[] =
|
||||
{
|
||||
0x76, 0x2f, 0x31, 0x01, // magic
|
||||
2, 0, 0, 0, // version, scanline
|
||||
// channels
|
||||
'c', 'h', 'a', 'n', 'n', 'e', 'l', 's', 0,
|
||||
'c', 'h', 'l', 'i', 's', 't', 0,
|
||||
55, 0, 0, 0,
|
||||
'B', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // B, half
|
||||
'G', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // G, half
|
||||
'R', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, // R, half
|
||||
0,
|
||||
// compression
|
||||
'c', 'o', 'm', 'p', 'r', 'e', 's', 's', 'i', 'o', 'n', 0,
|
||||
'c', 'o', 'm', 'p', 'r', 'e', 's', 's', 'i', 'o', 'n', 0,
|
||||
1, 0, 0, 0,
|
||||
0, // no compression
|
||||
// dataWindow
|
||||
'd', 'a', 't', 'a', 'W', 'i', 'n', 'd', 'o', 'w', 0,
|
||||
'b', 'o', 'x', '2', 'i', 0,
|
||||
16, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
ww & 0xFF, ( ww >> 8 ) & 0xFF, ( ww >> 16 ) & 0xFF, ( ww >> 24 ) & 0xFF,
|
||||
hh & 0xFF, ( hh >> 8 ) & 0xFF, ( hh >> 16 ) & 0xFF, ( hh >> 24 ) & 0xFF,
|
||||
// displayWindow
|
||||
'd', 'i', 's', 'p', 'l', 'a', 'y', 'W', 'i', 'n', 'd', 'o', 'w', 0,
|
||||
'b', 'o', 'x', '2', 'i', 0,
|
||||
16, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
ww & 0xFF, ( ww >> 8 ) & 0xFF, ( ww >> 16 ) & 0xFF, ( ww >> 24 ) & 0xFF,
|
||||
hh & 0xFF, ( hh >> 8 ) & 0xFF, ( hh >> 16 ) & 0xFF, ( hh >> 24 ) & 0xFF,
|
||||
// lineOrder
|
||||
'l', 'i', 'n', 'e', 'O', 'r', 'd', 'e', 'r', 0,
|
||||
'l', 'i', 'n', 'e', 'O', 'r', 'd', 'e', 'r', 0,
|
||||
1, 0, 0, 0,
|
||||
0, // increasing Y
|
||||
// pixelAspectRatio
|
||||
'p', 'i', 'x', 'e', 'l', 'A', 's', 'p', 'e', 'c', 't', 'R', 'a', 't', 'i', 'o', 0,
|
||||
'f', 'l', 'o', 'a', 't', 0,
|
||||
4, 0, 0, 0,
|
||||
0, 0, 0x80, 0x3f, // 1.0f
|
||||
// screenWindowCenter
|
||||
's', 'c', 'r', 'e', 'e', 'n', 'W', 'i', 'n', 'd', 'o', 'w', 'C', 'e', 'n', 't', 'e', 'r', 0,
|
||||
'v', '2', 'f', 0,
|
||||
8, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// screenWindowWidth
|
||||
's', 'c', 'r', 'e', 'e', 'n', 'W', 'i', 'n', 'd', 'o', 'w', 'W', 'i', 'd', 't', 'h', 0,
|
||||
'f', 'l', 'o', 'a', 't', 0,
|
||||
4, 0, 0, 0,
|
||||
0, 0, 0x80, 0x3f, // 1.0f
|
||||
// end of header
|
||||
0,
|
||||
};
|
||||
const int kHeaderSize = sizeof( kHeader );
|
||||
|
||||
const int kScanlineTableSize = 8 * height;
|
||||
const unsigned pixelRowSize = width * 3 * 2;
|
||||
const unsigned fullRowSize = pixelRowSize + 8;
|
||||
|
||||
unsigned bufSize = kHeaderSize + kScanlineTableSize + height * fullRowSize;
|
||||
unsigned char* buf = ( unsigned char* )Mem_Alloc( bufSize, TAG_TEMP );
|
||||
if( !buf )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// copy in header
|
||||
memcpy( buf, kHeader, kHeaderSize );
|
||||
|
||||
// line offset table
|
||||
unsigned ofs = kHeaderSize + kScanlineTableSize;
|
||||
unsigned char* ptr = buf + kHeaderSize;
|
||||
for( int y = 0; y < height; ++y )
|
||||
{
|
||||
*ptr++ = ofs & 0xFF;
|
||||
*ptr++ = ( ofs >> 8 ) & 0xFF;
|
||||
*ptr++ = ( ofs >> 16 ) & 0xFF;
|
||||
*ptr++ = ( ofs >> 24 ) & 0xFF;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
ofs += fullRowSize;
|
||||
}
|
||||
|
||||
// scanline data
|
||||
const unsigned char* src = ( const unsigned char* )rgba16f;
|
||||
const int stride = channelsPerPixel * 2;
|
||||
for( int y = 0; y < height; ++y )
|
||||
{
|
||||
// coordinate
|
||||
*ptr++ = y & 0xFF;
|
||||
*ptr++ = ( y >> 8 ) & 0xFF;
|
||||
*ptr++ = ( y >> 16 ) & 0xFF;
|
||||
*ptr++ = ( y >> 24 ) & 0xFF;
|
||||
// data size
|
||||
*ptr++ = pixelRowSize & 0xFF;
|
||||
*ptr++ = ( pixelRowSize >> 8 ) & 0xFF;
|
||||
*ptr++ = ( pixelRowSize >> 16 ) & 0xFF;
|
||||
*ptr++ = ( pixelRowSize >> 24 ) & 0xFF;
|
||||
// B, G, R
|
||||
const unsigned char* chsrc;
|
||||
chsrc = src + 4;
|
||||
for( int x = 0; x < width; ++x )
|
||||
{
|
||||
*ptr++ = chsrc[0];
|
||||
*ptr++ = chsrc[1];
|
||||
chsrc += stride;
|
||||
}
|
||||
chsrc = src + 2;
|
||||
for( int x = 0; x < width; ++x )
|
||||
{
|
||||
*ptr++ = chsrc[0];
|
||||
*ptr++ = chsrc[1];
|
||||
chsrc += stride;
|
||||
}
|
||||
chsrc = src + 0;
|
||||
for( int x = 0; x < width; ++x )
|
||||
{
|
||||
*ptr++ = chsrc[0];
|
||||
*ptr++ = chsrc[1];
|
||||
chsrc += stride;
|
||||
}
|
||||
|
||||
src += width * stride;
|
||||
}
|
||||
|
||||
assert( ptr - buf == bufSize );
|
||||
|
||||
fileSystem->WriteFile( filename, buf, bufSize, basePath );
|
||||
|
||||
Mem_Free( buf );
|
||||
}
|
||||
// RB end
|
||||
|
||||
//===================================================================
|
||||
|
|
|
@ -861,7 +861,7 @@ static void R_CreateBrdfLutImage( idImage* image )
|
|||
}
|
||||
#endif
|
||||
|
||||
image->GenerateImage( ( byte* )brfLutTexBytes, BRDFLUT_TEX_WIDTH, BRDFLUT_TEX_HEIGHT, TF_LINEAR, TR_CLAMP, TD_LOOKUP_TABLE_RGBA );
|
||||
image->GenerateImage( ( byte* )brfLutTexBytes, BRDFLUT_TEX_WIDTH, BRDFLUT_TEX_HEIGHT, TF_LINEAR, TR_CLAMP, TD_RG16F );
|
||||
}
|
||||
|
||||
// RB end
|
||||
|
|
|
@ -69,6 +69,8 @@ int BitsForFormat( textureFormat_t format )
|
|||
return 4;
|
||||
case FMT_SHADOW_ARRAY:
|
||||
return ( 32 * 6 );
|
||||
case FMT_RG16F:
|
||||
return 32;
|
||||
case FMT_RGBA16F:
|
||||
return 64;
|
||||
case FMT_RGBA32F:
|
||||
|
@ -114,6 +116,10 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
opts.format = FMT_SHADOW_ARRAY;
|
||||
break;
|
||||
|
||||
case TD_RG16F:
|
||||
opts.format = FMT_RG16F;
|
||||
break;
|
||||
|
||||
case TD_RGBA16F:
|
||||
opts.format = FMT_RGBA16F;
|
||||
break;
|
||||
|
@ -630,6 +636,7 @@ void idImage::Print() const
|
|||
// RB begin
|
||||
NAME_FORMAT( ETC1_RGB8_OES );
|
||||
NAME_FORMAT( SHADOW_ARRAY );
|
||||
NAME_FORMAT( RG16F );
|
||||
NAME_FORMAT( RGBA16F );
|
||||
NAME_FORMAT( RGBA32F );
|
||||
NAME_FORMAT( R32F );
|
||||
|
|
|
@ -472,7 +472,7 @@ void idImage::SetTexParameters()
|
|||
glTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_RED );
|
||||
glTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_ONE );
|
||||
}
|
||||
else if( opts.format == FMT_L8A8 )
|
||||
else if( opts.format == FMT_L8A8 )//|| opts.format == FMT_RG16F )
|
||||
{
|
||||
glTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_RED );
|
||||
glTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_RED );
|
||||
|
@ -690,10 +690,16 @@ void idImage::AllocImage()
|
|||
dataType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case FMT_RG16F:
|
||||
internalFormat = GL_RG16F;
|
||||
dataFormat = GL_RG;
|
||||
dataType = GL_HALF_FLOAT;
|
||||
break;
|
||||
|
||||
case FMT_RGBA16F:
|
||||
internalFormat = GL_RGBA16F;
|
||||
dataFormat = GL_RGBA;
|
||||
dataType = GL_UNSIGNED_BYTE;
|
||||
dataType = GL_HALF_FLOAT;
|
||||
break;
|
||||
|
||||
case FMT_RGBA32F:
|
||||
|
|
|
@ -1497,7 +1497,7 @@ idVec2 IntegrateBRDF( float NdotV, float roughness, int sampleCount )
|
|||
|
||||
void R_MakeBrdfLut_f( const idCmdArgs& args )
|
||||
{
|
||||
int outSize = 32;
|
||||
int outSize = 256;
|
||||
int width = 0, height = 0;
|
||||
|
||||
//if( args.Argc() != 2 )
|
||||
|
@ -1519,6 +1519,9 @@ void R_MakeBrdfLut_f( const idCmdArgs& args )
|
|||
int ldrBufferSize = outSize * outSize * 4;
|
||||
byte* ldrBuffer = ( byte* )Mem_Alloc( ldrBufferSize, TAG_TEMP );
|
||||
|
||||
int hdrBufferSize = outSize * outSize * 2 * sizeof( halfFloat_t );
|
||||
halfFloat_t* hdrBuffer = ( halfFloat_t* )Mem_Alloc( hdrBufferSize, TAG_TEMP );
|
||||
|
||||
CommandlineProgressBar progressBar( outSize * outSize );
|
||||
|
||||
int start = Sys_Milliseconds();
|
||||
|
@ -1538,18 +1541,23 @@ void R_MakeBrdfLut_f( const idCmdArgs& args )
|
|||
ldrBuffer[( y * outSize + x ) * 4 + 2] = 0;
|
||||
ldrBuffer[( y * outSize + x ) * 4 + 3] = 255;
|
||||
|
||||
halfFloat_t half1 = F32toF16( output.x );
|
||||
halfFloat_t half2 = F32toF16( output.y );
|
||||
|
||||
hdrBuffer[( y * outSize + x ) * 2 + 0] = half1;
|
||||
hdrBuffer[( y * outSize + x ) * 2 + 1] = half2;
|
||||
//hdrBuffer[( y * outSize + x ) * 4 + 2] = 0;
|
||||
//hdrBuffer[( y * outSize + x ) * 4 + 3] = 1;
|
||||
|
||||
progressBar.Increment();
|
||||
}
|
||||
|
||||
//const bool captureToImage = false;
|
||||
//common->UpdateScreen( captureToImage );
|
||||
}
|
||||
|
||||
idStr fullname = "env/_brdfLut.png";
|
||||
idLib::Printf( "writing %s\n", fullname.c_str() );
|
||||
|
||||
//R_WriteTGA( fullname, outBuffer, outSize, outSize, false, "fs_basepath" );
|
||||
R_WritePNG( fullname, ldrBuffer, 4, outSize, outSize, true, "fs_basepath" );
|
||||
//R_WriteEXR( "env/_brdfLut.exr", hdrBuffer, 4, outSize, outSize, "fs_basepath" );
|
||||
|
||||
|
||||
idFileLocal headerFile( fileSystem->OpenFileWrite( "env/Image_brdfLut.h", "fs_basepath" ) );
|
||||
|
@ -1558,27 +1566,24 @@ void R_MakeBrdfLut_f( const idCmdArgs& args )
|
|||
#ifndef BRDFLUT_TEX_H
|
||||
#define BRDFLUT_TEX_H
|
||||
|
||||
#define BRDFLUT_TEX_WIDTH 512
|
||||
#define BRDFLUT_TEX_HEIGHT 512
|
||||
#define BRDFLUT_TEX_WIDTH 256
|
||||
#define BRDFLUT_TEX_HEIGHT 256
|
||||
#define BRDFLUT_TEX_PITCH (BRDFLUT_TEX_WIDTH * 2)
|
||||
#define BRDFLUT_TEX_SIZE (BRDFLUT_TEX_WIDTH * BRDFLUT_TEX_PITCH)
|
||||
|
||||
/**
|
||||
* Stored in R8G8 format. Load it in the following format:
|
||||
* - DX9: D3DFMT_A8L8
|
||||
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
||||
*/
|
||||
// Stored in R16G16F format
|
||||
static const unsigned char brfLutTexBytes[] =
|
||||
{
|
||||
)";
|
||||
|
||||
headerFile->Printf( "%s\n", intro );
|
||||
|
||||
for( int i = 0; i < ldrBufferSize; i++ )
|
||||
const byte* hdrBytes = (const byte* ) hdrBuffer;
|
||||
for( int i = 0; i < hdrBufferSize; i++ )
|
||||
{
|
||||
byte b = ldrBuffer[i];
|
||||
byte b = hdrBytes[i];
|
||||
|
||||
if( i < ( ldrBufferSize - 1 ) )
|
||||
if( i < ( hdrBufferSize - 1 ) )
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx, ", b );
|
||||
}
|
||||
|
@ -1599,6 +1604,7 @@ static const unsigned char brfLutTexBytes[] =
|
|||
common->Printf( "%s integrated in %5.1f seconds\n\n", fullname.c_str(), ( end - start ) * 0.001f );
|
||||
|
||||
Mem_Free( ldrBuffer );
|
||||
Mem_Free( hdrBuffer );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue