mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-23 02:00:58 +00:00
Stencil shadows work again (thanks to Stephen Pridham), Renderer Sync #395
This commit is contained in:
parent
816d53790d
commit
f1668b7db8
34 changed files with 1046 additions and 503 deletions
|
@ -15,7 +15,7 @@ Thank you for downloading RBDOOM-3-BFG.
|
|||
|
||||
_______________________________________
|
||||
|
||||
02 March 2022 - RBDOOM-3-BFG 1.4.0
|
||||
06 March 2022 - RBDOOM-3-BFG 1.4.0
|
||||
_______________________________
|
||||
|
||||
<img src="https://i.imgur.com/3sUxOZi.jpg">
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
ID_TIME_T LoadFromGeneratedFile( ID_TIME_T sourceFileTime );
|
||||
ID_TIME_T WriteGeneratedFile( ID_TIME_T sourceFileTime );
|
||||
|
||||
const bimageFile_t& GetFileHeader()
|
||||
const bimageFile_t& GetFileHeader()
|
||||
{
|
||||
return fileData;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ public:
|
|||
return images[i].data;
|
||||
}
|
||||
static void GetGeneratedFileName( idStr& gfn, const char* imageName );
|
||||
|
||||
private:
|
||||
idStr imgName; // game path, including extension (except for cube maps), may be an image program
|
||||
bimageFile_t fileData;
|
||||
|
|
|
@ -44,12 +44,11 @@ This is where the Binary image headers go that are also included by external too
|
|||
|
||||
struct bimageImage_t
|
||||
{
|
||||
int level;
|
||||
int destZ;
|
||||
int level; // mip
|
||||
int destZ; // array slice
|
||||
int width;
|
||||
int height;
|
||||
int dataSize;
|
||||
// dataSize bytes follow
|
||||
int dataSize; // dataSize bytes follow
|
||||
};
|
||||
|
||||
#pragma pack( push, 1 )
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2014-2018 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -36,8 +37,15 @@ idList<Framebuffer*> Framebuffer::framebuffers;
|
|||
|
||||
globalFramebuffers_t globalFramebuffers;
|
||||
|
||||
Framebuffer* Framebuffer::Find( const char* name )
|
||||
{
|
||||
for( int i = 0; i < framebuffers.Num(); i++ )
|
||||
{
|
||||
if( idStr::Icmp( framebuffers[i]->fboName, name ) == 0 )
|
||||
{
|
||||
return framebuffers[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -54,8 +54,9 @@ public:
|
|||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static void CheckFramebuffers();
|
||||
static Framebuffer* Find( const char* name );
|
||||
static void ResizeFramebuffers();
|
||||
|
||||
void Bind();
|
||||
bool IsBound();
|
||||
|
@ -65,6 +66,7 @@ public:
|
|||
|
||||
void AddColorBuffer( int format, int index, int multiSamples = 0 );
|
||||
void AddDepthBuffer( int format, int multiSamples = 0 );
|
||||
void AddStencilBuffer( int format, int multiSamples = 0 );
|
||||
|
||||
void AttachImage2D( int target, const idImage* image, int index, int mipmapLod = 0 );
|
||||
void AttachImage3D( const idImage* image );
|
||||
|
@ -139,6 +141,7 @@ struct globalFramebuffers_t
|
|||
Framebuffer* smaaEdgesFBO;
|
||||
Framebuffer* smaaBlendFBO;
|
||||
};
|
||||
|
||||
extern globalFramebuffers_t globalFramebuffers;
|
||||
|
||||
#endif // __FRAMEBUFFER_H__
|
|
@ -407,6 +407,68 @@ This uses the "infinite far z" trick
|
|||
idCVar r_centerX( "r_centerX", "0", CVAR_FLOAT, "projection matrix center adjust" );
|
||||
idCVar r_centerY( "r_centerY", "0", CVAR_FLOAT, "projection matrix center adjust" );
|
||||
|
||||
inline float sgn( float a )
|
||||
{
|
||||
if( a > 0.0f )
|
||||
{
|
||||
return ( 1.0f );
|
||||
}
|
||||
if( a < 0.0f )
|
||||
{
|
||||
return ( -1.0f );
|
||||
}
|
||||
return ( 0.0f );
|
||||
}
|
||||
|
||||
// clipPlane is a plane in camera space.
|
||||
void ModifyProjectionMatrix( viewDef_t* viewDef, const idPlane& clipPlane )
|
||||
{
|
||||
static float s_flipMatrix[16] =
|
||||
{
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
0, 0, -1, 0,
|
||||
-1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
idMat4 flipMatrix;
|
||||
memcpy( &flipMatrix, &( s_flipMatrix[0] ), sizeof( float ) * 16 );
|
||||
|
||||
idVec4 vec = clipPlane.ToVec4();// * flipMatrix;
|
||||
idPlane newPlane( vec[0], vec[1], vec[2], vec[3] );
|
||||
|
||||
// Calculate the clip-space corner point opposite the clipping plane
|
||||
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
||||
// transform it into camera space by multiplying it
|
||||
// by the inverse of the projection matrix
|
||||
|
||||
//idVec4 q;
|
||||
//q.x = (sgn(newPlane[0]) + viewDef->projectionMatrix[8]) / viewDef->projectionMatrix[0];
|
||||
//q.y = (sgn(newPlane[1]) + viewDef->projectionMatrix[9]) / viewDef->projectionMatrix[5];
|
||||
//q.z = -1.0F;
|
||||
//q.w = (1.0F + viewDef->projectionMatrix[10]) / viewDef->projectionMatrix[14];
|
||||
|
||||
idMat4 unprojection;
|
||||
R_MatrixFullInverse( viewDef->projectionMatrix, ( float* )&unprojection );
|
||||
idVec4 q = unprojection * idVec4( sgn( newPlane[0] ), sgn( newPlane[1] ), 1.0f, 1.0f );
|
||||
|
||||
// Calculate the scaled plane vector
|
||||
idVec4 c = newPlane.ToVec4() * ( 2.0f / ( q * newPlane.ToVec4() ) );
|
||||
|
||||
float matrix[16];
|
||||
std::memcpy( matrix, viewDef->projectionMatrix, sizeof( float ) * 16 );
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
matrix[2] = c[0];
|
||||
matrix[6] = c[1];
|
||||
matrix[10] = c[2] + 1.0f;
|
||||
matrix[14] = c[3];
|
||||
|
||||
memcpy( viewDef->projectionMatrix, matrix, sizeof( float ) * 16 );
|
||||
}
|
||||
|
||||
void R_SetupProjectionMatrix( viewDef_t* viewDef )
|
||||
{
|
||||
// random jittering is usefull when multiple
|
||||
|
@ -493,6 +555,13 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
|
|||
viewDef->projectionMatrix[1 * 4 + 1] = -viewDef->projectionMatrix[1 * 4 + 1];
|
||||
viewDef->projectionMatrix[1 * 4 + 3] = -viewDef->projectionMatrix[1 * 4 + 3];
|
||||
}
|
||||
|
||||
// SP Begin
|
||||
if( viewDef->isObliqueProjection )
|
||||
{
|
||||
R_ObliqueProjection( viewDef );
|
||||
}
|
||||
// SP End
|
||||
}
|
||||
|
||||
|
||||
|
@ -606,4 +675,39 @@ void R_MatrixFullInverse( const float a[16], float r[16] )
|
|||
}
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
// RB end
|
||||
|
||||
// SP begin
|
||||
/*
|
||||
=====================
|
||||
R_ObliqueProjection - adjust near plane of previously set projection matrix to perform an oblique projection
|
||||
credits to motorsep: https://github.com/motorsep/StormEngine2/blob/743a0f9581a10837a91cb296ff5a1114535e8d4e/neo/renderer/tr_frontend_subview.cpp#L225
|
||||
=====================
|
||||
*/
|
||||
void R_ObliqueProjection( viewDef_t* parms )
|
||||
{
|
||||
float mvt[16]; // model view transpose
|
||||
idPlane pB = parms->clipPlanes[0];
|
||||
idPlane cp; // camera space plane
|
||||
R_MatrixTranspose( parms->worldSpace.modelViewMatrix, mvt );
|
||||
// transform plane (which is set to the surface we're mirroring about's plane) to camera space
|
||||
R_GlobalPlaneToLocal( mvt, pB, cp );
|
||||
|
||||
// oblique projection adjustment code
|
||||
idVec4 clipPlane( cp[0], cp[1], cp[2], cp[3] );
|
||||
idVec4 q;
|
||||
q[0] = ( ( clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f ) + parms->projectionMatrix[8] ) / parms->projectionMatrix[0];
|
||||
q[1] = ( ( clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f ) + parms->projectionMatrix[9] ) / parms->projectionMatrix[5];
|
||||
q[2] = -1.0f;
|
||||
q[3] = ( 1.0f + parms->projectionMatrix[10] ) / parms->projectionMatrix[14];
|
||||
|
||||
// scaled plane vector
|
||||
float d = 2.0f / ( clipPlane * q );
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
parms->projectionMatrix[2] = clipPlane[0] * d;
|
||||
parms->projectionMatrix[6] = clipPlane[1] * d;
|
||||
parms->projectionMatrix[10] = clipPlane[2] * d + 1.0f;
|
||||
parms->projectionMatrix[14] = clipPlane[3] * d;
|
||||
}
|
||||
// SP end
|
|
@ -68,4 +68,8 @@ void R_SetupProjectionMatrix2( const viewDef_t* viewDef, const float zNear, cons
|
|||
void R_MatrixFullInverse( const float in[16], float r[16] );
|
||||
// RB end
|
||||
|
||||
// SP begin
|
||||
void R_ObliqueProjection( viewDef_t* viewDef );
|
||||
// SP end
|
||||
|
||||
#endif /* !__GLMATRIX_H__ */
|
||||
|
|
|
@ -5,6 +5,7 @@ Doom 3 BFG Edition GPL Source Code
|
|||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2021 Robert Beckebans
|
||||
Copyright (C) 2016-2017 Dustin Land
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -28,6 +29,9 @@ If you have questions concerning this license or the applicable additional terms
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_H_
|
||||
#define IMAGE_H_
|
||||
|
||||
enum textureType_t
|
||||
{
|
||||
TT_DISABLED,
|
||||
|
@ -35,7 +39,7 @@ enum textureType_t
|
|||
TT_CUBIC,
|
||||
// RB begin
|
||||
TT_2D_ARRAY,
|
||||
TT_2D_MULTISAMPLE
|
||||
TT_2D_MULTISAMPLE,
|
||||
// RB end
|
||||
};
|
||||
|
||||
|
@ -101,6 +105,8 @@ enum textureFormat_t
|
|||
FMT_RGBA32F, // 128 bpp
|
||||
FMT_R32F, // 32 bpp
|
||||
FMT_R11G11B10F, // 32 bpp
|
||||
FMT_R8,
|
||||
FMT_DEPTH_STENCIL, // 32 bpp
|
||||
// RB end
|
||||
};
|
||||
|
||||
|
@ -157,6 +163,7 @@ public:
|
|||
int numLevels; // if 0, will be 1 for NEAREST / LINEAR filters, otherwise based on size
|
||||
bool gammaMips; // if true, mips will be generated with gamma correction
|
||||
bool readback; // 360 specific - cpu reads back from this texture, so allocate with cached memory
|
||||
bool isRenderTarget;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -175,8 +182,8 @@ ID_INLINE idImageOpts::idImageOpts()
|
|||
textureType = TT_2D;
|
||||
gammaMips = false;
|
||||
readback = false;
|
||||
|
||||
};
|
||||
isRenderTarget = false;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
|
@ -229,6 +236,8 @@ typedef enum
|
|||
TD_R32F,
|
||||
TD_R11G11B10F, // memory efficient HDR RGB format with only 32bpp
|
||||
// RB end
|
||||
TD_R8F, // Stephen: Added for ambient occlusion render target.
|
||||
TD_DEPTH_STENCIL, // depth buffer and stencil buffer
|
||||
} textureUsage_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -238,7 +247,8 @@ typedef enum
|
|||
CF_CAMERA, // _forward, _back, etc, rotated and flipped as needed before sending to GL
|
||||
CF_PANORAMA, // TODO latlong encoded HDRI panorama typically used by Substance or Blender
|
||||
CF_2D_ARRAY, // not a cube map but not a single 2d texture either
|
||||
CF_2D_PACKED_MIPCHAIN // usually 2d but can be an octahedron, packed mipmaps into single 2d texture atlas and limited to dim^2
|
||||
CF_2D_PACKED_MIPCHAIN, // usually 2d but can be an octahedron, packed mipmaps into single 2d texture atlas and limited to dim^2
|
||||
CF_SINGLE, // SP: A single texture cubemap. All six sides in one image.
|
||||
} cubeFiles_t;
|
||||
|
||||
enum imageFileType_t
|
||||
|
@ -266,7 +276,7 @@ public:
|
|||
return imgName;
|
||||
}
|
||||
|
||||
// Makes this image active on the current GL texture unit.
|
||||
// Makes this image active on the current texture unit.
|
||||
// automatically enables or disables cube mapping
|
||||
// May perform file loading if the image was not preloaded.
|
||||
void Bind();
|
||||
|
@ -365,12 +375,6 @@ public:
|
|||
int width, int height, const void* data,
|
||||
int pixelPitch = 0 );
|
||||
|
||||
// SetPixel is assumed to be a fast memory write on consoles, degenerating to a
|
||||
// SubImageUpload on PCs. Used to update the page mapping images.
|
||||
// We could remove this now, because the consoles don't use the intermediate page mapping
|
||||
// textures now that they can pack everything into the virtual page table images.
|
||||
void SetPixel( int mipLevel, int x, int y, const void* data, int dataSize );
|
||||
|
||||
// some scratch images are dynamically resized based on the display window size. This
|
||||
// simply purges the image and recreates it if the sizes are different, so it should not be
|
||||
// done under any normal circumstances, and probably not at all on consoles.
|
||||
|
@ -405,7 +409,9 @@ public:
|
|||
textureFilter_t filter,
|
||||
textureRepeat_t repeat,
|
||||
textureUsage_t usage,
|
||||
textureSamples_t samples = SAMPLE_1, cubeFiles_t cubeFiles = CF_2D );
|
||||
textureSamples_t samples = SAMPLE_1,
|
||||
cubeFiles_t cubeFiles = CF_2D,
|
||||
bool isRenderTarget = false );
|
||||
|
||||
void GenerateCubeImage( const byte* pic[6], int size,
|
||||
textureFilter_t filter, textureUsage_t usage );
|
||||
|
@ -433,13 +439,14 @@ public:
|
|||
private:
|
||||
friend class idImageManager;
|
||||
|
||||
void DeriveOpts();
|
||||
void AllocImage();
|
||||
void SetSamplerState( textureFilter_t tf, textureRepeat_t tr );
|
||||
void DeriveOpts();
|
||||
void AllocImage();
|
||||
void SetSamplerState( textureFilter_t tf, textureRepeat_t tr );
|
||||
|
||||
// parameters that define this image
|
||||
idStr imgName; // game path, including extension (except for cube maps), may be an image program
|
||||
cubeFiles_t cubeFiles; // If this is a cube map, and if so, what kind
|
||||
int cubeMapSize;
|
||||
void ( *generatorFunction )( idImage* image ); // NULL for files
|
||||
textureUsage_t usage; // Used to determine the type of compression to use
|
||||
idImageOpts opts; // Parameters that determine the storage method
|
||||
|
@ -526,7 +533,7 @@ public:
|
|||
// grid pattern.
|
||||
// Will automatically execute image programs if needed.
|
||||
idImage* ImageFromFile( const char* name,
|
||||
textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage, cubeFiles_t cubeMap = CF_2D );
|
||||
textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage, cubeFiles_t cubeMap = CF_2D, int cubeMapSize = 0 );
|
||||
|
||||
// look for a loaded image, whatever the parameters
|
||||
idImage* GetImage( const char* name ) const;
|
||||
|
@ -656,6 +663,11 @@ void R_VerticalFlip( byte* data, int width, int height );
|
|||
void R_VerticalFlipRGB16F( byte* data, int width, int height );
|
||||
void R_RotatePic( byte* data, int width );
|
||||
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 );
|
||||
// SP end
|
||||
|
||||
idVec4 R_CalculateMipRect( uint dimensions, uint mip );
|
||||
int R_CalculateUsedAtlasPixels( int dimensions );
|
||||
|
@ -672,7 +684,7 @@ IMAGEFILES
|
|||
void R_LoadImage( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp, bool makePowerOf2, textureUsage_t* usage );
|
||||
|
||||
// pic is in top to bottom raster format
|
||||
bool R_LoadCubeImages( const char* cname, cubeFiles_t extensions, byte* pic[6], int* size, ID_TIME_T* timestamp );
|
||||
bool R_LoadCubeImages( const char* cname, cubeFiles_t extensions, byte* pic[6], int* size, ID_TIME_T* timestamp, int cubeMapSize = 0 );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
@ -685,3 +697,4 @@ IMAGEPROGRAM
|
|||
void R_LoadImageProgram( const char* name, byte** pic, int* width, int* height, ID_TIME_T* timestamp, textureUsage_t* usage = NULL );
|
||||
const char* R_ParsePastImageProgram( idLexer& src );
|
||||
|
||||
#endif
|
|
@ -366,7 +366,7 @@ Loading of the image may be deferred for dynamic loading.
|
|||
==============
|
||||
*/
|
||||
idImage* idImageManager::ImageFromFile( const char* _name, textureFilter_t filter,
|
||||
textureRepeat_t repeat, textureUsage_t usage, cubeFiles_t cubeMap )
|
||||
textureRepeat_t repeat, textureUsage_t usage, cubeFiles_t cubeMap, int cubeMapSize )
|
||||
{
|
||||
|
||||
if( !_name || !_name[0] || idStr::Icmp( _name, "default" ) == 0 || idStr::Icmp( _name, "_default" ) == 0 )
|
||||
|
@ -845,17 +845,18 @@ int idImageManager::LoadLevelImages( bool pacifier )
|
|||
int loadCount = 0;
|
||||
for( int i = 0 ; i < images.Num() ; i++ )
|
||||
{
|
||||
idImage* image = images[ i ];
|
||||
|
||||
if( pacifier )
|
||||
{
|
||||
common->UpdateLevelLoadPacifier();
|
||||
|
||||
}
|
||||
|
||||
idImage* image = images[ i ];
|
||||
if( image->generatorFunction )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( image->levelLoadReferenced && !image->IsLoaded() )
|
||||
{
|
||||
loadCount++;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2012-2021 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -1514,7 +1515,7 @@ R_LoadCubeImages
|
|||
Loads six files with proper extensions
|
||||
=======================
|
||||
*/
|
||||
bool R_LoadCubeImages( const char* imgName, cubeFiles_t extensions, byte* pics[6], int* outSize, ID_TIME_T* timestamp )
|
||||
bool R_LoadCubeImages( const char* imgName, cubeFiles_t extensions, byte* pics[6], int* outSize, ID_TIME_T* timestamp, int cubeMapSize )
|
||||
{
|
||||
int i, j;
|
||||
const char* cameraSides[6] = { "_forward.tga", "_back.tga", "_left.tga", "_right.tga",
|
||||
|
@ -1546,6 +1547,74 @@ bool R_LoadCubeImages( const char* imgName, cubeFiles_t extensions, byte* pics[6
|
|||
*timestamp = 0;
|
||||
}
|
||||
|
||||
if( extensions == CF_SINGLE && cubeMapSize != 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
*outSize = cubeMapSize;
|
||||
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
pics[i] = R_GenerateCubeMapSideFromSingleImage( thisPic[0], width, height, cubeMapSize, i );
|
||||
switch( i )
|
||||
{
|
||||
case 0: // forward
|
||||
R_RotatePic( pics[i], cubeMapSize );
|
||||
break;
|
||||
case 1: // back
|
||||
R_RotatePic( pics[i], cubeMapSize );
|
||||
R_HorizontalFlip( pics[i], cubeMapSize, cubeMapSize );
|
||||
R_VerticalFlip( pics[i], cubeMapSize, cubeMapSize );
|
||||
break;
|
||||
case 2: // left
|
||||
R_VerticalFlip( pics[i], cubeMapSize, cubeMapSize );
|
||||
break;
|
||||
case 3: // right
|
||||
R_HorizontalFlip( pics[i], cubeMapSize, cubeMapSize );
|
||||
break;
|
||||
case 4: // up
|
||||
R_RotatePic( pics[i], cubeMapSize );
|
||||
break;
|
||||
case 5: // down
|
||||
R_RotatePic( pics[i], cubeMapSize );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
R_StaticFree( thisPic[0] );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for( i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] );
|
||||
|
|
|
@ -229,7 +229,7 @@ static void R_DepthImage( idImage* image )
|
|||
#else
|
||||
int msaaSamples = 0;
|
||||
#endif
|
||||
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_NEAREST, TR_CLAMP, TD_DEPTH );//, msaaSamples );
|
||||
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_NEAREST, TR_CLAMP, TD_DEPTH_STENCIL );//, msaaSamples );
|
||||
// RB end
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ static void R_EnvprobeImage_HDR( idImage* image )
|
|||
|
||||
static void R_EnvprobeImage_Depth( idImage* image )
|
||||
{
|
||||
image->GenerateImage( NULL, ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE, TF_NEAREST, TR_CLAMP, TD_DEPTH );
|
||||
image->GenerateImage( NULL, ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE, TF_NEAREST, TR_CLAMP, TD_DEPTH_STENCIL );
|
||||
}
|
||||
|
||||
static void R_SMAAImage_ResNative( idImage* image )
|
||||
|
@ -294,8 +294,24 @@ static void R_HierarchicalZBufferImage_ResNative( idImage* image )
|
|||
{
|
||||
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_NEAREST_MIPMAP, TR_CLAMP, TD_R32F );
|
||||
}
|
||||
|
||||
static void R_R8Image_ResNative_Linear( idImage* image )
|
||||
{
|
||||
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_LINEAR, TR_CLAMP, TD_LOOKUP_TABLE_MONO );
|
||||
}
|
||||
// RB end
|
||||
|
||||
static void R_HDR_RGBA8Image_ResNative( idImage* image )
|
||||
{
|
||||
// FIXME
|
||||
#if defined(USE_HDR_MSAA)
|
||||
int msaaSamples = glConfig.multisamples;
|
||||
#else
|
||||
int msaaSamples = 0;
|
||||
#endif
|
||||
image->GenerateImage( NULL, renderSystem->GetWidth(), renderSystem->GetHeight(), TF_NEAREST, TR_CLAMP, TD_LOOKUP_TABLE_RGBA ); //, msaaSamples );
|
||||
}
|
||||
|
||||
static void R_AlphaNotchImage( idImage* image )
|
||||
{
|
||||
byte data[2][4];
|
||||
|
|
|
@ -82,10 +82,14 @@ int BitsForFormat( textureFormat_t format )
|
|||
// RB end
|
||||
case FMT_DEPTH:
|
||||
return 32;
|
||||
case FMT_DEPTH_STENCIL:
|
||||
return 32;
|
||||
case FMT_X16:
|
||||
return 16;
|
||||
case FMT_Y16_X16:
|
||||
return 32;
|
||||
case FMT_R8:
|
||||
return 4;
|
||||
default:
|
||||
assert( 0 );
|
||||
return 0;
|
||||
|
@ -114,6 +118,12 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
opts.format = FMT_DEPTH;
|
||||
break;
|
||||
|
||||
// sp begin
|
||||
case TD_DEPTH_STENCIL:
|
||||
opts.format = FMT_DEPTH_STENCIL;
|
||||
break;
|
||||
// sp end
|
||||
|
||||
case TD_SHADOW_ARRAY:
|
||||
opts.format = FMT_SHADOW_ARRAY;
|
||||
break;
|
||||
|
@ -134,6 +144,10 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
opts.format = FMT_R32F;
|
||||
break;
|
||||
|
||||
case TD_R8F:
|
||||
opts.format = FMT_R8;
|
||||
break;
|
||||
|
||||
case TD_R11G11B10F:
|
||||
opts.format = FMT_R11G11B10F;
|
||||
break;
|
||||
|
@ -273,7 +287,6 @@ void idImage::GetGeneratedName( idStr& _name, const textureUsage_t& _usage, cons
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
ActuallyLoadImage
|
||||
|
@ -319,11 +332,11 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
|
|||
{
|
||||
opts.textureType = TT_2D_ARRAY;
|
||||
}
|
||||
else if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA )
|
||||
else if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_SINGLE )
|
||||
{
|
||||
opts.textureType = TT_CUBIC;
|
||||
repeat = TR_CLAMP;
|
||||
R_LoadCubeImages( GetName(), cubeFiles, NULL, NULL, &sourceFileTime );
|
||||
R_LoadCubeImages( GetName(), cubeFiles, NULL, NULL, &sourceFileTime, cubeMapSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -423,7 +436,9 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
|
|||
{
|
||||
opts.format = ( textureFormat_t )header.format;
|
||||
}
|
||||
|
||||
opts.textureType = ( textureType_t )header.textureType;
|
||||
|
||||
if( cvarSystem->GetCVarBool( "fs_buildresources" ) )
|
||||
{
|
||||
// for resource gathering write this image to the preload file for this map
|
||||
|
@ -454,12 +469,12 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
|
|||
//else if( toolUsage )
|
||||
// binarizeReason = va( "binarize: tool usage '%s'", generatedName.c_str() );
|
||||
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA )
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_SINGLE )
|
||||
{
|
||||
int size;
|
||||
byte* pics[6];
|
||||
|
||||
if( !R_LoadCubeImages( GetName(), cubeFiles, pics, &size, &sourceFileTime ) || size == 0 )
|
||||
if( !R_LoadCubeImages( GetName(), cubeFiles, pics, &size, &sourceFileTime, cubeMapSize ) || size == 0 )
|
||||
{
|
||||
idLib::Warning( "Couldn't load cube image: %s", GetName() );
|
||||
defaulted = true; // RB
|
||||
|
@ -750,7 +765,7 @@ void idImage::Reload( bool force )
|
|||
if( !force )
|
||||
{
|
||||
ID_TIME_T current;
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA )
|
||||
if( cubeFiles == CF_NATIVE || cubeFiles == CF_CAMERA || cubeFiles == CF_SINGLE )
|
||||
{
|
||||
R_LoadCubeImages( imgName, cubeFiles, NULL, NULL, ¤t );
|
||||
}
|
||||
|
@ -778,7 +793,7 @@ void idImage::Reload( bool force )
|
|||
GenerateImage
|
||||
================
|
||||
*/
|
||||
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, textureSamples_t samples, cubeFiles_t _cubeFiles )
|
||||
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, textureSamples_t samples, cubeFiles_t _cubeFiles, bool isRenderTarget )
|
||||
{
|
||||
PurgeImage();
|
||||
|
||||
|
@ -792,6 +807,7 @@ void idImage::GenerateImage( const byte* pic, int width, int height, textureFilt
|
|||
opts.height = height;
|
||||
opts.numLevels = 0;
|
||||
opts.samples = samples;
|
||||
opts.isRenderTarget = isRenderTarget;
|
||||
|
||||
// RB
|
||||
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
|
||||
|
@ -940,6 +956,8 @@ void idImage::GenerateShadowArray( int width, int height, textureFilter_t filter
|
|||
opts.width = width;
|
||||
opts.height = height;
|
||||
opts.numLevels = 0;
|
||||
opts.isRenderTarget = true;
|
||||
|
||||
DeriveOpts();
|
||||
|
||||
// if we don't have a rendering context, just return after we
|
||||
|
@ -980,6 +998,7 @@ void idImage::UploadScratch( const byte* data, int cols, int rows )
|
|||
{
|
||||
rows /= 6;
|
||||
const byte* pic[6];
|
||||
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
pic[i] = data + cols * rows * 4 * i;
|
||||
|
@ -990,6 +1009,7 @@ void idImage::UploadScratch( const byte* data, int cols, int rows )
|
|||
GenerateCubeImage( pic, cols, TF_LINEAR, TD_LOOKUP_TABLE_RGBA );
|
||||
return;
|
||||
}
|
||||
|
||||
if( opts.width != cols || opts.height != rows )
|
||||
{
|
||||
opts.width = cols;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2021 Robert Beckebans
|
||||
Copyright (C) 2021 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -628,3 +629,77 @@ int R_CalculateUsedAtlasPixels( int dimensions )
|
|||
|
||||
return numPixels;
|
||||
}
|
||||
|
||||
// SP begin
|
||||
|
||||
byte* R_GenerateCubeMapSideFromSingleImage( byte* data, int srcWidth, int srcHeight, int size, int side )
|
||||
{
|
||||
size_t x = 0, y = 0;
|
||||
switch( side )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// negative Z, front
|
||||
x = size;
|
||||
y = size;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// positive Z, back
|
||||
x = 3 * size;
|
||||
y = size;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// negative X, left
|
||||
x = 0;
|
||||
y = size;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// positive X, right
|
||||
x = size * 2;
|
||||
y = size;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// positive Y, top
|
||||
x = size;
|
||||
y = 0;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// negative Y, bottom
|
||||
x = size;
|
||||
y = 2 * ( size_t )size;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
common->Warning( "Invalid side when generating cube map images" );
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for( int j = 0; j < size; j++ )
|
||||
{
|
||||
for( int i = 0; i < size; i++ )
|
||||
{
|
||||
out_p[i + j * size] = in_p[i + j * srcWidth];
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// SP end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2021 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -390,6 +391,42 @@ static void R_ImageAdd( byte* data1, int width1, int height1, byte* data2, int w
|
|||
}
|
||||
}
|
||||
|
||||
// SP begin
|
||||
static void R_CombineRgba( byte* data1, int width1, int height1, byte* data2, int width2, int height2, byte* data3, int width3, int height3 )
|
||||
{
|
||||
assert( width1 == width2 );
|
||||
//assert(width2 == width3);
|
||||
assert( height1 == height2 );
|
||||
|
||||
for( int j = 0; j < 4 * height1; j += 4 )
|
||||
{
|
||||
for( int i = 0; i < 4 * width1; i += 4 )
|
||||
{
|
||||
// Assume that these textures are all grayscale images. just take the r channel of each and set them to
|
||||
// the respective rgb.
|
||||
byte r = data1[i + j * width1];
|
||||
|
||||
byte g = data2[i + j * width1];
|
||||
|
||||
byte b = 255;
|
||||
|
||||
if( data3 && width1 == width3 )
|
||||
{
|
||||
b = data3[i + j * width1];
|
||||
}
|
||||
|
||||
byte a = 255;
|
||||
|
||||
data1[0 + i + j * width1] = r;
|
||||
data1[1 + i + j * width1] = g;
|
||||
data1[2 + i + j * width1] = b;
|
||||
data1[3 + i + j * width1] = a;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// SP end
|
||||
|
||||
|
||||
// we build a canonical token form of the image program here
|
||||
static char parseBuffer[MAX_IMAGE_NAME];
|
||||
|
@ -710,6 +747,56 @@ static bool R_ParseImageProgram_r( idLexer& src, byte** pic, int* width, int* he
|
|||
return true;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "combineRgba" ) )
|
||||
{
|
||||
byte* pic2 = nullptr;
|
||||
byte* pic3 = nullptr;
|
||||
int width2, height2;
|
||||
int width3, height3;
|
||||
|
||||
MatchAndAppendToken( src, "(" );
|
||||
|
||||
if( !R_ParseImageProgram_r( src, pic, width, height, timestamps, usage ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MatchAndAppendToken( src, "," );
|
||||
|
||||
if( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, usage ) )
|
||||
{
|
||||
if( pic )
|
||||
{
|
||||
R_StaticFree( *pic );
|
||||
*pic = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MatchAndAppendToken( src, "," );
|
||||
|
||||
if( !R_ParseImageProgram_r( src, pic2 ? &pic3 : NULL, &width3, &height3, timestamps, usage ) )
|
||||
{
|
||||
if( pic )
|
||||
{
|
||||
R_StaticFree( *pic );
|
||||
*pic = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// process it
|
||||
if( pic )
|
||||
{
|
||||
R_CombineRgba( *pic, *width, *height, pic2, width2, height2, pic3, width3, height3 );
|
||||
R_StaticFree( pic2 );
|
||||
R_StaticFree( pic3 );
|
||||
}
|
||||
|
||||
MatchAndAppendToken( src, ")" );
|
||||
return true;
|
||||
}
|
||||
|
||||
// if we are just parsing instead of loading or checking,
|
||||
// don't do the R_LoadImage
|
||||
if( !timestamps && !pic )
|
||||
|
|
|
@ -5,6 +5,7 @@ Doom 3 BFG Edition GPL Source Code
|
|||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2014-2016 Robert Beckebans
|
||||
Copyright (C) 2014-2016 Kot in Action Creative Artel
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -89,6 +90,7 @@ void idMaterial::CommonInit()
|
|||
surfaceFlags = SURFTYPE_NONE;
|
||||
materialFlags = 0;
|
||||
sort = SS_BAD;
|
||||
subViewType = SUBVIEW_NONE;
|
||||
stereoEye = 0;
|
||||
coverage = MC_BAD;
|
||||
cullType = CT_FRONT_SIDED;
|
||||
|
@ -186,6 +188,11 @@ void idMaterial::FreeData()
|
|||
Mem_Free( stages[i].newStage );
|
||||
stages[i].newStage = NULL;
|
||||
}
|
||||
if( stages[i].stencilStage != nullptr )
|
||||
{
|
||||
Mem_Free( stages[i].stencilStage );
|
||||
stages[i].stencilStage = nullptr;
|
||||
}
|
||||
}
|
||||
R_StaticFree( stages );
|
||||
stages = NULL;
|
||||
|
@ -1268,6 +1275,11 @@ void idMaterial::ParseFragmentMap( idLexer& src, newShaderStage_t* newStage )
|
|||
cubeMap = CF_CAMERA;
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "cubeMapSingle" ) )
|
||||
{
|
||||
cubeMap = CF_SINGLE;
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "nearest" ) )
|
||||
{
|
||||
tf = TF_NEAREST;
|
||||
|
@ -1329,6 +1341,207 @@ void idMaterial::ParseFragmentMap( idLexer& src, newShaderStage_t* newStage )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idMaterial::ParseStencilCompare
|
||||
===============
|
||||
*/
|
||||
void idMaterial::ParseStencilCompare( const idToken& token, stencilComp_t* stencilComp )
|
||||
{
|
||||
if( !token.Icmp( "Greater" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_GREATER;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "GEqual" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_GEQUAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Less" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_LESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "LEqual" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_LEQUAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Equal" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_EQUAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "NotEqual" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_NOTEQUAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Always" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_ALWAYS;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Never" ) )
|
||||
{
|
||||
*stencilComp = STENCIL_COMP_NEVER;
|
||||
return;
|
||||
}
|
||||
|
||||
common->Warning( "Material %s expected a valid stencil comparison function. Got %s", GetName(), token.c_str() );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idMaterial::ParseStencilOperation
|
||||
===============
|
||||
*/
|
||||
void idMaterial::ParseStencilOperation( const idToken& token, stencilOperation_t* stencilOp )
|
||||
{
|
||||
if( !token.Icmp( "Keep" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_KEEP;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Zero" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Replace" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_REPLACE;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "IncrSat" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_INCRSAT;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "DecrSat" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_DECRSAT;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Invert" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_INVERT;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "IncrWrap" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_INCRWRAP;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "DecrWrap" ) )
|
||||
{
|
||||
*stencilOp = STENCIL_OP_DECRWRAP;
|
||||
return;
|
||||
}
|
||||
|
||||
common->Warning( "Material %s expected a valid stencil operation function. Got %s", GetName(), token.c_str() );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idMaterial::ParseStencil
|
||||
===============
|
||||
*/
|
||||
void idMaterial::ParseStencil( idLexer& src, stencilStage_t* stencilStage )
|
||||
{
|
||||
idToken token;
|
||||
src.ReadToken( &token );
|
||||
if( token.Icmp( "{" ) )
|
||||
{
|
||||
common->Warning( "Material %s Missing { after stencil", GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( TestMaterialFlag( MF_DEFAULTED ) ) // we have a parse error
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !src.ExpectAnyToken( &token ) )
|
||||
{
|
||||
SetMaterialFlag( MF_DEFAULTED );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "}" ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Ref" ) )
|
||||
{
|
||||
src.ReadTokenOnLine( &token );
|
||||
|
||||
if( !token.IsNumeric() )
|
||||
{
|
||||
common->Warning( "Material %s expected number for stencil ref value. Got %s", GetName(), token.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( token.GetIntValue() > 255 || token.GetIntValue() < 0 )
|
||||
{
|
||||
common->Warning( "Material %s expected stencil ref value between 0 and 255. Got %s", GetName(), token.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
stencilStage->ref = token.GetIntValue();
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Comp" ) )
|
||||
{
|
||||
src.ReadTokenOnLine( &token );
|
||||
ParseStencilCompare( token, &stencilStage->comp );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Pass" ) )
|
||||
{
|
||||
src.ReadTokenOnLine( &token );
|
||||
ParseStencilOperation( token, &stencilStage->pass );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "Fail" ) )
|
||||
{
|
||||
src.ReadTokenOnLine( &token );
|
||||
ParseStencilOperation( token, &stencilStage->fail );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "ZFail" ) )
|
||||
{
|
||||
src.ReadTokenOnLine( &token );
|
||||
ParseStencilOperation( token, &stencilStage->zFail );
|
||||
continue;
|
||||
}
|
||||
|
||||
common->Warning( "Material %s expected a valid stencil keyword. Got %s.", GetName(), token.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idMaterial::MultiplyTextureMatrix
|
||||
|
@ -1400,10 +1613,12 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
textureRepeat_t trp;
|
||||
textureUsage_t td;
|
||||
cubeFiles_t cubeMap;
|
||||
int cubeMapSize = 0; // SP: The size of the cubemap for subimage uploading to the cubemap targets.
|
||||
char imageName[MAX_IMAGE_NAME];
|
||||
int a, b;
|
||||
int matrix[2][3];
|
||||
newShaderStage_t newStage;
|
||||
stencilStage_t stencilStage; // SP
|
||||
|
||||
if( numStages >= MAX_SHADER_STAGES )
|
||||
{
|
||||
|
@ -1490,6 +1705,30 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
ts->texgen = TG_SCREEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "guiRenderMap" ) )
|
||||
{
|
||||
// Emit fullscreen view of the gui to this dynamically generated texture
|
||||
ts->dynamic = DI_GUI_RENDER;
|
||||
ts->width = src.ParseInt();
|
||||
ts->height = src.ParseInt();
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( !token.Icmp( "renderTargetMap" ) )
|
||||
{
|
||||
// Emit fullscreen view of the gui to this dynamically generated texture
|
||||
idToken otherMaterialToken;
|
||||
ts->dynamic = DI_RENDER_TARGET;
|
||||
src.ReadToken( &otherMaterialToken );
|
||||
ts->renderTargetMaterial = declManager->FindMaterial( otherMaterialToken.c_str() );
|
||||
ts->width = src.ParseInt();
|
||||
ts->height = src.ParseInt();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !token.Icmp( "screen" ) )
|
||||
{
|
||||
ts->texgen = TG_SCREEN;
|
||||
|
@ -1550,6 +1789,21 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "cubeMapSingle" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::Copynz( imageName, str, sizeof( imageName ) );
|
||||
cubeMap = CF_SINGLE;
|
||||
td = TD_HIGHQUALITY_CUBE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "cubeMapSize" ) )
|
||||
{
|
||||
cubeMapSize = src.ParseInt();
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !token.Icmp( "cameraCubeMap" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
|
@ -1921,6 +2175,16 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
continue;
|
||||
}
|
||||
|
||||
// SP Begin
|
||||
if( !token.Icmp( "stencil" ) )
|
||||
{
|
||||
ParseStencil( src, &stencilStage );
|
||||
ss->stencilStage = ( stencilStage_t* )Mem_Alloc( sizeof( stencilStage_t ), TAG_MATERIAL );
|
||||
*ss->stencilStage = stencilStage;
|
||||
continue;
|
||||
}
|
||||
// SP End
|
||||
|
||||
|
||||
common->Warning( "unknown token '%s' in material '%s'", token.c_str(), GetName() );
|
||||
SetMaterialFlag( MF_DEFAULTED );
|
||||
|
@ -1990,7 +2254,7 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
// now load the image with all the parms we parsed for the coverage stage
|
||||
if( imageName[0] )
|
||||
{
|
||||
coverageTS->image = globalImages->ImageFromFile( imageName, tf, trp, TD_COVERAGE, cubeMap );
|
||||
coverageTS->image = globalImages->ImageFromFile( imageName, tf, trp, TD_COVERAGE, cubeMap, cubeMapSize );
|
||||
if( !coverageTS->image )
|
||||
{
|
||||
coverageTS->image = globalImages->defaultImage;
|
||||
|
@ -2006,7 +2270,7 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
// now load the image with all the parms we parsed
|
||||
if( imageName[0] )
|
||||
{
|
||||
ts->image = globalImages->ImageFromFile( imageName, tf, trp, td, cubeMap );
|
||||
ts->image = globalImages->ImageFromFile( imageName, tf, trp, td, cubeMap, cubeMapSize );
|
||||
if( !ts->image )
|
||||
{
|
||||
ts->image = globalImages->defaultImage;
|
||||
|
@ -2314,7 +2578,6 @@ void idMaterial::ParseMaterial( idLexer& src )
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
// polygonOffset
|
||||
else if( !token.Icmp( "polygonOffset" ) )
|
||||
{
|
||||
|
@ -2448,6 +2711,15 @@ void idMaterial::ParseMaterial( idLexer& src )
|
|||
{
|
||||
sort = SS_SUBVIEW;
|
||||
coverage = MC_OPAQUE;
|
||||
subViewType = SUBVIEW_MIRROR;
|
||||
continue;
|
||||
}
|
||||
// direct portal
|
||||
else if( !token.Icmp( "directPortal" ) )
|
||||
{
|
||||
sort = SS_SUBVIEW;
|
||||
coverage = MC_OPAQUE;
|
||||
subViewType = SUBVIEW_DIRECT_PORTAL;
|
||||
continue;
|
||||
}
|
||||
// noFog
|
||||
|
|
|
@ -5,6 +5,7 @@ Doom 3 BFG Edition GPL Source Code
|
|||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2014-2020 Robert Beckebans
|
||||
Copyright (C) 2014-2016 Kot in Action Creative Artel
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -97,7 +98,9 @@ typedef enum
|
|||
DI_CUBE_RENDER,
|
||||
DI_MIRROR_RENDER,
|
||||
DI_XRAY_RENDER,
|
||||
DI_REMOTE_RENDER
|
||||
DI_REMOTE_RENDER,
|
||||
DI_GUI_RENDER,
|
||||
DI_RENDER_TARGET,
|
||||
} dynamicidImage_t;
|
||||
|
||||
// note: keep opNames[] in sync with changes
|
||||
|
@ -205,6 +208,61 @@ typedef enum
|
|||
SVC_INVERSE_MODULATE
|
||||
} stageVertexColor_t;
|
||||
|
||||
// SP Begin
|
||||
typedef enum
|
||||
{
|
||||
STENCIL_COMP_GREATER,
|
||||
STENCIL_COMP_GEQUAL,
|
||||
STENCIL_COMP_LESS,
|
||||
STENCIL_COMP_LEQUAL,
|
||||
STENCIL_COMP_EQUAL,
|
||||
STENCIL_COMP_NOTEQUAL,
|
||||
STENCIL_COMP_ALWAYS,
|
||||
STENCIL_COMP_NEVER
|
||||
} stencilComp_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STENCIL_OP_KEEP,
|
||||
STENCIL_OP_ZERO,
|
||||
STENCIL_OP_REPLACE,
|
||||
STENCIL_OP_INCRSAT,
|
||||
STENCIL_OP_DECRSAT,
|
||||
STENCIL_OP_INVERT,
|
||||
STENCIL_OP_INCRWRAP,
|
||||
STENCIL_OP_DECRWRAP
|
||||
} stencilOperation_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// The value to be compared against (if Comp is anything else than always) and/or the value to be written to the buffer
|
||||
// (if either Pass, Fail or ZFail is set to replace).
|
||||
byte ref = 0;
|
||||
|
||||
// An 8 bit mask as an 0–255 integer, used when comparing the reference value with the contents of the buffer
|
||||
// (referenceValue & readMask) comparisonFunction (stencilBufferValue & readMask).
|
||||
byte readMask = 255;
|
||||
|
||||
// An 8 bit mask as an 0–255 integer, used when writing to the buffer.Note that, like other write masks,
|
||||
// it specifies which bits of stencil buffer will be affected by write
|
||||
// (i.e.WriteMask 0 means that no bits are affected and not that 0 will be written).
|
||||
byte writeMask = 255;
|
||||
|
||||
// Function used to compare the reference value to the current contents of the buffer.
|
||||
stencilComp_t comp = STENCIL_COMP_ALWAYS;
|
||||
|
||||
// What to do with the contents of the buffer if the stencil test(and the depth test) passes.
|
||||
stencilOperation_t pass = STENCIL_OP_KEEP;
|
||||
|
||||
// What to do with the contents of the buffer if the stencil test fails.
|
||||
stencilOperation_t fail = STENCIL_OP_KEEP;
|
||||
|
||||
// What to do with the contents of the buffer if the stencil test passes, but the depth test fails.
|
||||
stencilOperation_t zFail = STENCIL_OP_KEEP;
|
||||
} stencilStage_t;
|
||||
// SP End
|
||||
|
||||
|
||||
static const int MAX_FRAGMENT_IMAGES = 8;
|
||||
static const int MAX_VERTEX_PARMS = 4;
|
||||
|
||||
|
@ -234,6 +292,7 @@ typedef struct
|
|||
// if the surface is alpha tested
|
||||
float privatePolygonOffset; // a per-stage polygon offset
|
||||
|
||||
stencilStage_t* stencilStage;
|
||||
newShaderStage_t* newStage; // vertex / fragment program based stage
|
||||
} shaderStage_t;
|
||||
|
||||
|
@ -267,6 +326,13 @@ typedef enum
|
|||
SS_POST_PROCESS = 100 // after a screen copy to texture
|
||||
} materialSort_t;
|
||||
|
||||
enum SubViewType : uint16_t
|
||||
{
|
||||
SUBVIEW_NONE,
|
||||
SUBVIEW_MIRROR,
|
||||
SUBVIEW_DIRECT_PORTAL
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CT_FRONT_SIDED,
|
||||
|
@ -377,6 +443,7 @@ typedef enum
|
|||
// won't collect light from any angle
|
||||
} surfaceFlags_t;
|
||||
|
||||
|
||||
class idSoundEmitter;
|
||||
|
||||
// RB: predefined Quake 1 light styles
|
||||
|
@ -497,6 +564,16 @@ public:
|
|||
return hasSubview;
|
||||
}
|
||||
|
||||
bool IsPortalSubView() const
|
||||
{
|
||||
return subViewType == SubViewType::SUBVIEW_DIRECT_PORTAL;
|
||||
}
|
||||
|
||||
bool IsMirrorSubView() const
|
||||
{
|
||||
return subViewType == SubViewType::SUBVIEW_MIRROR;
|
||||
}
|
||||
|
||||
// returns true if the material will generate shadows, not making a
|
||||
// distinction between global and no-self shadows
|
||||
bool SurfaceCastsShadow() const
|
||||
|
@ -882,6 +959,9 @@ private:
|
|||
void ParseVertexParm( idLexer& src, newShaderStage_t* newStage );
|
||||
void ParseVertexParm2( idLexer& src, newShaderStage_t* newStage );
|
||||
void ParseFragmentMap( idLexer& src, newShaderStage_t* newStage );
|
||||
void ParseStencilCompare( const idToken& token, stencilComp_t* stencilComp );
|
||||
void ParseStencilOperation( const idToken& token, stencilOperation_t* stencilOp );
|
||||
void ParseStencil( idLexer& src, stencilStage_t* stencilStage );
|
||||
void ParseStage( idLexer& src, const textureRepeat_t trpDefault = TR_REPEAT );
|
||||
void ParseDeform( idLexer& src );
|
||||
void ParseDecalInfo( idLexer& src );
|
||||
|
@ -939,6 +1019,7 @@ private:
|
|||
|
||||
materialCoverage_t coverage;
|
||||
cullType_t cullType; // CT_FRONT_SIDED, CT_BACK_SIDED, or CT_TWO_SIDED
|
||||
SubViewType subViewType; // SP added
|
||||
bool shouldCreateBackSides;
|
||||
|
||||
bool fogLight;
|
||||
|
|
|
@ -2489,8 +2489,9 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, idList<InputChannel>& pPerIndex
|
|||
numPrimitives = 1;
|
||||
}
|
||||
|
||||
pMesh->mFaceSize.AssureSize( numPrimitives );
|
||||
//pMesh->mFacePosIndices.AssureSize( indices.Num() / numOffsets );
|
||||
const int startFaceSize = pMesh->mFaceSize.Num();
|
||||
|
||||
pMesh->mFaceSize.AssureSize( Max( pMesh->mFaceSize.Size(), numPrimitives ) );
|
||||
|
||||
size_t appendedVerts = 0;
|
||||
for( size_t a = 0; a < numPrimitives; a++ )
|
||||
|
@ -2519,7 +2520,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, idList<InputChannel>& pPerIndex
|
|||
}
|
||||
|
||||
// store the face size to later reconstruct the face from
|
||||
pMesh->mFaceSize[a] = numPoints;
|
||||
pMesh->mFaceSize[startFaceSize + a] = numPoints;
|
||||
|
||||
// gather that number of vertices
|
||||
for( size_t b = 0; b < numPoints; b++ )
|
||||
|
|
|
@ -719,7 +719,6 @@ idRenderModelMD5::LoadBinaryModel
|
|||
*/
|
||||
bool idRenderModelMD5::LoadBinaryModel( idFile* file, const ID_TIME_T sourceTimeStamp )
|
||||
{
|
||||
|
||||
if( !idRenderModelStatic::LoadBinaryModel( file, sourceTimeStamp ) )
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -455,7 +455,38 @@ void Framebuffer::AddDepthBuffer( int format, int multiSamples )
|
|||
|
||||
if( notCreatedYet )
|
||||
{
|
||||
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer );
|
||||
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthBuffer );
|
||||
}
|
||||
|
||||
GL_CheckErrors();
|
||||
}
|
||||
|
||||
void Framebuffer::AddStencilBuffer( int format, int multiSamples )
|
||||
{
|
||||
stencilFormat = format;
|
||||
|
||||
bool notCreatedYet = stencilBuffer == 0;
|
||||
if( notCreatedYet )
|
||||
{
|
||||
glGenRenderbuffers( 1, &stencilBuffer );
|
||||
}
|
||||
|
||||
glBindRenderbuffer( GL_RENDERBUFFER, stencilBuffer );
|
||||
|
||||
if( multiSamples > 0 )
|
||||
{
|
||||
glRenderbufferStorageMultisample( GL_RENDERBUFFER, multiSamples, format, width, height );
|
||||
|
||||
msaaSamples = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
glRenderbufferStorage( GL_RENDERBUFFER, format, width, height );
|
||||
}
|
||||
|
||||
if( notCreatedYet )
|
||||
{
|
||||
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilBuffer );
|
||||
}
|
||||
|
||||
GL_CheckErrors();
|
||||
|
@ -486,7 +517,7 @@ void Framebuffer::AttachImageDepth( int target, const idImage* image )
|
|||
return;
|
||||
}
|
||||
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target, image->texnum, 0 );
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, target, image->texnum, 0 );
|
||||
}
|
||||
|
||||
void Framebuffer::AttachImageDepthLayer( const idImage* image, int layer )
|
||||
|
|
|
@ -53,6 +53,7 @@ idImage::idImage( const char* name ) : imgName( name )
|
|||
repeat = TR_REPEAT;
|
||||
usage = TD_DEFAULT;
|
||||
cubeFiles = CF_2D;
|
||||
cubeMapSize = 0;
|
||||
|
||||
referencedOutsideLevelLoad = false;
|
||||
levelLoadReferenced = false;
|
||||
|
@ -416,16 +417,6 @@ void idImage::SetSamplerState( textureFilter_t tf, textureRepeat_t tr )
|
|||
SetTexParameters();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idImage::SetPixel
|
||||
========================
|
||||
*/
|
||||
void idImage::SetPixel( int mipLevel, int x, int y, const void* data, int dataSize )
|
||||
{
|
||||
SubImageUpload( mipLevel, x, y, 0, 1, 1, data );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idImage::SetTexParameters
|
||||
|
@ -677,6 +668,12 @@ void idImage::AllocImage()
|
|||
dataType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case FMT_DEPTH_STENCIL:
|
||||
internalFormat = GL_DEPTH24_STENCIL8;
|
||||
dataFormat = GL_DEPTH_STENCIL;
|
||||
dataType = GL_UNSIGNED_INT_24_8;
|
||||
break;
|
||||
|
||||
case FMT_SHADOW_ARRAY:
|
||||
internalFormat = GL_DEPTH_COMPONENT;
|
||||
dataFormat = GL_DEPTH_COMPONENT;
|
||||
|
|
|
@ -2374,6 +2374,14 @@ void idRenderBackend::ImGui_Shutdown()
|
|||
|
||||
void idRenderBackend::ImGui_RenderDrawLists( ImDrawData* draw_data )
|
||||
{
|
||||
/*
|
||||
if( draw_data->CmdListsCount == 0 )
|
||||
{
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
#if IMGUI_BFGUI
|
||||
|
||||
tr.guiModel->EmitImGui( draw_data );
|
||||
|
|
|
@ -220,7 +220,6 @@ void idRenderProgManager::LoadShader( shader_t& shader )
|
|||
idStr hlslCode( hlslFileBuffer );
|
||||
idStr programHLSL = StripDeadCode( hlslCode, inFile, compileMacros, shader.builtin );
|
||||
programGLSL = ConvertCG2GLSL( programHLSL, inFile.c_str(), shader.stage, programUniforms, false, hasGPUSkinning, shader.vertexLayout );
|
||||
|
||||
fileSystem->WriteFile( outFileHLSL, programHLSL.c_str(), programHLSL.Length(), "fs_savepath" );
|
||||
fileSystem->WriteFile( outFileGLSL, programGLSL.c_str(), programGLSL.Length(), "fs_savepath" );
|
||||
fileSystem->WriteFile( outFileUniforms, programUniforms.c_str(), programUniforms.Length(), "fs_savepath" );
|
||||
|
|
|
@ -4804,9 +4804,13 @@ void idRenderBackend::Bloom( const viewDef_t* _viewDef )
|
|||
return;
|
||||
}
|
||||
|
||||
renderLog.OpenMainBlock( MRB_BLOOM );
|
||||
renderLog.OpenBlock( "Render_Bloom", colorBlue );
|
||||
|
||||
RENDERLOG_PRINTF( "---------- RB_Bloom( avg = %f, max = %f, key = %f ) ----------\n", hdrAverageLuminance, hdrMaxLuminance, hdrKey );
|
||||
|
||||
// BRIGHTPASS
|
||||
renderLog.OpenBlock( "Brightpass" );
|
||||
|
||||
//GL_CheckErrors();
|
||||
|
||||
|
@ -4887,6 +4891,10 @@ void idRenderBackend::Bloom( const viewDef_t* _viewDef )
|
|||
// Draw
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
|
||||
renderLog.CloseBlock(); // Brightpass
|
||||
|
||||
renderLog.OpenBlock( "Bloom Ping Pong" );
|
||||
|
||||
// BLOOM PING PONG rendering
|
||||
renderProgManager.BindShader_HDRGlareChromatic();
|
||||
|
||||
|
@ -4918,9 +4926,14 @@ void idRenderBackend::Bloom( const viewDef_t* _viewDef )
|
|||
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
|
||||
renderLog.CloseBlock(); // Bloom Ping Pong
|
||||
|
||||
renderProgManager.Unbind();
|
||||
|
||||
GL_State( GLS_DEFAULT );
|
||||
|
||||
renderLog.CloseBlock(); // Render_Bloom
|
||||
renderLog.CloseMainBlock(); // MRB_BLOOM
|
||||
}
|
||||
|
||||
|
||||
|
@ -5027,8 +5040,6 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
|
|||
GL_Viewport( 0, 0, aoScreenWidth, aoScreenHeight );
|
||||
GL_Scissor( 0, 0, aoScreenWidth, aoScreenHeight );
|
||||
|
||||
|
||||
|
||||
if( downModulateScreen )
|
||||
{
|
||||
if( r_ssaoFiltering.GetBool() )
|
||||
|
@ -5294,7 +5305,6 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
|
|||
glClearColor( 0, 0, 0, 1 );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
//globalImages->currentDepthImage->Bind();
|
||||
|
||||
for( int i = 0; i < MAX_HIERARCHICAL_ZBUFFERS; i++ )
|
||||
{
|
||||
|
@ -5709,7 +5719,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
|
|||
|
||||
//GL_CheckErrors();
|
||||
|
||||
#if !defined(USE_VULKAN)
|
||||
#if !defined( USE_VULKAN ) && !defined( USE_NVRHI )
|
||||
// bind one global Vertex Array Object (VAO)
|
||||
glBindVertexArray( glConfig.global_vao );
|
||||
#endif
|
||||
|
|
|
@ -605,6 +605,7 @@ struct viewDef_t
|
|||
bool isEditor;
|
||||
bool is2Dgui;
|
||||
|
||||
bool isObliqueProjection; // true if this view has an oblique projection
|
||||
int numClipPlanes; // mirrors will often use a single clip plane
|
||||
idPlane clipPlanes[MAX_CLIP_PLANES]; // in world space, the positive side
|
||||
// of the plane is the visible side
|
||||
|
@ -653,6 +654,8 @@ struct viewDef_t
|
|||
idImage* irradianceImage; // cubemap image used for diffuse IBL by backend
|
||||
idImage* radianceImages[3]; // cubemap image used for specular IBL by backend
|
||||
idVec4 radianceImageBlends; // blending weights
|
||||
|
||||
Framebuffer* targetRender; // The framebuffer to render to
|
||||
};
|
||||
|
||||
|
||||
|
@ -802,9 +805,6 @@ const idMaterial* R_RemapShaderBySkin( const idMaterial* shader, const idDeclSki
|
|||
|
||||
//====================================================
|
||||
|
||||
|
||||
|
||||
|
||||
enum vertexLayoutType_t
|
||||
{
|
||||
LAYOUT_UNKNOWN = 0, // RB: TODO -1
|
||||
|
@ -1188,6 +1188,7 @@ extern idCVar r_shadowMapRegularDepthBiasScale;
|
|||
extern idCVar r_shadowMapSunDepthBiasScale;
|
||||
|
||||
extern idCVar r_hdrAutoExposure;
|
||||
extern idCVar r_hdrAdaptionRate;
|
||||
extern idCVar r_hdrMinLuminance;
|
||||
extern idCVar r_hdrMaxLuminance;
|
||||
extern idCVar r_hdrKey;
|
||||
|
@ -1253,8 +1254,8 @@ struct vidMode_t
|
|||
// RB begin
|
||||
vidMode_t()
|
||||
{
|
||||
width = 640;
|
||||
height = 480;
|
||||
width = SCREEN_WIDTH;
|
||||
height = SCREEN_HEIGHT;
|
||||
displayHz = 60;
|
||||
}
|
||||
|
||||
|
@ -1476,6 +1477,8 @@ TR_FRONTEND_DEFORM
|
|||
|
||||
drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf );
|
||||
|
||||
drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf, deform_t deformType );
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ TODO: Emit statistics to the logfile at the end of views and frames.
|
|||
================================================================================================
|
||||
*/
|
||||
|
||||
idCVar r_logLevel( "r_logLevel", "2", CVAR_INTEGER, "1 = blocks only, 2 = everything", 1, 2 );
|
||||
idCVar r_logLevel( "r_logLevel", "0", CVAR_INTEGER, "1 = blocks only, 2 = everything", 1, 2 );
|
||||
|
||||
static const int LOG_LEVEL_BLOCKS_ONLY = 1;
|
||||
static const int LOG_LEVEL_EVERYTHING = 2;
|
||||
|
@ -53,12 +53,13 @@ const char* renderLogMainBlockLabels[] =
|
|||
ASSERT_ENUM_STRING( MRB_DRAW_INTERACTIONS, 6 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES, 7 ),
|
||||
ASSERT_ENUM_STRING( MRB_FOG_ALL_LIGHTS, 8 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES_POST, 9 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_DEBUG_TOOLS, 10 ),
|
||||
ASSERT_ENUM_STRING( MRB_CAPTURE_COLORBUFFER, 11 ),
|
||||
ASSERT_ENUM_STRING( MRB_POSTPROCESS, 12 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_GUI, 13 ),
|
||||
ASSERT_ENUM_STRING( MRB_TOTAL, 14 )
|
||||
ASSERT_ENUM_STRING( MRB_BLOOM, 9 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_SHADER_PASSES_POST, 10 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_DEBUG_TOOLS, 11 ),
|
||||
ASSERT_ENUM_STRING( MRB_CAPTURE_COLORBUFFER, 12 ),
|
||||
ASSERT_ENUM_STRING( MRB_POSTPROCESS, 13 ),
|
||||
ASSERT_ENUM_STRING( MRB_DRAW_GUI, 14 ),
|
||||
ASSERT_ENUM_STRING( MRB_TOTAL, 15 )
|
||||
};
|
||||
|
||||
#if defined( USE_VULKAN )
|
||||
|
@ -107,6 +108,11 @@ FIXME: this is not thread safe on the PC
|
|||
*/
|
||||
void PC_BeginNamedEvent( const char* szName, const idVec4& color )
|
||||
{
|
||||
if( r_logLevel.GetInteger() <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( USE_VULKAN )
|
||||
|
||||
// start an annotated group of calls under the this name
|
||||
|
@ -190,6 +196,11 @@ PC_EndNamedEvent
|
|||
*/
|
||||
void PC_EndNamedEvent()
|
||||
{
|
||||
if( r_logLevel.GetInteger() <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( USE_VULKAN )
|
||||
// SRS - Prefer VK_EXT_debug_utils over VK_EXT_debug_marker/VK_EXT_debug_report (deprecated by VK_EXT_debug_utils)
|
||||
if( vkcontext.debugUtilsSupportAvailable )
|
||||
|
@ -284,308 +295,7 @@ idRenderLog
|
|||
|
||||
idRenderLog renderLog;
|
||||
|
||||
#if !defined( STUB_RENDER_LOG )
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::idRenderLog
|
||||
========================
|
||||
*/
|
||||
idRenderLog::idRenderLog()
|
||||
{
|
||||
activeLevel = 0;
|
||||
indentString[0] = '\0';
|
||||
indentLevel = 0;
|
||||
// logFile = NULL;
|
||||
|
||||
frameStartTime = 0;
|
||||
closeBlockTime = 0;
|
||||
logLevel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::StartFrame
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::StartFrame()
|
||||
{
|
||||
if( r_logFile.GetInteger() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// open a new logfile
|
||||
indentLevel = 0;
|
||||
indentString[0] = '\0';
|
||||
activeLevel = r_logLevel.GetInteger();
|
||||
|
||||
/*
|
||||
struct tm* newtime;
|
||||
time_t aclock;
|
||||
|
||||
char ospath[ MAX_OSPATH ];
|
||||
|
||||
char qpath[128];
|
||||
sprintf( qpath, "renderlogPC_%04i.txt", r_logFile.GetInteger() );
|
||||
//idStr finalPath = fileSystem->RelativePathToOSPath( qpath );
|
||||
sprintf( ospath, "%s", qpath );
|
||||
*/
|
||||
/*
|
||||
for ( int i = 0; i < 9999 ; i++ ) {
|
||||
char qpath[128];
|
||||
sprintf( qpath, "renderlog_%04i.txt", r_logFile.GetInteger() );
|
||||
idStr finalPath = fileSystem->RelativePathToOSPath( qpath );
|
||||
fileSystem->RelativePathToOSPath( qpath, ospath, MAX_OSPATH ,FSPATH_BASE );
|
||||
if ( !fileSystem->FileExists( finalPath.c_str() ) ) {
|
||||
break; // use this name
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
common->SetRefreshOnPrint( false ); // problems are caused if this print causes a refresh...
|
||||
|
||||
/*
|
||||
if( logFile != NULL )
|
||||
{
|
||||
fileSystem->CloseFile( logFile );
|
||||
logFile = NULL;
|
||||
}
|
||||
|
||||
logFile = fileSystem->OpenFileWrite( ospath );
|
||||
if( logFile == NULL )
|
||||
{
|
||||
idLib::Warning( "Failed to open logfile %s", ospath );
|
||||
return;
|
||||
}
|
||||
idLib::Printf( "Opened logfile %s\n", ospath );
|
||||
|
||||
// write the time out to the top of the file
|
||||
time( &aclock );
|
||||
newtime = localtime( &aclock );
|
||||
const char* str = asctime( newtime );
|
||||
logFile->Printf( "// %s", str );
|
||||
logFile->Printf( "// %s\n\n", com_version.GetString() );
|
||||
*/
|
||||
|
||||
frameStartTime = Sys_Microseconds();
|
||||
closeBlockTime = frameStartTime;
|
||||
OpenBlock( "Frame" );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::EndFrame
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::EndFrame()
|
||||
{
|
||||
PC_EndFrame();
|
||||
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
if( r_logFile.GetInteger() == 1 )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
// log is open, so decrement r_logFile and stop if it is zero
|
||||
//r_logFile.SetInteger( r_logFile.GetInteger() - 1 );
|
||||
//idLib::Printf( "Frame logged.\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::Close
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::Close()
|
||||
{
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
CloseBlock();
|
||||
//idLib::Printf( "Closing logfile\n" );
|
||||
//fileSystem->CloseFile( logFile );
|
||||
//logFile = NULL;
|
||||
activeLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::OpenMainBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::OpenMainBlock( renderLogMainBlock_t block )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::CloseMainBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::CloseMainBlock()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::OpenBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::OpenBlock( const char* label )
|
||||
{
|
||||
// Allow the PIX functionality even when logFile is not running.
|
||||
PC_BeginNamedEvent( label );
|
||||
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
LogOpenBlock( RENDER_LOG_INDENT_MAIN_BLOCK, "%s", label );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::CloseBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::CloseBlock()
|
||||
{
|
||||
PC_EndNamedEvent();
|
||||
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
LogCloseBlock( RENDER_LOG_INDENT_MAIN_BLOCK );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::Printf
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::Printf( const char* fmt, ... )
|
||||
{
|
||||
#if !defined(USE_VULKAN)
|
||||
if( activeLevel <= LOG_LEVEL_BLOCKS_ONLY )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if( logFile == NULL )
|
||||
if( r_logFile.GetInteger() == 0 || !glConfig.gremedyStringMarkerAvailable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list marker;
|
||||
char msg[4096];
|
||||
|
||||
idStr out = indentString;
|
||||
|
||||
va_start( marker, fmt );
|
||||
idStr::vsnPrintf( msg, sizeof( msg ), fmt, marker );
|
||||
va_end( marker );
|
||||
|
||||
msg[sizeof( msg ) - 1] = '\0';
|
||||
|
||||
out.Append( msg );
|
||||
|
||||
glStringMarkerGREMEDY( out.Length(), out.c_str() );
|
||||
|
||||
//logFile->Printf( "%s", indentString );
|
||||
//va_start( marker, fmt );
|
||||
//logFile->VPrintf( fmt, marker );
|
||||
//va_end( marker );
|
||||
|
||||
|
||||
// logFile->Flush(); this makes it take waaaay too long
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::LogOpenBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::LogOpenBlock( renderLogIndentLabel_t label, const char* fmt, ... )
|
||||
{
|
||||
uint64 now = Sys_Microseconds();
|
||||
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
//if( now - closeBlockTime >= 1000 )
|
||||
//{
|
||||
//logFile->Printf( "%s%1.1f msec gap from last closeblock\n", indentString, ( now - closeBlockTime ) * ( 1.0f / 1000.0f ) );
|
||||
//}
|
||||
|
||||
#if !defined(USE_VULKAN)
|
||||
if( glConfig.gremedyStringMarkerAvailable )
|
||||
{
|
||||
//Printf( fmt, args );
|
||||
//Printf( " {\n" );
|
||||
|
||||
//logFile->Printf( "%s", indentString );
|
||||
//logFile->VPrintf( fmt, args );
|
||||
//logFile->Printf( " {\n" );
|
||||
|
||||
va_list marker;
|
||||
char msg[4096];
|
||||
|
||||
idStr out = indentString;
|
||||
|
||||
va_start( marker, fmt );
|
||||
idStr::vsnPrintf( msg, sizeof( msg ), fmt, marker );
|
||||
va_end( marker );
|
||||
|
||||
msg[sizeof( msg ) - 1] = '\0';
|
||||
|
||||
out.Append( msg );
|
||||
out += " {";
|
||||
|
||||
glStringMarkerGREMEDY( out.Length(), out.c_str() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Indent( label );
|
||||
|
||||
if( logLevel >= MAX_LOG_LEVELS )
|
||||
{
|
||||
idLib::Warning( "logLevel %d >= MAX_LOG_LEVELS", logLevel );
|
||||
}
|
||||
|
||||
|
||||
logLevel++;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::LogCloseBlock
|
||||
========================
|
||||
*/
|
||||
void idRenderLog::LogCloseBlock( renderLogIndentLabel_t label )
|
||||
{
|
||||
closeBlockTime = Sys_Microseconds();
|
||||
|
||||
//assert( logLevel > 0 );
|
||||
logLevel--;
|
||||
|
||||
Outdent( label );
|
||||
|
||||
//if( logFile != NULL )
|
||||
//{
|
||||
//}
|
||||
}
|
||||
|
||||
#else // !STUB_RENDER_LOG
|
||||
|
||||
// RB begin
|
||||
/*
|
||||
|
@ -708,6 +418,4 @@ void idRenderLog::CloseBlock()
|
|||
{
|
||||
PC_EndNamedEvent();
|
||||
}
|
||||
// RB end
|
||||
|
||||
#endif // !STUB_RENDER_LOG
|
||||
// RB end
|
|
@ -35,9 +35,6 @@ Contains the RenderLog declaration.
|
|||
================================================================================================
|
||||
*/
|
||||
|
||||
#if 1 //defined(ID_RETAIL) && !defined(ID_RETAIL_INTERNAL)
|
||||
#define STUB_RENDER_LOG
|
||||
#endif
|
||||
|
||||
enum renderLogMainBlock_t
|
||||
{
|
||||
|
@ -51,6 +48,7 @@ enum renderLogMainBlock_t
|
|||
MRB_DRAW_INTERACTIONS,
|
||||
MRB_DRAW_SHADER_PASSES,
|
||||
MRB_FOG_ALL_LIGHTS,
|
||||
MRB_BLOOM,
|
||||
MRB_DRAW_SHADER_PASSES_POST,
|
||||
MRB_DRAW_DEBUG_TOOLS,
|
||||
MRB_CAPTURE_COLORBUFFER,
|
||||
|
@ -73,102 +71,7 @@ enum renderLogIndentLabel_t
|
|||
// using this macro avoids printf parameter overhead if the renderlog isn't active
|
||||
#define RENDERLOG_PRINTF( ... ) if ( renderLog.activeLevel ) renderLog.Printf( __VA_ARGS__ );
|
||||
|
||||
#if !defined( STUB_RENDER_LOG )
|
||||
|
||||
/*
|
||||
================================================
|
||||
idRenderLog contains block-based performance-tuning information. It combines
|
||||
logfile, and msec accumulation code.
|
||||
================================================
|
||||
*/
|
||||
class idRenderLog
|
||||
{
|
||||
public:
|
||||
idRenderLog();
|
||||
|
||||
void StartFrame();
|
||||
void EndFrame();
|
||||
void Close();
|
||||
int Active()
|
||||
{
|
||||
return activeLevel; // returns greater than 1 for more detailed logging
|
||||
}
|
||||
|
||||
// The label must be a constant string literal and may not point to a temporary.
|
||||
void OpenMainBlock( renderLogMainBlock_t block );
|
||||
void CloseMainBlock();
|
||||
|
||||
void OpenBlock( const char* label );
|
||||
void CloseBlock();
|
||||
|
||||
void Indent( renderLogIndentLabel_t label = RENDER_LOG_INDENT_DEFAULT );
|
||||
void Outdent( renderLogIndentLabel_t label = RENDER_LOG_INDENT_DEFAULT );
|
||||
|
||||
void Printf( VERIFY_FORMAT_STRING const char* fmt, ... );
|
||||
|
||||
static const int MAX_LOG_LEVELS = 20;
|
||||
|
||||
int activeLevel;
|
||||
renderLogIndentLabel_t indentLabel[MAX_LOG_LEVELS];
|
||||
char indentString[MAX_LOG_LEVELS * 4];
|
||||
int indentLevel;
|
||||
const char* lastLabel;
|
||||
renderLogMainBlock_t lastMainBlock;
|
||||
// idFile* logFile;
|
||||
|
||||
struct logStats_t
|
||||
{
|
||||
uint64 startTiming;
|
||||
int startDraws;
|
||||
int startIndexes;
|
||||
};
|
||||
|
||||
uint64 frameStartTime;
|
||||
uint64 closeBlockTime;
|
||||
logStats_t logStats[MAX_LOG_LEVELS];
|
||||
int logLevel;
|
||||
|
||||
void LogOpenBlock( renderLogIndentLabel_t label, const char* fmt, ... );
|
||||
void LogCloseBlock( renderLogIndentLabel_t label );
|
||||
};
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::Indent
|
||||
========================
|
||||
*/
|
||||
ID_INLINE void idRenderLog::Indent( renderLogIndentLabel_t label )
|
||||
{
|
||||
//if( logFile != NULL )
|
||||
if( r_logFile.GetInteger() != 0 )
|
||||
{
|
||||
indentLabel[indentLevel] = label;
|
||||
indentLevel++;
|
||||
for( int i = 4; i > 0; i-- )
|
||||
{
|
||||
indentString[indentLevel * 4 - i] = ' ';
|
||||
}
|
||||
indentString[indentLevel * 4] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idRenderLog::Outdent
|
||||
========================
|
||||
*/
|
||||
ID_INLINE void idRenderLog::Outdent( renderLogIndentLabel_t label )
|
||||
{
|
||||
//if( logFile != NULL && indentLevel > 0 )
|
||||
if( r_logFile.GetInteger() != 0 && indentLevel > 0 )
|
||||
{
|
||||
indentLevel--;
|
||||
assert( indentLabel[indentLevel] == label ); // indent and outdent out of sync ?
|
||||
indentString[indentLevel * 4] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#else // !STUB_RENDER_LOG
|
||||
|
||||
/*
|
||||
================================================
|
||||
|
@ -207,8 +110,6 @@ public:
|
|||
int activeLevel;
|
||||
};
|
||||
|
||||
#endif // !STUB_RENDER_LOG
|
||||
|
||||
extern idRenderLog renderLog;
|
||||
|
||||
#endif // !__RENDERLOG_H__
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2014-2016 Robert Beckebans
|
||||
Copyright (C) 2014-2021 Robert Beckebans
|
||||
Copyright (C) 2014-2016 Kot in Action Creative Artel
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
|
|
@ -1074,6 +1074,7 @@ void idRenderWorldLocal::RenderScene( const renderView_t* renderView )
|
|||
// setup view parms for the initial view
|
||||
viewDef_t* parms = ( viewDef_t* )R_ClearedFrameAlloc( sizeof( *parms ), FRAME_ALLOC_VIEW_DEF );
|
||||
parms->renderView = *renderView;
|
||||
parms->targetRender = nullptr;
|
||||
|
||||
if( tr.takingScreenshot )
|
||||
{
|
||||
|
@ -1102,6 +1103,7 @@ void idRenderWorldLocal::RenderScene( const renderView_t* renderView )
|
|||
parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1;
|
||||
|
||||
parms->isSubview = false;
|
||||
parms->isObliqueProjection = false;
|
||||
parms->initialViewAreaOrigin = renderView->vieworg;
|
||||
parms->renderWorld = this;
|
||||
|
||||
|
|
|
@ -719,7 +719,7 @@ void idRenderWorldLocal::WriteRenderLight( idDemoFile* f, qhandle_t handle, cons
|
|||
ReadRenderLight
|
||||
================
|
||||
*/
|
||||
void idRenderWorldLocal::ReadRenderLight( )
|
||||
void idRenderWorldLocal::ReadRenderLight()
|
||||
{
|
||||
renderLight_t light;
|
||||
int index, i;
|
||||
|
|
|
@ -78,6 +78,7 @@ static VkFormat VK_GetFormatFromTextureFormat( const textureFormat_t format )
|
|||
case FMT_DXT5:
|
||||
return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
case FMT_DEPTH:
|
||||
case FMT_DEPTH_STENCIL:
|
||||
return vkcontext.depthFormat;
|
||||
case FMT_X16:
|
||||
return VK_FORMAT_R16_UNORM;
|
||||
|
|
|
@ -386,6 +386,8 @@ static void R_AddSingleLight( viewLight_t* vLight )
|
|||
vLight->entityInteractionState[ edef->index ] = viewLight_t::INTERACTION_NO;
|
||||
|
||||
// The table is updated at interaction::AllocAndLink() and interaction::UnlinkAndFree()
|
||||
|
||||
// TODO(Stephen): interactionTableRow is null if renderDef is used in a gui.sub
|
||||
const idInteraction* inter = interactionTableRow[ edef->index ];
|
||||
|
||||
const renderEntity_t& eParms = edef->parms;
|
||||
|
|
|
@ -1133,11 +1133,21 @@ drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return R_DeformDrawSurf( drawSurf, drawSurf->material->Deform() );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DeformDrawSurf
|
||||
=================
|
||||
*/
|
||||
drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf, deform_t deformType )
|
||||
{
|
||||
if( r_skipDeforms.GetBool() )
|
||||
{
|
||||
return drawSurf;
|
||||
}
|
||||
switch( drawSurf->material->Deform() )
|
||||
switch( deformType )
|
||||
{
|
||||
case DFRM_SPRITE:
|
||||
return R_AutospriteDeform( drawSurf );
|
||||
|
@ -1160,4 +1170,4 @@ drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf )
|
|||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2014 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -228,6 +229,7 @@ static viewDef_t* R_MirrorViewBySurface( const drawSurf_t* drawSurf )
|
|||
viewDef_t* parms = ( viewDef_t* )R_FrameAlloc( sizeof( *parms ) );
|
||||
*parms = *tr.viewDef;
|
||||
parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons
|
||||
parms->targetRender = nullptr;
|
||||
|
||||
parms->isSubview = true;
|
||||
parms->isMirror = true;
|
||||
|
@ -271,6 +273,97 @@ static viewDef_t* R_MirrorViewBySurface( const drawSurf_t* drawSurf )
|
|||
return parms;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
R_PortalViewBySurface
|
||||
========================
|
||||
*/
|
||||
static viewDef_t* R_PortalViewBySurface( const drawSurf_t* surf )
|
||||
{
|
||||
if( !surf->space->entityDef->parms.remoteRenderView )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// copy the viewport size from the original
|
||||
viewDef_t* parms = ( viewDef_t* )R_FrameAlloc( sizeof( *parms ) );
|
||||
*parms = *tr.viewDef;
|
||||
|
||||
idMat3 viewaxis = parms->renderView.viewaxis;
|
||||
idMat3 remoteViewAxis = surf->space->entityDef->parms.remoteRenderView->viewaxis;
|
||||
const idVec3 orig = parms->renderView.vieworg;
|
||||
float fov_x = parms->renderView.fov_x;
|
||||
float fov_y = parms->renderView.fov_y;
|
||||
|
||||
parms->renderView = *surf->space->entityDef->parms.remoteRenderView;
|
||||
parms->renderView.fov_x = fov_x;
|
||||
parms->renderView.fov_y = fov_y;
|
||||
|
||||
idAngles ang = viewaxis.ToAngles();
|
||||
idAngles angleDiff;
|
||||
|
||||
idMat3 surfViewAxis;
|
||||
|
||||
// Difference in view axis
|
||||
idPlane originalPlane, plane;
|
||||
R_PlaneForSurface( surf->frontEndGeo, originalPlane );
|
||||
R_LocalPlaneToGlobal( surf->space->modelMatrix, originalPlane, plane );
|
||||
|
||||
orientation_t surface;
|
||||
surface.origin = plane.Normal() * -plane[3];
|
||||
surface.axis[0] = plane.Normal();
|
||||
surface.axis[0].NormalVectors( surface.axis[1], surface.axis[2] );
|
||||
surface.axis[2] = -surface.axis[2];
|
||||
|
||||
surfViewAxis = surface.axis;
|
||||
idAngles surfAng = surfViewAxis.ToAngles();
|
||||
angleDiff = surfAng - ang;
|
||||
|
||||
idAngles origAngle = parms->renderView.viewaxis.ToAngles();
|
||||
origAngle = origAngle - angleDiff;
|
||||
origAngle.yaw -= 180;
|
||||
origAngle.Normalize180();
|
||||
|
||||
parms->renderView.viewaxis = origAngle.ToMat3();
|
||||
|
||||
// Direction vector in camera space.
|
||||
const idMat3 inverseSurfView = surfViewAxis.Transpose();
|
||||
idVec3 dirToPortal = ( surf->space->entityDef->parms.origin - orig ) * inverseSurfView;
|
||||
dirToPortal.z = -dirToPortal.z;
|
||||
parms->renderView.vieworg += dirToPortal * remoteViewAxis;
|
||||
|
||||
// Set up oblique view clipping plane
|
||||
parms->numClipPlanes = 1;
|
||||
parms->clipPlanes[0] = remoteViewAxis[0];
|
||||
parms->clipPlanes[0][3] = -( surf->space->entityDef->parms.remoteRenderView->vieworg * parms->clipPlanes[0].Normal() );
|
||||
float dist = parms->clipPlanes[0].Dist();
|
||||
float viewdist = parms->renderView.vieworg * parms->clipPlanes[0].Normal();
|
||||
float fDist = -dist + viewdist;
|
||||
// fudge avoids depth precision artifacts when performing oblique projection
|
||||
static const float fudge = 2.f;
|
||||
if( fDist > fudge || fDist < -fudge )
|
||||
{
|
||||
if( fDist < 0.f )
|
||||
{
|
||||
fDist += fudge;
|
||||
}
|
||||
else
|
||||
{
|
||||
fDist -= fudge;
|
||||
}
|
||||
}
|
||||
parms->clipPlanes[0][3] = fDist;
|
||||
parms->isObliqueProjection = true;
|
||||
|
||||
parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons
|
||||
parms->initialViewAreaOrigin = parms->renderView.vieworg;
|
||||
parms->isSubview = true;
|
||||
parms->isMirror = false;
|
||||
|
||||
return parms;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
R_XrayViewBySurface
|
||||
|
@ -519,29 +612,54 @@ bool R_GenerateSurfaceSubview( const drawSurf_t* drawSurf )
|
|||
case DI_XRAY_RENDER:
|
||||
R_XrayRender( drawSurf, const_cast<textureStage_t*>( &stage->texture ), scissor );
|
||||
break;
|
||||
|
||||
case DI_GUI_RENDER:
|
||||
case DI_RENDER_TARGET:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// issue a new view command
|
||||
parms = R_MirrorViewBySurface( drawSurf );
|
||||
if( parms == NULL )
|
||||
if( shader->IsMirrorSubView() )
|
||||
{
|
||||
return false;
|
||||
// issue a new view command
|
||||
parms = R_MirrorViewBySurface( drawSurf );
|
||||
if( parms == NULL )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
parms->scissor = scissor;
|
||||
parms->superView = tr.viewDef;
|
||||
parms->subviewSurface = drawSurf;
|
||||
|
||||
// triangle culling order changes with mirroring
|
||||
parms->isMirror = ( ( ( int )parms->isMirror ^ ( int )tr.viewDef->isMirror ) != 0 );
|
||||
|
||||
// generate render commands for it
|
||||
R_RenderView( parms );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if( shader->IsPortalSubView() )
|
||||
{
|
||||
parms = R_PortalViewBySurface( drawSurf );
|
||||
if( parms == nullptr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
parms->scissor = scissor;
|
||||
parms->superView = tr.viewDef;
|
||||
parms->subviewSurface = drawSurf;
|
||||
|
||||
R_RenderView( parms );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
parms->scissor = scissor;
|
||||
parms->superView = tr.viewDef;
|
||||
parms->subviewSurface = drawSurf;
|
||||
|
||||
// triangle culling order changes with mirroring
|
||||
parms->isMirror = ( ( ( int )parms->isMirror ^ ( int )tr.viewDef->isMirror ) != 0 );
|
||||
|
||||
// generate render commands for it
|
||||
R_RenderView( parms );
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
REM 7z a RBDOOM-3-BFG-1.3.1.1-lite-win64-20220109-git-xxxxxxx.7z -r base/env/ base/maps/*.lightgrid base/maps/*_extra_ents.map -x!generated
|
||||
set filename=RBDOOM-3-BFG-1.4.0.7-lite-win64-20220302-git-xxxxxxx.7z
|
||||
set filename=RBDOOM-3-BFG-1.4.0.8-lite-win64-20220305-git-xxxxxxx.7z
|
||||
7z a %filename% README.md RELEASE-NOTES.md base/devtools.cfg base/modelviewer.cfg base/extract_resources.cfg base/convert_maps_to_valve220.cfg base/def/*.def base/materials/*.mtr base/textures/common base/textures/editor base/maps/zoomaps -x!generated -xr!autosave -xr!*.xcf -xr!*.blend
|
||||
7z a %filename% README.md RELEASE-NOTES.md base/_tb/fgd/*.fgd
|
||||
7z a %filename% README.md RELEASE-NOTES.md tools/trenchbroom -xr!TrenchBroom-nomanual* -xr!TrenchBroom.pdb
|
||||
|
|
Loading…
Reference in a new issue