mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-13 22:22:05 +00:00
Added HDRI extension to the material system
This commit is contained in:
parent
31fdbfed42
commit
f5cb915356
6 changed files with 414 additions and 13 deletions
|
@ -735,6 +735,15 @@ void idBinaryImage::LoadCubeFromMemory( int width, const byte* pics[6], int numL
|
|||
dxt.CompressImageDXT5Fast( padSrc, img.data, padSize, padSize );
|
||||
}
|
||||
}
|
||||
else if( textureFormat == FMT_R11G11B10F )
|
||||
{
|
||||
// RB: copy it as it was a RGBA8 because of the same size
|
||||
img.Alloc( padSize * padSize * 4 );
|
||||
for( int i = 0; i < img.dataSize; i++ )
|
||||
{
|
||||
img.data[ i ] = pic[ i ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileData.format = textureFormat = FMT_RGBA8;
|
||||
|
|
|
@ -674,8 +674,10 @@ void R_ApplyCubeMapTransforms( int i, byte* data, int size );
|
|||
// SP begin
|
||||
// This method takes in a cubemap from a single image. Depending on the side (0-5),
|
||||
// the image will be extracted from data and returned. The dimensions will be size x size.
|
||||
byte* R_GenerateCubeMapSideFromSingleImage( byte* data, int srcWidth, int srcHeight, int size, int side );
|
||||
byte* R_GenerateCubeMapSideFromSingleImage( const byte* in, int srcWidth, int srcHeight, int size, int side );
|
||||
// SP end
|
||||
// RB
|
||||
byte* R_GenerateCubeMapSideFromPanoramaImage( const byte* in, int srcWidth, int srcHeight, int size, int side );
|
||||
|
||||
idVec4 R_CalculateMipRect( uint dimensions, uint mip );
|
||||
int R_CalculateUsedAtlasPixels( int dimensions );
|
||||
|
|
|
@ -905,14 +905,14 @@ static void LoadHDR( const char* filename, unsigned char** pic, int* width, int*
|
|||
|
||||
int32 numChannels;
|
||||
|
||||
float* rgba = stbi_loadf_from_memory( ( stbi_uc const* ) fbuffer, fileSize, width, height, &numChannels, 0 );
|
||||
float* rgb = 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 )
|
||||
if( rgb )
|
||||
{
|
||||
int32 pixelCount = *width * *height;
|
||||
byte* out = ( byte* )R_StaticAlloc( pixelCount * 4, TAG_IMAGE );
|
||||
|
@ -921,7 +921,7 @@ static void LoadHDR( const char* filename, unsigned char** pic, int* width, int*
|
|||
|
||||
// convert to packed R11G11B10F as uint32 for each pixel
|
||||
|
||||
const float* src = rgba;
|
||||
const float* src = rgb;
|
||||
byte* dst = out;
|
||||
for( int i = 0; i < pixelCount; i++ )
|
||||
{
|
||||
|
@ -936,11 +936,11 @@ static void LoadHDR( const char* filename, unsigned char** pic, int* width, int*
|
|||
uint32_t value = float3_to_r11g11b10f( p );
|
||||
*( uint32_t* )dst = value;
|
||||
|
||||
src += 4;
|
||||
src += 3;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
free( rgba );
|
||||
free( rgb );
|
||||
}
|
||||
|
||||
Mem_Free( ( void* )fbuffer );
|
||||
|
@ -1268,6 +1268,52 @@ bool R_LoadCubeImages( const char* imgName, cubeFiles_t extensions, byte* pics[6
|
|||
return true;
|
||||
}
|
||||
|
||||
if( extensions == CF_PANORAMA )
|
||||
{
|
||||
ID_TIME_T thisTime;
|
||||
byte* thisPic[1];
|
||||
thisPic[0] = nullptr;
|
||||
|
||||
if( pics )
|
||||
{
|
||||
R_LoadImageProgram( imgName, thisPic, &width, &height, &thisTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
// load just the timestamps
|
||||
R_LoadImageProgram( imgName, nullptr, &width, &height, &thisTime );
|
||||
}
|
||||
|
||||
|
||||
if( thisTime == FILE_NOT_FOUND_TIMESTAMP )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( timestamp )
|
||||
{
|
||||
if( thisTime > *timestamp )
|
||||
{
|
||||
*timestamp = thisTime;
|
||||
}
|
||||
}
|
||||
|
||||
if( pics )
|
||||
{
|
||||
cubeMapSize = 512;
|
||||
*outSize = cubeMapSize;
|
||||
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
pics[i] = R_GenerateCubeMapSideFromPanoramaImage( thisPic[0], width, height, cubeMapSize, i );
|
||||
}
|
||||
|
||||
R_StaticFree( thisPic[0] );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for( i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] );
|
||||
|
|
|
@ -574,7 +574,7 @@ void idImage::ActuallyLoadImage( bool fromBackEnd, nvrhi::ICommandList* commandL
|
|||
{
|
||||
opts.textureType = TT_2D_ARRAY;
|
||||
}
|
||||
else if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE )
|
||||
else if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE || cubeFiles == CF_PANORAMA )
|
||||
{
|
||||
opts.textureType = TT_CUBIC;
|
||||
repeat = TR_CLAMP;
|
||||
|
@ -714,7 +714,7 @@ void idImage::ActuallyLoadImage( bool fromBackEnd, nvrhi::ICommandList* commandL
|
|||
//else if( toolUsage )
|
||||
// binarizeReason = va( "binarize: tool usage '%s'", generatedName.c_str() );
|
||||
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE )
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE || cubeFiles == CF_PANORAMA )
|
||||
{
|
||||
int size;
|
||||
byte* pics[6];
|
||||
|
@ -1242,7 +1242,7 @@ void idImage::Reload( bool force, nvrhi::ICommandList* commandList )
|
|||
if( !force )
|
||||
{
|
||||
ID_TIME_T current;
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE )
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_QUAKE1 || cubeFiles == CF_SINGLE || cubeFiles == CF_PANORAMA )
|
||||
{
|
||||
R_LoadCubeImages( imgName, cubeFiles, NULL, NULL, ¤t );
|
||||
}
|
||||
|
|
|
@ -631,8 +631,7 @@ int R_CalculateUsedAtlasPixels( int dimensions )
|
|||
}
|
||||
|
||||
// SP begin
|
||||
|
||||
byte* R_GenerateCubeMapSideFromSingleImage( byte* data, int srcWidth, int srcHeight, int size, int side )
|
||||
byte* R_GenerateCubeMapSideFromSingleImage( const byte* in, int srcWidth, int srcHeight, int size, int side )
|
||||
{
|
||||
size_t x = 0, y = 0;
|
||||
switch( side )
|
||||
|
@ -689,7 +688,7 @@ byte* R_GenerateCubeMapSideFromSingleImage( byte* data, int srcWidth, int srcHei
|
|||
const size_t copySize = ( size_t )size * ( size_t )size * 4;
|
||||
byte* out = ( byte* )R_StaticAlloc( copySize, TAG_IMAGE );
|
||||
uint32_t* out_p = ( uint32_t* )out;
|
||||
const uint32_t* in_p = ( uint32_t* )data + x + y * srcWidth;
|
||||
const uint32_t* in_p = ( uint32_t* )in + x + y * srcWidth;
|
||||
|
||||
for( int j = 0; j < size; j++ )
|
||||
{
|
||||
|
@ -701,5 +700,321 @@ byte* R_GenerateCubeMapSideFromSingleImage( byte* data, int srcWidth, int srcHei
|
|||
|
||||
return out;
|
||||
}
|
||||
|
||||
// SP end
|
||||
|
||||
|
||||
// RB: ripped from cmft utils by Dario Manesku
|
||||
/*
|
||||
* Copyright 2014-2015 Dario Manesku. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
///
|
||||
///
|
||||
/// +----------+
|
||||
/// | +---->+x |
|
||||
/// | | |
|
||||
/// | | +y |
|
||||
/// |+z 2 |
|
||||
/// +----------+----------+----------+----------+
|
||||
/// | +---->+z | +---->+x | +---->-z | +---->-x |
|
||||
/// | | | | | | | | |
|
||||
/// | | -x | | +z | | +x | | -z |
|
||||
/// |-y 1 |-y 4 |-y 0 |-y 5 |
|
||||
/// +----------+----------+----------+----------+
|
||||
/// | +---->+x |
|
||||
/// | | |
|
||||
/// | | -y |
|
||||
/// |-z 3 |
|
||||
/// +----------+
|
||||
///
|
||||
static const float s_faceUvVectors[6][3][3] =
|
||||
{
|
||||
{
|
||||
// +x face
|
||||
{ 0.0f, 0.0f, -1.0f }, // u -> -z
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 1.0f, 0.0f, 0.0f }, // +x face
|
||||
},
|
||||
{
|
||||
// -x face
|
||||
{ 0.0f, 0.0f, 1.0f }, // u -> +z
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ -1.0f, 0.0f, 0.0f }, // -x face
|
||||
},
|
||||
{
|
||||
// +y face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, 0.0f, 1.0f }, // v -> +z
|
||||
{ 0.0f, 1.0f, 0.0f }, // +y face
|
||||
},
|
||||
{
|
||||
// -y face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, 0.0f, -1.0f }, // v -> -z
|
||||
{ 0.0f, -1.0f, 0.0f }, // -y face
|
||||
},
|
||||
{
|
||||
// +z face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 0.0f, 0.0f, 1.0f }, // +z face
|
||||
},
|
||||
{
|
||||
// -z face
|
||||
{ -1.0f, 0.0f, 0.0f }, // u -> -x
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 0.0f, 0.0f, -1.0f }, // -z face
|
||||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CMFT_FACE_POS_X = 0,
|
||||
CMFT_FACE_NEG_X = 1,
|
||||
CMFT_FACE_POS_Y = 2,
|
||||
CMFT_FACE_NEG_Y = 3,
|
||||
CMFT_FACE_POS_Z = 4,
|
||||
CMFT_FACE_NEG_Z = 5,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CMFT_EDGE_LEFT = 0,
|
||||
CMFT_EDGE_RIGHT = 1,
|
||||
CMFT_EDGE_TOP = 2,
|
||||
CMFT_EDGE_BOTTOM = 3,
|
||||
};
|
||||
|
||||
///
|
||||
/// --> U _____
|
||||
/// | | |
|
||||
/// v | +Y |
|
||||
/// V _____|_____|_____ _____
|
||||
/// | | | | |
|
||||
/// | -X | +Z | +X | -Z |
|
||||
/// |_____|_____|_____|_____|
|
||||
/// | |
|
||||
/// | -Y |
|
||||
/// |_____|
|
||||
///
|
||||
/// Neighbour faces in order: left, right, top, bottom.
|
||||
/// FaceEdge is the edge that belongs to the neighbour face.
|
||||
static const struct CubeFaceNeighbour
|
||||
{
|
||||
uint8_t m_faceIdx;
|
||||
uint8_t m_faceEdge;
|
||||
} s_cubeFaceNeighbours[6][4] =
|
||||
{
|
||||
{
|
||||
//POS_X
|
||||
{ CMFT_FACE_POS_Z, CMFT_EDGE_RIGHT },
|
||||
{ CMFT_FACE_NEG_Z, CMFT_EDGE_LEFT },
|
||||
{ CMFT_FACE_POS_Y, CMFT_EDGE_RIGHT },
|
||||
{ CMFT_FACE_NEG_Y, CMFT_EDGE_RIGHT },
|
||||
},
|
||||
{
|
||||
//NEG_X
|
||||
{ CMFT_FACE_NEG_Z, CMFT_EDGE_RIGHT },
|
||||
{ CMFT_FACE_POS_Z, CMFT_EDGE_LEFT },
|
||||
{ CMFT_FACE_POS_Y, CMFT_EDGE_LEFT },
|
||||
{ CMFT_FACE_NEG_Y, CMFT_EDGE_LEFT },
|
||||
},
|
||||
{
|
||||
//POS_Y
|
||||
{ CMFT_FACE_NEG_X, CMFT_EDGE_TOP },
|
||||
{ CMFT_FACE_POS_X, CMFT_EDGE_TOP },
|
||||
{ CMFT_FACE_NEG_Z, CMFT_EDGE_TOP },
|
||||
{ CMFT_FACE_POS_Z, CMFT_EDGE_TOP },
|
||||
},
|
||||
{
|
||||
//NEG_Y
|
||||
{ CMFT_FACE_NEG_X, CMFT_EDGE_BOTTOM },
|
||||
{ CMFT_FACE_POS_X, CMFT_EDGE_BOTTOM },
|
||||
{ CMFT_FACE_POS_Z, CMFT_EDGE_BOTTOM },
|
||||
{ CMFT_FACE_NEG_Z, CMFT_EDGE_BOTTOM },
|
||||
},
|
||||
{
|
||||
//POS_Z
|
||||
{ CMFT_FACE_NEG_X, CMFT_EDGE_RIGHT },
|
||||
{ CMFT_FACE_POS_X, CMFT_EDGE_LEFT },
|
||||
{ CMFT_FACE_POS_Y, CMFT_EDGE_BOTTOM },
|
||||
{ CMFT_FACE_NEG_Y, CMFT_EDGE_TOP },
|
||||
},
|
||||
{
|
||||
//NEG_Z
|
||||
{ CMFT_FACE_POS_X, CMFT_EDGE_RIGHT },
|
||||
{ CMFT_FACE_NEG_X, CMFT_EDGE_LEFT },
|
||||
{ CMFT_FACE_POS_Y, CMFT_EDGE_TOP },
|
||||
{ CMFT_FACE_NEG_Y, CMFT_EDGE_BOTTOM },
|
||||
}
|
||||
};
|
||||
|
||||
/// _u and _v should be center adressing and in [-1.0+invSize..1.0-invSize] range.
|
||||
static inline void TexelCoordToVec( float* _out3f, float _u, float _v, uint8_t _faceId )
|
||||
{
|
||||
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
|
||||
_out3f[0] = s_faceUvVectors[_faceId][0][0] * _u + s_faceUvVectors[_faceId][1][0] * _v + s_faceUvVectors[_faceId][2][0];
|
||||
_out3f[1] = s_faceUvVectors[_faceId][0][1] * _u + s_faceUvVectors[_faceId][1][1] * _v + s_faceUvVectors[_faceId][2][1];
|
||||
_out3f[2] = s_faceUvVectors[_faceId][0][2] * _u + s_faceUvVectors[_faceId][1][2] * _v + s_faceUvVectors[_faceId][2][2];
|
||||
|
||||
// Normalize.
|
||||
const float invLen = 1.0f / sqrtf( _out3f[0] * _out3f[0] + _out3f[1] * _out3f[1] + _out3f[2] * _out3f[2] );
|
||||
_out3f[0] *= invLen;
|
||||
_out3f[1] *= invLen;
|
||||
_out3f[2] *= invLen;
|
||||
}
|
||||
|
||||
/// Notice: _faceSize should not be equal to one!
|
||||
static inline float WarpFixupFactor( float _faceSize )
|
||||
{
|
||||
// Edge fixup.
|
||||
// Based on Nvtt : http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvtt/CubeSurface.cpp
|
||||
if( _faceSize == 1.0f )
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const float fs = _faceSize;
|
||||
const float fsmo = fs - 1.0f;
|
||||
return ( fs * fs ) / ( fsmo * fsmo * fsmo );
|
||||
}
|
||||
|
||||
/// _u and _v should be center adressing and in [-1.0+invSize..1.0-invSize] range.
|
||||
static inline void TexelCoordToVecWarp( float* _out3f, float _u, float _v, uint8_t _faceId, float _warpFixup )
|
||||
{
|
||||
_u = ( _warpFixup * _u * _u * _u ) + _u;
|
||||
_v = ( _warpFixup * _v * _v * _v ) + _v;
|
||||
|
||||
TexelCoordToVec( _out3f, _u, _v, _faceId );
|
||||
}
|
||||
|
||||
inline void vec3Mul( float* __restrict _result, const float* __restrict _a, float _b )
|
||||
{
|
||||
_result[0] = _a[0] * _b;
|
||||
_result[1] = _a[1] * _b;
|
||||
_result[2] = _a[2] * _b;
|
||||
}
|
||||
|
||||
inline float vec3Dot( const float* __restrict _a, const float* __restrict _b )
|
||||
{
|
||||
return _a[0] * _b[0] + _a[1] * _b[1] + _a[2] * _b[2];
|
||||
}
|
||||
|
||||
/// _u and _v are in [0.0 .. 1.0] range.
|
||||
static inline void VecToTexelCoord( float& _u, float& _v, uint8_t& _faceIdx, const float* _vec )
|
||||
{
|
||||
const float absVec[3] =
|
||||
{
|
||||
fabsf( _vec[0] ),
|
||||
fabsf( _vec[1] ),
|
||||
fabsf( _vec[2] ),
|
||||
};
|
||||
const float max = fmaxf( fmaxf( absVec[0], absVec[1] ), absVec[2] );
|
||||
|
||||
// Get face id (max component == face vector).
|
||||
if( max == absVec[0] )
|
||||
{
|
||||
_faceIdx = ( _vec[0] >= 0.0f ) ? uint8_t( CMFT_FACE_POS_X ) : uint8_t( CMFT_FACE_NEG_X );
|
||||
}
|
||||
else if( max == absVec[1] )
|
||||
{
|
||||
_faceIdx = ( _vec[1] >= 0.0f ) ? uint8_t( CMFT_FACE_POS_Y ) : uint8_t( CMFT_FACE_NEG_Y );
|
||||
}
|
||||
else //if (max == absVec[2])
|
||||
{
|
||||
_faceIdx = ( _vec[2] >= 0.0f ) ? uint8_t( CMFT_FACE_POS_Z ) : uint8_t( CMFT_FACE_NEG_Z );
|
||||
}
|
||||
|
||||
// Divide by max component.
|
||||
float faceVec[3];
|
||||
vec3Mul( faceVec, _vec, 1.0f / max );
|
||||
|
||||
// Project other two components to face uv basis.
|
||||
_u = ( vec3Dot( s_faceUvVectors[_faceIdx][0], faceVec ) + 1.0f ) * 0.5f;
|
||||
_v = ( vec3Dot( s_faceUvVectors[_faceIdx][1], faceVec ) + 1.0f ) * 0.5f;
|
||||
}
|
||||
|
||||
#define CMFT_RPI 0.31830988618379067153f
|
||||
|
||||
static inline void LatLongFromVec( float& _u, float& _v, const float _vec[3] )
|
||||
{
|
||||
const float phi = atan2f( _vec[0], _vec[2] );
|
||||
const float theta = acosf( _vec[1] );
|
||||
|
||||
_u = ( idMath::PI + phi ) * ( 0.5f / idMath::PI );
|
||||
_v = theta * CMFT_RPI;
|
||||
}
|
||||
|
||||
static inline void VecFromLatLong( float _vec[3], float _u, float _v )
|
||||
{
|
||||
const float phi = _u * idMath::TWO_PI;
|
||||
const float theta = _v * idMath::PI;
|
||||
|
||||
_vec[0] = -sinf( theta ) * sinf( phi );
|
||||
_vec[1] = cosf( theta );
|
||||
_vec[2] = -sinf( theta ) * cosf( phi );
|
||||
}
|
||||
|
||||
byte* R_GenerateCubeMapSideFromPanoramaImage( const byte* in, int srcWidth, int srcHeight, int cubeWidth, int side )
|
||||
{
|
||||
size_t x = 0, y = 0;
|
||||
|
||||
const uint32 bytesPerPixel = 4;
|
||||
|
||||
const int copySize = cubeWidth * cubeWidth * bytesPerPixel;
|
||||
|
||||
byte* out = ( byte* )R_StaticAlloc( copySize, TAG_IMAGE );
|
||||
uint32_t* out_p = ( uint32_t* )out;
|
||||
|
||||
const uint32 dstFaceSize = cubeWidth;
|
||||
const uint32 dstPitch = dstFaceSize * bytesPerPixel;
|
||||
//const uint32 dstFaceDataSize = dstPitch * dstFaceSize;
|
||||
//const uint32 dstDataSize = dstFaceDataSize * 6;
|
||||
|
||||
const float srcWidthMinusOne = float( int32( srcWidth - 1 ) );
|
||||
const float srcHeightMinusOne = float( int32( srcHeight - 1 ) );
|
||||
const uint32 srcPitch = srcWidth * bytesPerPixel;
|
||||
const float invDstFaceSizef = 1.0f / float( dstFaceSize );
|
||||
|
||||
// maybe wrong, done by observation
|
||||
const idMat4 toDoomTransform( idAngles( -90, 0, -90 ).ToMat3(), vec3_origin );
|
||||
|
||||
byte* dstFaceData = ( byte* )out;// + face * dstFaceDataSize;
|
||||
for( int y = 0; y < dstFaceSize; y++ )
|
||||
{
|
||||
byte* dstRowData = ( byte* )dstFaceData + y * dstPitch;
|
||||
for( int x = 0; x < dstFaceSize; x++ )
|
||||
{
|
||||
// Cubemap (u,v) on current face.
|
||||
const float uu = 2.0f * x * invDstFaceSizef - 1.0f;
|
||||
const float vv = 2.0f * y * invDstFaceSizef - 1.0f;
|
||||
|
||||
// Get cubemap vector (x,y,z) from (u,v,faceIdx).
|
||||
idVec3 vec;
|
||||
TexelCoordToVec( &vec[0], uu, vv, side );
|
||||
vec = toDoomTransform * vec;
|
||||
|
||||
// Convert cubemap vector (x,y,z) to latlong (u,v).
|
||||
float xSrcf;
|
||||
float ySrcf;
|
||||
LatLongFromVec( xSrcf, ySrcf, &vec[0] );
|
||||
|
||||
// Convert from [0..1] to [0..(size-1)] range.
|
||||
xSrcf *= srcWidthMinusOne;
|
||||
ySrcf *= srcHeightMinusOne;
|
||||
|
||||
const int32 xSrc = int32( idMath::Fabs( idMath::Rint( xSrcf ) ) );
|
||||
const int32 ySrc = int32( idMath::Fabs( idMath::Rint( ySrcf ) ) );
|
||||
const byte* src = ( const byte* )in + ySrc * srcPitch + xSrc * bytesPerPixel ;
|
||||
|
||||
byte* dstColumnData = ( uint8_t* )dstRowData + x * bytesPerPixel;
|
||||
dstColumnData[0] = src[0];
|
||||
dstColumnData[1] = src[1];
|
||||
dstColumnData[2] = src[2];
|
||||
dstColumnData[3] = src[3];
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
// RB end
|
|
@ -1285,6 +1285,17 @@ void idMaterial::ParseFragmentMap( idLexer& src, newShaderStage_t* newStage )
|
|||
cubeMap = CF_SINGLE;
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "panoramaMap" ) )
|
||||
{
|
||||
cubeMap = CF_PANORAMA;
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "hdriMap" ) )
|
||||
{
|
||||
cubeMap = CF_PANORAMA;
|
||||
td = TD_R11G11B10F;
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "nearest" ) )
|
||||
{
|
||||
tf = TF_NEAREST;
|
||||
|
@ -1807,6 +1818,24 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "panoramaMap" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::Copynz( imageName, str, sizeof( imageName ) );
|
||||
cubeMap = CF_PANORAMA;
|
||||
td = TD_HIGHQUALITY_CUBE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "hdriMap" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::Copynz( imageName, str, sizeof( imageName ) );
|
||||
cubeMap = CF_PANORAMA;
|
||||
td = TD_R11G11B10F;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "cubeMapSize" ) )
|
||||
{
|
||||
cubeMapSize = src.ParseInt();
|
||||
|
|
Loading…
Reference in a new issue