mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 02:32:18 +00:00
Removed unimplemented renderer passes
This commit is contained in:
parent
f408fcad38
commit
80ca705d8d
8 changed files with 2 additions and 2573 deletions
|
@ -57,9 +57,8 @@ idCVar r_syncEveryFrame( "r_syncEveryFrame", "1", CVAR_BOOL, "Don't let the GPU
|
|||
|
||||
idCVar r_uploadBufferSizeMB( "r_uploadBufferSizeMB", "64", CVAR_INTEGER | CVAR_INIT, "Size of gpu upload buffer (Vulkan only)" );
|
||||
|
||||
// SRS - What is GLimp_SwapBuffers() used for? Disable for now
|
||||
//void GLimp_SwapBuffers();
|
||||
void RB_SetMVP( const idRenderMatrix& mvp );
|
||||
|
||||
constexpr std::size_t MAX_IMAGE_PARMS = 16;
|
||||
|
||||
class NvrhiContext
|
||||
{
|
||||
|
|
|
@ -1,855 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include <precompiled.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "framework/Common_local.h"
|
||||
#include "renderer/RenderCommon.h"
|
||||
#include "renderer/Framebuffer.h"
|
||||
|
||||
#include "FowardShadingPass.h"
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
same as D3DXMatrixOrthoOffCenterRH
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/bb205348(VS.85).aspx
|
||||
*/
|
||||
static void MatrixOrthogonalProjectionRH( float m[16], float left, float right, float bottom, float top, float zNear, float zFar )
|
||||
{
|
||||
m[0] = 2 / ( right - left );
|
||||
m[4] = 0;
|
||||
m[8] = 0;
|
||||
m[12] = ( left + right ) / ( left - right );
|
||||
m[1] = 0;
|
||||
m[5] = 2 / ( top - bottom );
|
||||
m[9] = 0;
|
||||
m[13] = ( top + bottom ) / ( bottom - top );
|
||||
m[2] = 0;
|
||||
m[6] = 0;
|
||||
m[10] = 1 / ( zNear - zFar );
|
||||
m[14] = zNear / ( zNear - zFar );
|
||||
m[3] = 0;
|
||||
m[7] = 0;
|
||||
m[11] = 0;
|
||||
m[15] = 1;
|
||||
}
|
||||
|
||||
void ForwardShadingPass::Init( nvrhi::DeviceHandle deviceHandle )
|
||||
{
|
||||
device = deviceHandle;
|
||||
|
||||
auto texturedBindingLayoutDesc = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
|
||||
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) );
|
||||
|
||||
auto geometrySkinnedBindingLayoutDesc = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
|
||||
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 1 ) );
|
||||
|
||||
auto geometryBindingLayoutDesc = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) );
|
||||
|
||||
texturedBindingLayout = device->createBindingLayout( texturedBindingLayoutDesc );
|
||||
geometryBindingLayout = device->createBindingLayout( geometryBindingLayoutDesc );
|
||||
pipelineDesc.bindingLayouts = { geometryBindingLayout };
|
||||
|
||||
geometryBindingSetDesc = nvrhi::BindingSetDesc()
|
||||
.addItem( nvrhi::BindingSetItem::ConstantBuffer( 0, renderProgManager.ConstantBuffer() ) );
|
||||
|
||||
samplerCache.Init( deviceHandle.Get() );
|
||||
|
||||
pipeline = nullptr;
|
||||
}
|
||||
|
||||
void ForwardShadingPass::DrawInteractions( nvrhi::ICommandList* commandList, const viewDef_t* viewDef )
|
||||
{
|
||||
if( r_skipInteractions.GetBool() || viewDef->viewLights == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
commandList->beginMarker( "DrawInteractions" );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
|
||||
const bool useLightDepthBounds = r_useLightDepthBounds.GetBool() && !r_useShadowMapping.GetBool();
|
||||
|
||||
Framebuffer* previousFramebuffer = currentFramebuffer;
|
||||
|
||||
//
|
||||
// for each light, perform shadowing and adding
|
||||
//
|
||||
for( const viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next )
|
||||
{
|
||||
// do fogging later
|
||||
if( vLight->lightShader->IsFogLight() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( vLight->lightShader->IsBlendLight() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( vLight->localInteractions == NULL && vLight->globalInteractions == NULL && vLight->translucentInteractions == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const idMaterial* lightShader = vLight->lightShader;
|
||||
commandList->beginMarker( lightShader->GetName() );
|
||||
|
||||
// set the depth bounds for the whole light
|
||||
if( useLightDepthBounds )
|
||||
{
|
||||
GL_DepthBoundsTest( vLight->scissorRect.zmin, vLight->scissorRect.zmax );
|
||||
}
|
||||
|
||||
// RB: shadow mapping
|
||||
if( r_useShadowMapping.GetBool() )
|
||||
{
|
||||
int side, sideStop;
|
||||
|
||||
if( vLight->parallel )
|
||||
{
|
||||
side = 0;
|
||||
sideStop = r_shadowMapSplits.GetInteger() + 1;
|
||||
}
|
||||
else if( vLight->pointLight )
|
||||
{
|
||||
if( r_shadowMapSingleSide.GetInteger() != -1 )
|
||||
{
|
||||
side = r_shadowMapSingleSide.GetInteger();
|
||||
sideStop = side + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
side = 0;
|
||||
sideStop = 6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
side = -1;
|
||||
sideStop = 0;
|
||||
}
|
||||
|
||||
for( ; side < sideStop; side++ )
|
||||
{
|
||||
ShadowMapPass( commandList, vLight->globalShadows, vLight, side );
|
||||
}
|
||||
|
||||
// go back to main render target
|
||||
if( previousFramebuffer != NULL )
|
||||
{
|
||||
previousFramebuffer->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
Framebuffer::Unbind();
|
||||
}
|
||||
|
||||
renderProgManager.Unbind();
|
||||
|
||||
GL_State( GLS_DEFAULT, false );
|
||||
}
|
||||
// RB end
|
||||
|
||||
commandList->endMarker();
|
||||
}
|
||||
|
||||
// disable stencil shadow test
|
||||
GL_State( GLS_DEFAULT );
|
||||
|
||||
// unbind texture units
|
||||
GL_SelectTexture( 0 );
|
||||
|
||||
// reset depth bounds
|
||||
if( useLightDepthBounds )
|
||||
{
|
||||
GL_DepthBoundsTest( 0.0f, 0.0f );
|
||||
}
|
||||
|
||||
commandList->endMarker();
|
||||
}
|
||||
|
||||
void ForwardShadingPass::ShadowMapPass( nvrhi::ICommandList* commandList, const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side )
|
||||
{
|
||||
if( r_skipShadows.GetBool() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( drawSurfs == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( viewDef->renderView.rdflags & RDF_NOSHADOWS )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderProgManager.BindShader_Depth();
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
|
||||
uint64 glState = 0;
|
||||
|
||||
// the actual stencil func will be set in the draw code, but we need to make sure it isn't
|
||||
// disabled here, and that the value will get reset for the interactions without looking
|
||||
// like a no-change-required
|
||||
GL_State( glState | GLS_POLYGON_OFFSET );
|
||||
|
||||
switch( r_shadowMapOccluderFacing.GetInteger() )
|
||||
{
|
||||
case 0:
|
||||
GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_FRONTSIDED );
|
||||
GL_PolygonOffset( r_shadowMapPolygonFactor.GetFloat(), r_shadowMapPolygonOffset.GetFloat() );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_BACKSIDED );
|
||||
GL_PolygonOffset( -r_shadowMapPolygonFactor.GetFloat(), -r_shadowMapPolygonOffset.GetFloat() );
|
||||
break;
|
||||
|
||||
default:
|
||||
GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_TWOSIDED );
|
||||
GL_PolygonOffset( r_shadowMapPolygonFactor.GetFloat(), r_shadowMapPolygonOffset.GetFloat() );
|
||||
break;
|
||||
}
|
||||
|
||||
idRenderMatrix lightProjectionRenderMatrix;
|
||||
idRenderMatrix lightViewRenderMatrix;
|
||||
|
||||
|
||||
if( vLight->parallel && side >= 0 )
|
||||
{
|
||||
assert( side >= 0 && side < 6 );
|
||||
|
||||
// original light direction is from surface to light origin
|
||||
idVec3 lightDir = -vLight->lightCenter;
|
||||
if( lightDir.Normalize() == 0.0f )
|
||||
{
|
||||
lightDir[2] = -1.0f;
|
||||
}
|
||||
|
||||
idMat3 rotation = lightDir.ToMat3();
|
||||
//idAngles angles = lightDir.ToAngles();
|
||||
//idMat3 rotation = angles.ToMat3();
|
||||
|
||||
const idVec3 viewDir = viewDef->renderView.viewaxis[0];
|
||||
const idVec3 viewPos = viewDef->renderView.vieworg;
|
||||
|
||||
#if 1
|
||||
idRenderMatrix::CreateViewMatrix( viewDef->renderView.vieworg, rotation, lightViewRenderMatrix );
|
||||
#else
|
||||
float lightViewMatrix[16];
|
||||
MatrixLookAtRH( lightViewMatrix, viewPos, lightDir, viewDir );
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )lightViewMatrix, lightViewRenderMatrix );
|
||||
#endif
|
||||
|
||||
idBounds lightBounds;
|
||||
lightBounds.Clear();
|
||||
|
||||
ALIGNTYPE16 frustumCorners_t corners;
|
||||
idRenderMatrix::GetFrustumCorners( corners, vLight->inverseBaseLightProject, bounds_zeroOneCube );
|
||||
|
||||
idVec4 point, transf;
|
||||
for( int j = 0; j < 8; j++ )
|
||||
{
|
||||
point[0] = corners.x[j];
|
||||
point[1] = corners.y[j];
|
||||
point[2] = corners.z[j];
|
||||
point[3] = 1;
|
||||
|
||||
lightViewRenderMatrix.TransformPoint( point, transf );
|
||||
transf[0] /= transf[3];
|
||||
transf[1] /= transf[3];
|
||||
transf[2] /= transf[3];
|
||||
|
||||
lightBounds.AddPoint( transf.ToVec3() );
|
||||
}
|
||||
|
||||
float lightProjectionMatrix[16];
|
||||
MatrixOrthogonalProjectionRH( lightProjectionMatrix, lightBounds[0][0], lightBounds[1][0], lightBounds[0][1], lightBounds[1][1], -lightBounds[1][2], -lightBounds[0][2] );
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )lightProjectionMatrix, lightProjectionRenderMatrix );
|
||||
|
||||
|
||||
// 'frustumMVP' goes from global space -> camera local space -> camera projective space
|
||||
// invert the MVP projection so we can deform zero-to-one cubes into the frustum pyramid shape and calculate global bounds
|
||||
|
||||
idRenderMatrix splitFrustumInverse;
|
||||
if( !idRenderMatrix::Inverse( viewDef->frustumMVPs[FRUSTUM_CASCADE1 + side], splitFrustumInverse ) )
|
||||
{
|
||||
idLib::Warning( "splitFrustumMVP invert failed" );
|
||||
}
|
||||
|
||||
// splitFrustumCorners in global space
|
||||
ALIGNTYPE16 frustumCorners_t splitFrustumCorners;
|
||||
idRenderMatrix::GetFrustumCorners( splitFrustumCorners, splitFrustumInverse, bounds_unitCube );
|
||||
|
||||
idRenderMatrix lightViewProjectionRenderMatrix;
|
||||
idRenderMatrix::Multiply( lightProjectionRenderMatrix, lightViewRenderMatrix, lightViewProjectionRenderMatrix );
|
||||
|
||||
// find the bounding box of the current split in the light's clip space
|
||||
idBounds cropBounds;
|
||||
cropBounds.Clear();
|
||||
for( int j = 0; j < 8; j++ )
|
||||
{
|
||||
point[0] = splitFrustumCorners.x[j];
|
||||
point[1] = splitFrustumCorners.y[j];
|
||||
point[2] = splitFrustumCorners.z[j];
|
||||
point[3] = 1;
|
||||
|
||||
lightViewRenderMatrix.TransformPoint( point, transf );
|
||||
transf[0] /= transf[3];
|
||||
transf[1] /= transf[3];
|
||||
transf[2] /= transf[3];
|
||||
|
||||
cropBounds.AddPoint( transf.ToVec3() );
|
||||
}
|
||||
|
||||
// don't let the frustum AABB be bigger than the light AABB
|
||||
if( cropBounds[0][0] < lightBounds[0][0] )
|
||||
{
|
||||
cropBounds[0][0] = lightBounds[0][0];
|
||||
}
|
||||
|
||||
if( cropBounds[0][1] < lightBounds[0][1] )
|
||||
{
|
||||
cropBounds[0][1] = lightBounds[0][1];
|
||||
}
|
||||
|
||||
if( cropBounds[1][0] > lightBounds[1][0] )
|
||||
{
|
||||
cropBounds[1][0] = lightBounds[1][0];
|
||||
}
|
||||
|
||||
if( cropBounds[1][1] > lightBounds[1][1] )
|
||||
{
|
||||
cropBounds[1][1] = lightBounds[1][1];
|
||||
}
|
||||
|
||||
cropBounds[0][2] = lightBounds[0][2];
|
||||
cropBounds[1][2] = lightBounds[1][2];
|
||||
|
||||
//float cropMatrix[16];
|
||||
//MatrixCrop(cropMatrix, cropBounds[0], cropBounds[1]);
|
||||
|
||||
//idRenderMatrix cropRenderMatrix;
|
||||
//idRenderMatrix::Transpose( *( idRenderMatrix* )cropMatrix, cropRenderMatrix );
|
||||
|
||||
//idRenderMatrix tmp = lightProjectionRenderMatrix;
|
||||
//idRenderMatrix::Multiply( cropRenderMatrix, tmp, lightProjectionRenderMatrix );
|
||||
|
||||
MatrixOrthogonalProjectionRH( lightProjectionMatrix, cropBounds[0][0], cropBounds[1][0], cropBounds[0][1], cropBounds[1][1], -cropBounds[1][2], -cropBounds[0][2] );
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )lightProjectionMatrix, lightProjectionRenderMatrix );
|
||||
|
||||
shadowV[side] = lightViewRenderMatrix;
|
||||
shadowP[side] = lightProjectionRenderMatrix;
|
||||
}
|
||||
else if( vLight->pointLight && side >= 0 )
|
||||
{
|
||||
assert( side >= 0 && side < 6 );
|
||||
|
||||
// FIXME OPTIMIZE no memset
|
||||
|
||||
float viewMatrix[16];
|
||||
|
||||
idVec3 vec;
|
||||
idVec3 origin = vLight->globalLightOrigin;
|
||||
|
||||
// side of a point light
|
||||
memset( viewMatrix, 0, sizeof( viewMatrix ) );
|
||||
switch( side )
|
||||
{
|
||||
case 0:
|
||||
viewMatrix[0] = 1;
|
||||
viewMatrix[9] = 1;
|
||||
viewMatrix[6] = -1;
|
||||
break;
|
||||
case 1:
|
||||
viewMatrix[0] = -1;
|
||||
viewMatrix[9] = -1;
|
||||
viewMatrix[6] = -1;
|
||||
break;
|
||||
case 2:
|
||||
viewMatrix[4] = 1;
|
||||
viewMatrix[1] = -1;
|
||||
viewMatrix[10] = 1;
|
||||
break;
|
||||
case 3:
|
||||
viewMatrix[4] = -1;
|
||||
viewMatrix[1] = -1;
|
||||
viewMatrix[10] = -1;
|
||||
break;
|
||||
case 4:
|
||||
viewMatrix[8] = 1;
|
||||
viewMatrix[1] = -1;
|
||||
viewMatrix[6] = -1;
|
||||
break;
|
||||
case 5:
|
||||
viewMatrix[8] = -1;
|
||||
viewMatrix[1] = 1;
|
||||
viewMatrix[6] = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
viewMatrix[12] = -origin[0] * viewMatrix[0] + -origin[1] * viewMatrix[4] + -origin[2] * viewMatrix[8];
|
||||
viewMatrix[13] = -origin[0] * viewMatrix[1] + -origin[1] * viewMatrix[5] + -origin[2] * viewMatrix[9];
|
||||
viewMatrix[14] = -origin[0] * viewMatrix[2] + -origin[1] * viewMatrix[6] + -origin[2] * viewMatrix[10];
|
||||
|
||||
viewMatrix[3] = 0;
|
||||
viewMatrix[7] = 0;
|
||||
viewMatrix[11] = 0;
|
||||
viewMatrix[15] = 1;
|
||||
|
||||
// from world space to light origin, looking down the X axis
|
||||
float unflippedLightViewMatrix[16];
|
||||
|
||||
// from world space to OpenGL view space, looking down the negative Z axis
|
||||
float lightViewMatrix[16];
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
memcpy( unflippedLightViewMatrix, viewMatrix, sizeof( unflippedLightViewMatrix ) );
|
||||
R_MatrixMultiply( viewMatrix, s_flipMatrix, lightViewMatrix );
|
||||
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )lightViewMatrix, lightViewRenderMatrix );
|
||||
|
||||
// set up 90 degree projection matrix
|
||||
const float zNear = 4;
|
||||
const float fov = r_shadowMapFrustumFOV.GetFloat();
|
||||
|
||||
float ymax = zNear * tan( fov * idMath::PI / 360.0f );
|
||||
float ymin = -ymax;
|
||||
|
||||
float xmax = zNear * tan( fov * idMath::PI / 360.0f );
|
||||
float xmin = -xmax;
|
||||
|
||||
const float width = xmax - xmin;
|
||||
const float height = ymax - ymin;
|
||||
|
||||
// from OpenGL view space to OpenGL NDC ( -1 : 1 in XYZ )
|
||||
float lightProjectionMatrix[16];
|
||||
|
||||
lightProjectionMatrix[0 * 4 + 0] = 2.0f * zNear / width;
|
||||
lightProjectionMatrix[1 * 4 + 0] = 0.0f;
|
||||
lightProjectionMatrix[2 * 4 + 0] = ( xmax + xmin ) / width; // normally 0
|
||||
lightProjectionMatrix[3 * 4 + 0] = 0.0f;
|
||||
|
||||
lightProjectionMatrix[0 * 4 + 1] = 0.0f;
|
||||
lightProjectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
|
||||
lightProjectionMatrix[2 * 4 + 1] = ( ymax + ymin ) / height; // normally 0
|
||||
lightProjectionMatrix[3 * 4 + 1] = 0.0f;
|
||||
|
||||
// this is the far-plane-at-infinity formulation, and
|
||||
// crunches the Z range slightly so w=0 vertexes do not
|
||||
// rasterize right at the wraparound point
|
||||
lightProjectionMatrix[0 * 4 + 2] = 0.0f;
|
||||
lightProjectionMatrix[1 * 4 + 2] = 0.0f;
|
||||
lightProjectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues
|
||||
lightProjectionMatrix[3 * 4 + 2] = -2.0f * zNear;
|
||||
|
||||
lightProjectionMatrix[0 * 4 + 3] = 0.0f;
|
||||
lightProjectionMatrix[1 * 4 + 3] = 0.0f;
|
||||
lightProjectionMatrix[2 * 4 + 3] = -1.0f;
|
||||
lightProjectionMatrix[3 * 4 + 3] = 0.0f;
|
||||
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )lightProjectionMatrix, lightProjectionRenderMatrix );
|
||||
|
||||
shadowV[side] = lightViewRenderMatrix;
|
||||
shadowP[side] = lightProjectionRenderMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightViewRenderMatrix.Identity();
|
||||
lightProjectionRenderMatrix = vLight->baseLightProject;
|
||||
|
||||
shadowV[0] = lightViewRenderMatrix;
|
||||
shadowP[0] = lightProjectionRenderMatrix;
|
||||
}
|
||||
|
||||
GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] );
|
||||
|
||||
//glClear( GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
// process the chain of shadows with the current rendering state
|
||||
currentSpace = NULL;
|
||||
|
||||
nvrhi::GraphicsState graphicsState;
|
||||
graphicsState.framebuffer = currentFramebuffer->GetApiObject();
|
||||
nvrhi::Viewport viewport;
|
||||
viewport.minX = currentViewport.x1;
|
||||
viewport.minY = currentViewport.y1;
|
||||
viewport.maxX = currentViewport.x2;
|
||||
viewport.maxY = currentViewport.y2;
|
||||
viewport.minZ = currentViewport.zmin;
|
||||
viewport.maxZ = currentViewport.zmax;
|
||||
graphicsState.viewport.addViewportAndScissorRect( viewport );
|
||||
graphicsState.viewport.addScissorRect( nvrhi::Rect( currentScissor.x1, currentScissor.y1, currentScissor.x2, currentScissor.y2 ) );
|
||||
renderProgManager.BindShader_Depth();
|
||||
auto currentBindingSet = bindingCache.GetOrCreateBindingSet( geometryBindingSetDesc, renderProgManager.BindingLayout() );
|
||||
graphicsState.bindings = { currentBindingSet };
|
||||
|
||||
bool stateValid = false;
|
||||
|
||||
nvrhi::DrawArguments currentDraw;
|
||||
currentDraw.instanceCount = 0;
|
||||
|
||||
shaderStage_t lastStage;
|
||||
bool changedStage = false;
|
||||
|
||||
int lastShader = -1;
|
||||
|
||||
for( const drawSurf_t* drawSurf = drawSurfs; drawSurf != NULL; drawSurf = drawSurf->nextOnLight )
|
||||
{
|
||||
stateValid = false;
|
||||
|
||||
// Make sure the shadow occluder geometry is done
|
||||
if( drawSurf->shadowVolumeState != SHADOWVOLUME_DONE )
|
||||
{
|
||||
assert( drawSurf->shadowVolumeState == SHADOWVOLUME_UNFINISHED || drawSurf->shadowVolumeState == SHADOWVOLUME_DONE );
|
||||
|
||||
uint64 start = Sys_Microseconds();
|
||||
while( drawSurf->shadowVolumeState == SHADOWVOLUME_UNFINISHED )
|
||||
{
|
||||
Sys_Yield();
|
||||
}
|
||||
uint64 end = Sys_Microseconds();
|
||||
|
||||
// TODO(Stephen): will probably need to change this if we're going to make this multi-threaded.
|
||||
tr.backend.pc.cpuShadowMicroSec += end - start;
|
||||
}
|
||||
|
||||
if( drawSurf->numIndexes == 0 )
|
||||
{
|
||||
continue; // a job may have created an empty shadow geometry
|
||||
}
|
||||
|
||||
if( drawSurf->space != currentSpace )
|
||||
{
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )drawSurf->space->modelMatrix, modelRenderMatrix );
|
||||
|
||||
idRenderMatrix modelToLightRenderMatrix;
|
||||
idRenderMatrix::Multiply( lightViewRenderMatrix, modelRenderMatrix, modelToLightRenderMatrix );
|
||||
|
||||
idRenderMatrix clipMVP;
|
||||
idRenderMatrix::Multiply( lightProjectionRenderMatrix, modelToLightRenderMatrix, clipMVP );
|
||||
|
||||
if( vLight->parallel )
|
||||
{
|
||||
idRenderMatrix MVP;
|
||||
idRenderMatrix::Multiply( renderMatrix_clipSpaceToWindowSpace, clipMVP, MVP );
|
||||
|
||||
RB_SetMVP( clipMVP );
|
||||
}
|
||||
else if( side < 0 )
|
||||
{
|
||||
// from OpenGL view space to OpenGL NDC ( -1 : 1 in XYZ )
|
||||
idRenderMatrix MVP;
|
||||
idRenderMatrix::Multiply( renderMatrix_windowSpaceToClipSpace, clipMVP, MVP );
|
||||
|
||||
RB_SetMVP( MVP );
|
||||
}
|
||||
else
|
||||
{
|
||||
RB_SetMVP( clipMVP );
|
||||
}
|
||||
|
||||
// set the local light position to allow the vertex program to project the shadow volume end cap to infinity
|
||||
/*
|
||||
idVec4 localLight( 0.0f );
|
||||
R_GlobalPointToLocal( drawSurf->space->modelMatrix, vLight->globalLightOrigin, localLight.ToVec3() );
|
||||
SetVertexParm( RENDERPARM_LOCALLIGHTORIGIN, localLight.ToFloatPtr() );
|
||||
*/
|
||||
|
||||
currentSpace = drawSurf->space;
|
||||
}
|
||||
|
||||
bool didDraw = false;
|
||||
|
||||
const idMaterial* shader = drawSurf->material;
|
||||
|
||||
// get the expressions for conditionals / color / texcoords
|
||||
const float* regs = drawSurf->shaderRegisters;
|
||||
idVec4 color( 0, 0, 0, 1 );
|
||||
|
||||
uint64 surfGLState = 0;
|
||||
|
||||
// set polygon offset if necessary
|
||||
if( shader && shader->TestMaterialFlag( MF_POLYGONOFFSET ) )
|
||||
{
|
||||
surfGLState |= GLS_POLYGON_OFFSET;
|
||||
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
|
||||
}
|
||||
|
||||
if( shader && shader->Coverage() == MC_PERFORATED )
|
||||
{
|
||||
// perforated surfaces may have multiple alpha tested stages
|
||||
for( int stage = 0; stage < shader->GetNumStages(); stage++ )
|
||||
{
|
||||
const shaderStage_t* pStage = shader->GetStage( stage );
|
||||
|
||||
if( !pStage->hasAlphaTest )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check the stage enable condition
|
||||
if( regs[pStage->conditionRegister] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we at least tried to draw an alpha tested stage,
|
||||
// we won't draw the opaque surface
|
||||
didDraw = true;
|
||||
|
||||
// set the alpha modulate
|
||||
color[3] = regs[pStage->color.registers[3]];
|
||||
|
||||
// skip the entire stage if alpha would be black
|
||||
if( color[3] <= 0.0f )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64 stageGLState = surfGLState;
|
||||
|
||||
// set privatePolygonOffset if necessary
|
||||
if( pStage->privatePolygonOffset )
|
||||
{
|
||||
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset );
|
||||
stageGLState |= GLS_POLYGON_OFFSET;
|
||||
}
|
||||
|
||||
GL_Color( color );
|
||||
|
||||
GL_State( stageGLState );
|
||||
idVec4 alphaTestValue( regs[pStage->alphaTestRegister] );
|
||||
renderProgManager.SetRenderParm( RENDERPARM_ALPHA_TEST, alphaTestValue.ToFloatPtr() );
|
||||
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_TextureVertexColorSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_TextureVertexColor();
|
||||
}
|
||||
|
||||
RB_SetVertexColorParms( SVC_IGNORE );
|
||||
|
||||
bool imageChanged = ( imageParms[0] != pStage->texture.image );
|
||||
|
||||
// bind the texture
|
||||
GL_SelectTexture( 0 );
|
||||
GL_BindTexture( pStage->texture.image );
|
||||
|
||||
// set texture matrix and texGens
|
||||
PrepareStageTexturing( pStage, drawSurf );
|
||||
|
||||
if( imageChanged )
|
||||
{
|
||||
auto bindingSetDesc = nvrhi::BindingSetDesc()
|
||||
.addItem( nvrhi::BindingSetItem::ConstantBuffer( 0, renderProgManager.ConstantBuffer() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )imageParms[0]->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 0, ( nvrhi::ISampler* )imageParms[0]->GetSampler( samplerCache ) ) );
|
||||
|
||||
auto currentBindingSet = bindingCache.GetOrCreateBindingSet( bindingSetDesc, renderProgManager.BindingLayout() );
|
||||
|
||||
graphicsState.bindings = { currentBindingSet };
|
||||
|
||||
stateValid = false;
|
||||
}
|
||||
|
||||
// must render with less-equal for Z-Cull to work properly
|
||||
assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS );
|
||||
|
||||
SetupInputBuffers( drawSurf, graphicsState );
|
||||
|
||||
renderProgManager.CommitConstantBuffer( commandList );
|
||||
|
||||
if( !stateValid )
|
||||
{
|
||||
commandList->setGraphicsState( graphicsState );
|
||||
stateValid = true;
|
||||
}
|
||||
|
||||
if( !pipeline )
|
||||
{
|
||||
pipeline = CreateGraphicsPipeline( currentFramebuffer->GetApiObject() );
|
||||
}
|
||||
|
||||
nvrhi::DrawArguments args;
|
||||
args.vertexCount = drawSurf->numIndexes;
|
||||
args.instanceCount = 1;
|
||||
commandList->drawIndexed( args );
|
||||
|
||||
// clean up
|
||||
FinishStageTexturing( pStage, drawSurf );
|
||||
|
||||
// unset privatePolygonOffset if necessary
|
||||
if( pStage->privatePolygonOffset )
|
||||
{
|
||||
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !didDraw )
|
||||
{
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_DepthSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_Depth();
|
||||
}
|
||||
|
||||
// must render with less-equal for Z-Cull to work properly
|
||||
assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS );
|
||||
|
||||
SetupInputBuffers( drawSurf, graphicsState );
|
||||
|
||||
if( !stateValid )
|
||||
{
|
||||
commandList->setGraphicsState( graphicsState );
|
||||
stateValid = true;
|
||||
}
|
||||
|
||||
if( !pipeline )
|
||||
{
|
||||
pipeline = CreateGraphicsPipeline( currentFramebuffer->GetApiObject() );
|
||||
}
|
||||
|
||||
renderProgManager.CommitConstantBuffer( commandList );
|
||||
|
||||
nvrhi::DrawArguments args;
|
||||
args.vertexCount = drawSurf->numIndexes;
|
||||
args.instanceCount = 1;
|
||||
commandList->drawIndexed( args );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvrhi::GraphicsPipelineHandle ForwardShadingPass::CreateGraphicsPipeline( nvrhi::IFramebuffer* framebuffer )
|
||||
{
|
||||
return device->createGraphicsPipeline( pipelineDesc, framebuffer );
|
||||
}
|
||||
|
||||
void ForwardShadingPass::SetupView( nvrhi::ICommandList* commandList, viewDef_t* viewDef )
|
||||
{
|
||||
}
|
||||
|
||||
bool ForwardShadingPass::SetupMaterial( const idMaterial* material, nvrhi::RasterCullMode cullMode, nvrhi::GraphicsState& state )
|
||||
{
|
||||
if( !pipeline )
|
||||
{
|
||||
pipeline = CreateGraphicsPipeline( state.framebuffer );
|
||||
}
|
||||
|
||||
if( !pipeline )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
assert( pipeline->getFramebufferInfo() == state.framebuffer->getFramebufferInfo() );
|
||||
|
||||
state.pipeline = pipeline;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ForwardShadingPass::SetupInputBuffers( const drawSurf_t* surf, nvrhi::GraphicsState& state )
|
||||
{
|
||||
// Get vertex buffer
|
||||
const vertCacheHandle_t vbHandle = surf->ambientCache;
|
||||
idVertexBuffer* vertexBuffer;
|
||||
if( vertexCache.CacheIsStatic( vbHandle ) )
|
||||
{
|
||||
vertexBuffer = &vertexCache.staticData.vertexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64 frameNum = ( int )( vbHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
|
||||
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
|
||||
{
|
||||
idLib::Warning( "RB_DrawElementsWithCounters, vertexBuffer == NULL" );
|
||||
return;
|
||||
}
|
||||
vertexBuffer = &vertexCache.frameData[vertexCache.drawListNum].vertexBuffer;
|
||||
}
|
||||
const uint vertOffset = ( uint )( vbHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
|
||||
|
||||
// Get index buffer
|
||||
const vertCacheHandle_t ibHandle = surf->indexCache;
|
||||
idIndexBuffer* indexBuffer;
|
||||
if( vertexCache.CacheIsStatic( ibHandle ) )
|
||||
{
|
||||
indexBuffer = &vertexCache.staticData.indexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64 frameNum = ( int )( ibHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
|
||||
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
|
||||
{
|
||||
idLib::Warning( "RB_DrawElementsWithCounters, indexBuffer == NULL" );
|
||||
return;
|
||||
}
|
||||
indexBuffer = &vertexCache.frameData[vertexCache.drawListNum].indexBuffer;
|
||||
}
|
||||
const uint indexOffset = ( uint )( ibHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
|
||||
|
||||
state.indexBuffer = { indexBuffer->GetAPIObject(), nvrhi::Format::R16_UINT, indexOffset };
|
||||
state.vertexBuffers = { { vertexBuffer->GetAPIObject(), 0, vertOffset } };
|
||||
}
|
||||
|
||||
void ForwardShadingPass::SetPushConstants( nvrhi::ICommandList* commandList, nvrhi::GraphicsState& state, nvrhi::DrawArguments& args )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef RENDERER_PASSES_FORWARDSHADINGPASS_H_
|
||||
#define RENDERER_PASSES_FORWARDSHADINGPASS_H_
|
||||
|
||||
#include "GeometryPasses.h"
|
||||
|
||||
#if 0
|
||||
class ForwardShadingPass : IGeometryPass
|
||||
{
|
||||
public:
|
||||
|
||||
ForwardShadingPass() = default;
|
||||
virtual ~ForwardShadingPass() = default;
|
||||
|
||||
void Init( nvrhi::DeviceHandle deviceHandle );
|
||||
|
||||
void DrawInteractions( nvrhi::ICommandList* commandList, const viewDef_t* _viewDef );
|
||||
void ShadowMapPass( nvrhi::ICommandList* commandList, const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side );
|
||||
|
||||
protected:
|
||||
|
||||
nvrhi::DeviceHandle device;
|
||||
nvrhi::BindingLayoutHandle geometryBindingLayout;
|
||||
nvrhi::BindingLayoutHandle texturedBindingLayout;
|
||||
nvrhi::BindingSetDesc geometryBindingSetDesc;
|
||||
SamplerCache samplerCache;
|
||||
|
||||
nvrhi::GraphicsPipelineHandle CreateGraphicsPipeline( nvrhi::IFramebuffer* framebuffer );
|
||||
|
||||
public:
|
||||
|
||||
void SetupView( nvrhi::ICommandList* commandList, viewDef_t* viewDef ) override;
|
||||
bool SetupMaterial( const idMaterial* material, nvrhi::RasterCullMode cullMode, nvrhi::GraphicsState& state ) override;
|
||||
void SetupInputBuffers( const drawSurf_t* drawSurf, nvrhi::GraphicsState& state ) override;
|
||||
void SetPushConstants( nvrhi::ICommandList* commandList, nvrhi::GraphicsState& state, nvrhi::DrawArguments& args ) override;
|
||||
|
||||
private:
|
||||
|
||||
idRenderMatrix shadowV[6]; // shadow depth view matrix
|
||||
idRenderMatrix shadowP[6]; // shadow depth projection matrix
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,678 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include <precompiled.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "renderer/RenderCommon.h"
|
||||
|
||||
#include "GBufferFillPass.h"
|
||||
|
||||
#if 0
|
||||
|
||||
void GBufferFillPass::Init( nvrhi::DeviceHandle deviceHandle )
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
void GBufferFillPass::RenderView( nvrhi::ICommandList* commandList, const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer )
|
||||
{
|
||||
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
|
||||
|
||||
if( numDrawSurfs == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !drawSurfs )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are just doing 2D rendering, no need to fill the depth buffer
|
||||
if( viewDef->viewEntitys == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( viewDef->renderView.rdflags & RDF_NOAMBIENT )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if( !fillGbuffer )
|
||||
{
|
||||
// clear gbuffer
|
||||
GL_Clear( true, false, false, 0, 0.0f, 0.0f, 0.0f, 1.0f, false );
|
||||
}
|
||||
*/
|
||||
|
||||
if( !fillGbuffer && r_useSSAO.GetBool() && r_ssaoDebug.GetBool() )
|
||||
{
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
|
||||
|
||||
// We just want to do a quad pass - so make sure we disable any texgen and
|
||||
// set the texture matrix to the identity so we don't get anomalies from
|
||||
// any stale uniform data being present from a previous draw call
|
||||
const float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
const float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS );
|
||||
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT );
|
||||
|
||||
// disable any texgen
|
||||
const float texGenEnabled[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled );
|
||||
|
||||
currentSpace = NULL;
|
||||
RB_SetMVP( renderMatrix_identity );
|
||||
|
||||
renderProgManager.BindShader_Texture();
|
||||
GL_Color( idVec4( 1 ) );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->ambientOcclusionImage[0]->Bind();
|
||||
|
||||
DrawElementsWithCounters( &tr.backend.unitSquareSurface );
|
||||
|
||||
renderProgManager.Unbind();
|
||||
GL_State( GLS_DEFAULT );
|
||||
|
||||
renderProgManager.SetRenderParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
renderLog.OpenMainBlock( fillGbuffer ? MRB_FILL_GEOMETRY_BUFFER : MRB_AMBIENT_PASS );
|
||||
renderLog.OpenBlock( fillGbuffer ? "Fill_GeometryBuffer" : "Render_AmbientPass", colorBlue );
|
||||
|
||||
if( fillGbuffer )
|
||||
{
|
||||
globalFramebuffers.geometryBufferFBO->Bind();
|
||||
|
||||
GL_Clear( true, false, false, 0, 0.0f, 0.0f, 0.0f, 1.0f, false );
|
||||
}
|
||||
|
||||
commandList->setEnableAutomaticBarriers( false );
|
||||
commandList->setResourceStatesForFramebuffer( currentFrameBuffer->GetApiObject() );
|
||||
commandList->commitBarriers();
|
||||
|
||||
// RB: not needed
|
||||
// GL_StartDepthPass( backEnd.viewDef->scissor );
|
||||
|
||||
// force MVP change on first surface
|
||||
currentSpace = NULL;
|
||||
|
||||
// draw all the subview surfaces, which will already be at the start of the sorted list,
|
||||
// with the general purpose path
|
||||
GL_State( GLS_DEFAULT );
|
||||
|
||||
#define BLEND_NORMALS 1
|
||||
|
||||
// RB: even use additive blending to blend the normals
|
||||
//GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
|
||||
GL_Color( colorWhite );
|
||||
|
||||
idVec4 diffuseColor;
|
||||
idVec4 specularColor;
|
||||
idVec4 ambientColor;
|
||||
|
||||
if( viewDef->renderView.rdflags & RDF_IRRADIANCE )
|
||||
{
|
||||
// RB: don't let artist run into a trap when baking multibounce lightgrids
|
||||
|
||||
// use default value of r_lightScale 3
|
||||
const float lightScale = 3;
|
||||
const idVec4 lightColor = colorWhite * lightScale;
|
||||
|
||||
// apply the world-global overbright and the 2x factor for specular
|
||||
diffuseColor = lightColor;
|
||||
specularColor = lightColor;// * 2.0f;
|
||||
|
||||
// loose 5% with every bounce like in DDGI
|
||||
const float energyConservation = 0.95f;
|
||||
|
||||
//ambientColor.Set( energyConservation, energyConservation, energyConservation, 1.0f );
|
||||
float a = r_forceAmbient.GetFloat();
|
||||
|
||||
ambientColor.Set( a, a, a, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const float lightScale = r_lightScale.GetFloat();
|
||||
const idVec4 lightColor = colorWhite * lightScale;
|
||||
|
||||
// apply the world-global overbright and tune down specular a bit so we have less fresnel overglow
|
||||
diffuseColor = lightColor;
|
||||
specularColor = lightColor;// * 0.5f;
|
||||
|
||||
float ambientBoost = 1.0f;
|
||||
if( !r_usePBR.GetBool() )
|
||||
{
|
||||
ambientBoost += r_useSSAO.GetBool() ? 0.2f : 0.0f;
|
||||
ambientBoost *= 1.1f;
|
||||
}
|
||||
|
||||
ambientColor.x = r_forceAmbient.GetFloat() * ambientBoost;
|
||||
ambientColor.y = r_forceAmbient.GetFloat() * ambientBoost;
|
||||
ambientColor.z = r_forceAmbient.GetFloat() * ambientBoost;
|
||||
ambientColor.w = 1;
|
||||
}
|
||||
|
||||
renderProgManager.SetRenderParm( RENDERPARM_AMBIENT_COLOR, ambientColor.ToFloatPtr() );
|
||||
|
||||
bool useIBL = r_usePBR.GetBool() && !fillGbuffer;
|
||||
|
||||
// setup renderparms assuming we will be drawing trivial surfaces first
|
||||
RB_SetupForFastPathInteractions( diffuseColor, specularColor );
|
||||
|
||||
for( int i = 0; i < numDrawSurfs; i++ )
|
||||
{
|
||||
const drawSurf_t* drawSurf = drawSurfs[i];
|
||||
const idMaterial* surfaceMaterial = drawSurf->material;
|
||||
|
||||
// translucent surfaces don't put anything in the depth buffer and don't
|
||||
// test against it, which makes them fail the mirror clip plane operation
|
||||
if( surfaceMaterial->Coverage() == MC_TRANSLUCENT )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the expressions for conditionals / color / texcoords
|
||||
const float* surfaceRegs = drawSurf->shaderRegisters;
|
||||
|
||||
// if all stages of a material have been conditioned off, don't do anything
|
||||
int stage = 0;
|
||||
for( ; stage < surfaceMaterial->GetNumStages(); stage++ )
|
||||
{
|
||||
const shaderStage_t* pStage = surfaceMaterial->GetStage( stage );
|
||||
// check the stage enable condition
|
||||
if( surfaceRegs[pStage->conditionRegister] != 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( stage == surfaceMaterial->GetNumStages() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//bool isWorldModel = ( drawSurf->space->entityDef->parms.origin == vec3_origin );
|
||||
|
||||
//if( isWorldModel )
|
||||
//{
|
||||
// renderProgManager.BindShader_VertexLighting();
|
||||
//}
|
||||
//else
|
||||
{
|
||||
if( fillGbuffer )
|
||||
{
|
||||
// TODO support PBR textures and store roughness in the alpha channel
|
||||
|
||||
// fill geometry buffer with normal/roughness information
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_SmallGeometryBufferSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_SmallGeometryBuffer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// TODO support PBR textures
|
||||
|
||||
// draw Quake 4 style ambient
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_AmbientLightingSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_AmbientLighting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// change the matrix if needed
|
||||
if( drawSurf->space != currentSpace )
|
||||
{
|
||||
currentSpace = drawSurf->space;
|
||||
|
||||
RB_SetMVP( drawSurf->space->mvp );
|
||||
|
||||
// tranform the view origin into model local space
|
||||
idVec4 localViewOrigin( 1.0f );
|
||||
R_GlobalPointToLocal( drawSurf->space->modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() );
|
||||
SetVertexParm( RENDERPARM_LOCALVIEWORIGIN, localViewOrigin.ToFloatPtr() );
|
||||
|
||||
// RB: if we want to store the normals in world space so we need the model -> world matrix
|
||||
idRenderMatrix modelMatrix;
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )drawSurf->space->modelMatrix, modelMatrix );
|
||||
|
||||
SetVertexParms( RENDERPARM_MODELMATRIX_X, modelMatrix[0], 4 );
|
||||
|
||||
// RB: if we want to store the normals in camera space so we need the model -> camera matrix
|
||||
float modelViewMatrixTranspose[16];
|
||||
R_MatrixTranspose( drawSurf->space->modelViewMatrix, modelViewMatrixTranspose );
|
||||
SetVertexParms( RENDERPARM_MODELVIEWMATRIX_X, modelViewMatrixTranspose, 4 );
|
||||
}
|
||||
|
||||
/*
|
||||
uint64 surfGLState = 0;
|
||||
|
||||
// set polygon offset if necessary
|
||||
if( surfaceMaterial->TestMaterialFlag( MF_POLYGONOFFSET ) )
|
||||
{
|
||||
surfGLState |= GLS_POLYGON_OFFSET;
|
||||
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * surfaceMaterial->GetPolygonOffset() );
|
||||
}
|
||||
|
||||
// subviews will just down-modulate the color buffer
|
||||
idVec4 color;
|
||||
if( surfaceMaterial->GetSort() == SS_SUBVIEW )
|
||||
{
|
||||
surfGLState |= GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHFUNC_LESS;
|
||||
color[0] = 1.0f;
|
||||
color[1] = 1.0f;
|
||||
color[2] = 1.0f;
|
||||
color[3] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// others just draw black
|
||||
#if 0
|
||||
color[0] = 0.0f;
|
||||
color[1] = 0.0f;
|
||||
color[2] = 0.0f;
|
||||
color[3] = 1.0f;
|
||||
#else
|
||||
color = colorWhite;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
drawInteraction_t inter = {};
|
||||
inter.surf = drawSurf;
|
||||
|
||||
inter.diffuseColor[0] = inter.diffuseColor[1] = inter.diffuseColor[2] = inter.diffuseColor[3] = 1;
|
||||
inter.specularColor[0] = inter.specularColor[1] = inter.specularColor[2] = inter.specularColor[3] = 0;
|
||||
|
||||
// check for the fast path
|
||||
if( surfaceMaterial->GetFastPathBumpImage() && !r_skipInteractionFastPath.GetBool() )
|
||||
{
|
||||
renderLog.OpenBlock( surfaceMaterial->GetName(), colorMdGrey );
|
||||
|
||||
inter.bumpImage = surfaceMaterial->GetFastPathBumpImage();
|
||||
inter.specularImage = surfaceMaterial->GetFastPathSpecularImage();
|
||||
inter.diffuseImage = surfaceMaterial->GetFastPathDiffuseImage();
|
||||
|
||||
DrawSingleInteraction( &inter, true, useIBL, false );
|
||||
|
||||
renderLog.CloseBlock();
|
||||
continue;
|
||||
}
|
||||
|
||||
renderLog.OpenBlock( surfaceMaterial->GetName(), colorMdGrey );
|
||||
|
||||
//bool drawSolid = false;
|
||||
|
||||
inter.bumpImage = NULL;
|
||||
inter.specularImage = NULL;
|
||||
inter.diffuseImage = NULL;
|
||||
|
||||
// we may have multiple alpha tested stages
|
||||
// if the only alpha tested stages are condition register omitted,
|
||||
// draw a normal opaque surface
|
||||
bool didDraw = false;
|
||||
|
||||
// perforated surfaces may have multiple alpha tested stages
|
||||
for( stage = 0; stage < surfaceMaterial->GetNumStages(); stage++ )
|
||||
{
|
||||
const shaderStage_t* surfaceStage = surfaceMaterial->GetStage( stage );
|
||||
|
||||
switch( surfaceStage->lighting )
|
||||
{
|
||||
case SL_COVERAGE:
|
||||
{
|
||||
// ignore any coverage stages since they should only be used for the depth fill pass
|
||||
// for diffuse stages that use alpha test.
|
||||
break;
|
||||
}
|
||||
|
||||
case SL_AMBIENT:
|
||||
{
|
||||
// ignore ambient stages while drawing interactions
|
||||
break;
|
||||
}
|
||||
|
||||
case SL_BUMP:
|
||||
{
|
||||
// ignore stage that fails the condition
|
||||
if( !surfaceRegs[surfaceStage->conditionRegister] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// draw any previous interaction
|
||||
if( inter.bumpImage != NULL )
|
||||
{
|
||||
#if BLEND_NORMALS
|
||||
if( inter.vertexColor == SVC_IGNORE )
|
||||
{
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: this is a bit hacky: use additive blending to blend the normals
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
#endif
|
||||
|
||||
DrawSingleInteraction( &inter, false, useIBL, false );
|
||||
}
|
||||
inter.bumpImage = surfaceStage->texture.image;
|
||||
inter.diffuseImage = NULL;
|
||||
inter.specularImage = NULL;
|
||||
SetupInteractionStage( surfaceStage, surfaceRegs, NULL,
|
||||
inter.bumpMatrix, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
case SL_DIFFUSE:
|
||||
{
|
||||
// ignore stage that fails the condition
|
||||
if( !surfaceRegs[surfaceStage->conditionRegister] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// draw any previous interaction
|
||||
if( inter.diffuseImage != NULL )
|
||||
{
|
||||
#if BLEND_NORMALS
|
||||
if( inter.vertexColor == SVC_IGNORE )
|
||||
{
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: this is a bit hacky: use additive blending to blend the normals
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
#endif
|
||||
|
||||
DrawSingleInteraction( &inter, false, useIBL, false );
|
||||
}
|
||||
|
||||
inter.diffuseImage = surfaceStage->texture.image;
|
||||
inter.vertexColor = surfaceStage->vertexColor;
|
||||
SetupInteractionStage( surfaceStage, surfaceRegs, diffuseColor.ToFloatPtr(),
|
||||
inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() );
|
||||
break;
|
||||
}
|
||||
|
||||
case SL_SPECULAR:
|
||||
case SL_RMAO:
|
||||
{
|
||||
// ignore stage that fails the condition
|
||||
if( !surfaceRegs[surfaceStage->conditionRegister] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// draw any previous interaction
|
||||
if( inter.specularImage != NULL )
|
||||
{
|
||||
#if BLEND_NORMALS
|
||||
if( inter.vertexColor == SVC_IGNORE )
|
||||
{
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: this is a bit hacky: use additive blending to blend the normals
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
#endif
|
||||
|
||||
DrawSingleInteraction( &inter, false, useIBL, false );
|
||||
}
|
||||
inter.specularImage = surfaceStage->texture.image;
|
||||
inter.vertexColor = surfaceStage->vertexColor;
|
||||
SetupInteractionStage( surfaceStage, surfaceRegs, specularColor.ToFloatPtr(),
|
||||
inter.specularMatrix, inter.specularColor.ToFloatPtr() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the final interaction
|
||||
#if BLEND_NORMALS
|
||||
if( inter.vertexColor == SVC_IGNORE )
|
||||
{
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: this is a bit hacky: use additive blending to blend the normals
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
#endif
|
||||
|
||||
DrawSingleInteraction( &inter, false, useIBL, false );
|
||||
|
||||
renderLog.CloseBlock();
|
||||
}
|
||||
|
||||
// disable blending
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
|
||||
SetFragmentParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
|
||||
if( fillGbuffer )
|
||||
{
|
||||
// go back to main render target
|
||||
if( previousFramebuffer != NULL )
|
||||
{
|
||||
previousFramebuffer->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
Framebuffer::Unbind();
|
||||
}
|
||||
}
|
||||
|
||||
renderProgManager.Unbind();
|
||||
|
||||
renderLog.CloseBlock();
|
||||
renderLog.CloseMainBlock();
|
||||
}
|
||||
|
||||
nvrhi::GraphicsPipelineHandle GBufferFillPass::CreateGraphicsPipeline( nvrhi::IFramebuffer* framebuffer )
|
||||
{
|
||||
return nvrhi::GraphicsPipelineHandle();
|
||||
}
|
||||
|
||||
void GBufferFillPass::DrawElementsWithCounters( const drawSurf_t* surf )
|
||||
{
|
||||
// Get vertex buffer
|
||||
const vertCacheHandle_t vbHandle = surf->ambientCache;
|
||||
idVertexBuffer* vertexBuffer;
|
||||
if( vertexCache.CacheIsStatic( vbHandle ) )
|
||||
{
|
||||
vertexBuffer = &vertexCache.staticData.vertexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64 frameNum = ( int )( vbHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
|
||||
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
|
||||
{
|
||||
idLib::Warning( "RB_DrawElementsWithCounters, vertexBuffer == NULL" );
|
||||
return;
|
||||
}
|
||||
vertexBuffer = &vertexCache.frameData[vertexCache.drawListNum].vertexBuffer;
|
||||
}
|
||||
const uint vertOffset = ( uint )( vbHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
|
||||
auto currentVertexBuffer = vertexBuffer->GetAPIObject();
|
||||
|
||||
// Get index buffer
|
||||
const vertCacheHandle_t ibHandle = surf->indexCache;
|
||||
idIndexBuffer* indexBuffer;
|
||||
if( vertexCache.CacheIsStatic( ibHandle ) )
|
||||
{
|
||||
indexBuffer = &vertexCache.staticData.indexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64 frameNum = ( int )( ibHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
|
||||
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
|
||||
{
|
||||
idLib::Warning( "RB_DrawElementsWithCounters, indexBuffer == NULL" );
|
||||
return;
|
||||
}
|
||||
indexBuffer = &vertexCache.frameData[vertexCache.drawListNum].indexBuffer;
|
||||
}
|
||||
const uint indexOffset = ( uint )( ibHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
|
||||
|
||||
auto currentIndexBuffer = ( nvrhi::IBuffer* )indexBuffer->GetAPIObject();
|
||||
|
||||
if( currentIndexBuffer != ( nvrhi::IBuffer* )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() )
|
||||
{
|
||||
currentIndexBuffer = indexBuffer->GetAPIObject();
|
||||
}
|
||||
|
||||
if( !pipeline )
|
||||
{
|
||||
nvrhi::GraphicsPipelineDesc psoDesc;
|
||||
psoDesc.VS = vertexShader;
|
||||
psoDesc.PS = pixelShader;
|
||||
psoDesc.inputLayout = inputLayout;
|
||||
psoDesc.bindingLayouts = { currentBindingLayout };
|
||||
psoDesc.primType = nvrhi::PrimitiveType::TriangleList;
|
||||
currentRenderState.rasterState.enableScissor();
|
||||
psoDesc.setRenderState( currentRenderState );
|
||||
|
||||
pipeline = device->createGraphicsPipeline( psoDesc, currentFramebuffer->GetApiObject() );
|
||||
}
|
||||
|
||||
nvrhi::BindingSetDesc bindingSetDesc;
|
||||
|
||||
if( renderProgManager.BindingLayoutType() == BINDING_LAYOUT_DEFAULT )
|
||||
{
|
||||
bindingSetDesc
|
||||
.addItem( nvrhi::BindingSetItem::ConstantBuffer( 0, renderProgManager.ConstantBuffer() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 0, ( nvrhi::ISampler* )GetImageAt( 0 )->GetSampler() ) );
|
||||
}
|
||||
else if( renderProgManager.BindingLayoutType() == BINDING_LAYOUT_GBUFFER )
|
||||
{
|
||||
bindingSetDesc
|
||||
.addItem( nvrhi::BindingSetItem::ConstantBuffer( 0, renderProgManager.ConstantBuffer() ) );
|
||||
}
|
||||
else if( renderProgManager.BindingLayoutType() == BINDING_LAYOUT_LIGHTGRID )
|
||||
{
|
||||
bindingSetDesc
|
||||
.addItem( nvrhi::BindingSetItem::ConstantBuffer( 0, renderProgManager.ConstantBuffer() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 1, ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 2, ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 4, ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 7, ( nvrhi::ITexture* )GetImageAt( 7 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 8, ( nvrhi::ITexture* )GetImageAt( 8 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 9, ( nvrhi::ITexture* )GetImageAt( 9 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Texture_SRV( 10, ( nvrhi::ITexture* )GetImageAt( 10 )->GetTextureID() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 0, ( nvrhi::ISampler* )GetImageAt( 0 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 1, ( nvrhi::ISampler* )GetImageAt( 1 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 2, ( nvrhi::ISampler* )GetImageAt( 2 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 3, ( nvrhi::ISampler* )GetImageAt( 3 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 4, ( nvrhi::ISampler* )GetImageAt( 4 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 7, ( nvrhi::ISampler* )GetImageAt( 7 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 8, ( nvrhi::ISampler* )GetImageAt( 8 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 9, ( nvrhi::ISampler* )GetImageAt( 9 )->GetSampler() ) )
|
||||
.addItem( nvrhi::BindingSetItem::Sampler( 10, ( nvrhi::ISampler* )GetImageAt( 10 )->GetSampler() ) );
|
||||
}
|
||||
|
||||
currentBindingSet = bindingCache.GetOrCreateBindingSet( bindingSetDesc, currentBindingLayout );
|
||||
|
||||
renderProgManager.CommitConstantBuffer( commandList );
|
||||
|
||||
nvrhi::GraphicsState state;
|
||||
state.bindings = { currentBindingSet };
|
||||
state.indexBuffer = { currentIndexBuffer, nvrhi::Format::R16_UINT, indexOffset };
|
||||
state.vertexBuffers = { { currentVertexBuffer, 0, vertOffset } };
|
||||
state.pipeline = currentPipeline;
|
||||
state.framebuffer = currentFrameBuffer->GetApiObject();
|
||||
|
||||
// TODO(Stephen): use currentViewport instead.
|
||||
nvrhi::Viewport viewport;
|
||||
viewport.minX = currentViewport.x1;
|
||||
viewport.minY = currentViewport.y1;
|
||||
viewport.maxX = currentViewport.x2;
|
||||
viewport.maxY = currentViewport.y2;
|
||||
viewport.minZ = currentViewport.zmin;
|
||||
viewport.maxZ = currentViewport.zmax;
|
||||
state.viewport.addViewportAndScissorRect( viewport );
|
||||
state.viewport.addScissorRect( nvrhi::Rect( currentScissor.x1, currentScissor.y1, currentScissor.x2, currentScissor.y2 ) );
|
||||
|
||||
commandList->setGraphicsState( state );
|
||||
|
||||
nvrhi::DrawArguments args;
|
||||
args.vertexCount = surf->numIndexes;
|
||||
commandList->drawIndexed( args );
|
||||
|
||||
// RB: added stats
|
||||
pc.c_drawElements++;
|
||||
pc.c_drawIndexes += surf->numIndexes;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GBufferFillPass::SetupView( nvrhi::ICommandList* commandList, viewDef_t* viewDef )
|
||||
{
|
||||
}
|
||||
|
||||
bool GBufferFillPass::SetupMaterial( const idMaterial* material, nvrhi::RasterCullMode cullMode, nvrhi::GraphicsState& state )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GBufferFillPass::SetupInputBuffers( const drawSurf_t* drawSurf, nvrhi::GraphicsState& state )
|
||||
{
|
||||
}
|
||||
|
||||
void GBufferFillPass::SetPushConstants( nvrhi::ICommandList* commandList, nvrhi::GraphicsState& state, nvrhi::DrawArguments& args )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef RENDERER_PASSES_GBUFFERFILLPASS_H_
|
||||
#define RENDERER_PASSES_GBUFFERFILLPASS_H_
|
||||
|
||||
#include "GeometryPasses.h"
|
||||
|
||||
#if 0
|
||||
|
||||
// "Light" G-Buffer that renders the normals of the geometry
|
||||
class GBufferFillPass : IGeometryPass
|
||||
{
|
||||
public:
|
||||
|
||||
GBufferFillPass() = default;
|
||||
virtual ~GBufferFillPass() = default;
|
||||
|
||||
void Init( nvrhi::DeviceHandle deviceHandle );
|
||||
void RenderView( nvrhi::ICommandList* commandList, const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer );
|
||||
|
||||
protected:
|
||||
|
||||
nvrhi::DeviceHandle device;
|
||||
nvrhi::BindingLayoutHandle geometryBindingLayout;
|
||||
nvrhi::BindingLayoutHandle texturedBindingLayout;
|
||||
nvrhi::BindingSetDesc geometryBindingSetDesc;
|
||||
|
||||
nvrhi::GraphicsPipelineHandle CreateGraphicsPipeline( nvrhi::IFramebuffer* framebuffer );
|
||||
|
||||
void DrawElementsWithCounters( const drawSurf_t* surf );
|
||||
|
||||
public:
|
||||
|
||||
void SetupView( nvrhi::ICommandList* commandList, viewDef_t* viewDef ) override;
|
||||
bool SetupMaterial( const idMaterial* material, nvrhi::RasterCullMode cullMode, nvrhi::GraphicsState& state ) override;
|
||||
void SetupInputBuffers( const drawSurf_t* drawSurf, nvrhi::GraphicsState& state ) override;
|
||||
void SetPushConstants( nvrhi::ICommandList* commandList, nvrhi::GraphicsState& state, nvrhi::DrawArguments& args ) override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,799 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include <precompiled.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "renderer/RenderCommon.h"
|
||||
|
||||
#include "GeometryPasses.h"
|
||||
|
||||
#include "nvrhi/utils.h"
|
||||
|
||||
#if 0
|
||||
static ID_INLINE void SetVertexParm( renderParm_t rp, const float* value )
|
||||
{
|
||||
renderProgManager.SetUniformValue( rp, value );
|
||||
}
|
||||
|
||||
static ID_INLINE void SetVertexParms( renderParm_t rp, const float* value, int num )
|
||||
{
|
||||
for( int i = 0; i < num; i++ )
|
||||
{
|
||||
renderProgManager.SetUniformValue( ( renderParm_t )( rp + i ), value + ( i * 4 ) );
|
||||
}
|
||||
}
|
||||
|
||||
static ID_INLINE void SetFragmentParm( renderParm_t rp, const float* value )
|
||||
{
|
||||
renderProgManager.SetUniformValue( rp, value );
|
||||
}
|
||||
|
||||
static void RB_GetShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture, float matrix[16] )
|
||||
{
|
||||
matrix[0 * 4 + 0] = shaderRegisters[texture->matrix[0][0]];
|
||||
matrix[1 * 4 + 0] = shaderRegisters[texture->matrix[0][1]];
|
||||
matrix[2 * 4 + 0] = 0.0f;
|
||||
matrix[3 * 4 + 0] = shaderRegisters[texture->matrix[0][2]];
|
||||
|
||||
matrix[0 * 4 + 1] = shaderRegisters[texture->matrix[1][0]];
|
||||
matrix[1 * 4 + 1] = shaderRegisters[texture->matrix[1][1]];
|
||||
matrix[2 * 4 + 1] = 0.0f;
|
||||
matrix[3 * 4 + 1] = shaderRegisters[texture->matrix[1][2]];
|
||||
|
||||
// we attempt to keep scrolls from generating incredibly large texture values, but
|
||||
// center rotations and center scales can still generate offsets that need to be > 1
|
||||
if( matrix[3 * 4 + 0] < -40.0f || matrix[12] > 40.0f )
|
||||
{
|
||||
matrix[3 * 4 + 0] -= ( int )matrix[3 * 4 + 0];
|
||||
}
|
||||
if( matrix[13] < -40.0f || matrix[13] > 40.0f )
|
||||
{
|
||||
matrix[13] -= ( int )matrix[13];
|
||||
}
|
||||
|
||||
matrix[0 * 4 + 2] = 0.0f;
|
||||
matrix[1 * 4 + 2] = 0.0f;
|
||||
matrix[2 * 4 + 2] = 1.0f;
|
||||
matrix[3 * 4 + 2] = 0.0f;
|
||||
|
||||
matrix[0 * 4 + 3] = 0.0f;
|
||||
matrix[1 * 4 + 3] = 0.0f;
|
||||
matrix[2 * 4 + 3] = 0.0f;
|
||||
matrix[3 * 4 + 3] = 1.0f;
|
||||
}
|
||||
|
||||
static void RB_LoadShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture )
|
||||
{
|
||||
float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
|
||||
if( texture->hasMatrix )
|
||||
{
|
||||
float matrix[16];
|
||||
RB_GetShaderTextureMatrix( shaderRegisters, texture, matrix );
|
||||
texS[0] = matrix[0 * 4 + 0];
|
||||
texS[1] = matrix[1 * 4 + 0];
|
||||
texS[2] = matrix[2 * 4 + 0];
|
||||
texS[3] = matrix[3 * 4 + 0];
|
||||
|
||||
texT[0] = matrix[0 * 4 + 1];
|
||||
texT[1] = matrix[1 * 4 + 1];
|
||||
texT[2] = matrix[2 * 4 + 1];
|
||||
texT[3] = matrix[3 * 4 + 1];
|
||||
}
|
||||
|
||||
SetVertexParm( RENDERPARM_TEXTUREMATRIX_S, texS );
|
||||
SetVertexParm( RENDERPARM_TEXTUREMATRIX_T, texT );
|
||||
}
|
||||
|
||||
void IGeometryPass::PrepareStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf )
|
||||
{
|
||||
float useTexGenParm[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// set the texture matrix if needed
|
||||
RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture );
|
||||
|
||||
// texgens
|
||||
if( pStage->texture.texgen == TG_REFLECT_CUBE )
|
||||
{
|
||||
|
||||
// see if there is also a bump map specified
|
||||
const shaderStage_t* bumpStage = surf->material->GetBumpStage();
|
||||
if( bumpStage != NULL )
|
||||
{
|
||||
// per-pixel reflection mapping with bump mapping
|
||||
GL_SelectTexture( 1 );
|
||||
bumpStage->texture.image->Bind();
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
|
||||
RENDERLOG_PRINTF( "TexGen: TG_REFLECT_CUBE: Bumpy Environment\n" );
|
||||
if( surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_BumpyEnvironmentSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_BumpyEnvironment();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RENDERLOG_PRINTF( "TexGen: TG_REFLECT_CUBE: Environment\n" );
|
||||
if( surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_EnvironmentSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_Environment();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if( pStage->texture.texgen == TG_SKYBOX_CUBE )
|
||||
{
|
||||
renderProgManager.BindShader_SkyBox();
|
||||
}
|
||||
else if( pStage->texture.texgen == TG_WOBBLESKY_CUBE )
|
||||
{
|
||||
|
||||
const int* parms = surf->material->GetTexGenRegisters();
|
||||
|
||||
float wobbleDegrees = surf->shaderRegisters[parms[0]] * ( idMath::PI / 180.0f );
|
||||
float wobbleSpeed = surf->shaderRegisters[parms[1]] * ( 2.0f * idMath::PI / 60.0f );
|
||||
float rotateSpeed = surf->shaderRegisters[parms[2]] * ( 2.0f * idMath::PI / 60.0f );
|
||||
|
||||
idVec3 axis[3];
|
||||
{
|
||||
// very ad-hoc "wobble" transform
|
||||
float s, c;
|
||||
idMath::SinCos( wobbleSpeed * viewDef->renderView.time[0] * 0.001f, s, c );
|
||||
|
||||
float ws, wc;
|
||||
idMath::SinCos( wobbleDegrees, ws, wc );
|
||||
|
||||
axis[2][0] = ws * c;
|
||||
axis[2][1] = ws * s;
|
||||
axis[2][2] = wc;
|
||||
|
||||
axis[1][0] = -s * s * ws;
|
||||
axis[1][2] = -s * ws * ws;
|
||||
axis[1][1] = idMath::Sqrt( idMath::Fabs( 1.0f - ( axis[1][0] * axis[1][0] + axis[1][2] * axis[1][2] ) ) );
|
||||
|
||||
// make the second vector exactly perpendicular to the first
|
||||
axis[1] -= ( axis[2] * axis[1] ) * axis[2];
|
||||
axis[1].Normalize();
|
||||
|
||||
// construct the third with a cross
|
||||
axis[0].Cross( axis[1], axis[2] );
|
||||
}
|
||||
|
||||
// add the rotate
|
||||
float rs, rc;
|
||||
idMath::SinCos( rotateSpeed * viewDef->renderView.time[0] * 0.001f, rs, rc );
|
||||
|
||||
float transform[12];
|
||||
transform[0 * 4 + 0] = axis[0][0] * rc + axis[1][0] * rs;
|
||||
transform[0 * 4 + 1] = axis[0][1] * rc + axis[1][1] * rs;
|
||||
transform[0 * 4 + 2] = axis[0][2] * rc + axis[1][2] * rs;
|
||||
transform[0 * 4 + 3] = 0.0f;
|
||||
|
||||
transform[1 * 4 + 0] = axis[1][0] * rc - axis[0][0] * rs;
|
||||
transform[1 * 4 + 1] = axis[1][1] * rc - axis[0][1] * rs;
|
||||
transform[1 * 4 + 2] = axis[1][2] * rc - axis[0][2] * rs;
|
||||
transform[1 * 4 + 3] = 0.0f;
|
||||
|
||||
transform[2 * 4 + 0] = axis[2][0];
|
||||
transform[2 * 4 + 1] = axis[2][1];
|
||||
transform[2 * 4 + 2] = axis[2][2];
|
||||
transform[2 * 4 + 3] = 0.0f;
|
||||
|
||||
SetVertexParms( RENDERPARM_WOBBLESKY_X, transform, 3 );
|
||||
renderProgManager.BindShader_WobbleSky();
|
||||
|
||||
}
|
||||
else if( ( pStage->texture.texgen == TG_SCREEN ) || ( pStage->texture.texgen == TG_SCREEN2 ) )
|
||||
{
|
||||
|
||||
useTexGenParm[0] = 1.0f;
|
||||
useTexGenParm[1] = 1.0f;
|
||||
useTexGenParm[2] = 1.0f;
|
||||
useTexGenParm[3] = 1.0f;
|
||||
|
||||
float mat[16];
|
||||
R_MatrixMultiply( surf->space->modelViewMatrix, viewDef->projectionMatrix, mat );
|
||||
|
||||
RENDERLOG_PRINTF( "TexGen : %s\n", ( pStage->texture.texgen == TG_SCREEN ) ? "TG_SCREEN" : "TG_SCREEN2" );
|
||||
renderLog.Indent();
|
||||
|
||||
float plane[4];
|
||||
plane[0] = mat[0 * 4 + 0];
|
||||
plane[1] = mat[1 * 4 + 0];
|
||||
plane[2] = mat[2 * 4 + 0];
|
||||
plane[3] = mat[3 * 4 + 0];
|
||||
SetVertexParm( RENDERPARM_TEXGEN_0_S, plane );
|
||||
RENDERLOG_PRINTF( "TEXGEN_S = %4.3f, %4.3f, %4.3f, %4.3f\n", plane[0], plane[1], plane[2], plane[3] );
|
||||
|
||||
plane[0] = mat[0 * 4 + 1];
|
||||
plane[1] = mat[1 * 4 + 1];
|
||||
plane[2] = mat[2 * 4 + 1];
|
||||
plane[3] = mat[3 * 4 + 1];
|
||||
SetVertexParm( RENDERPARM_TEXGEN_0_T, plane );
|
||||
RENDERLOG_PRINTF( "TEXGEN_T = %4.3f, %4.3f, %4.3f, %4.3f\n", plane[0], plane[1], plane[2], plane[3] );
|
||||
|
||||
plane[0] = mat[0 * 4 + 3];
|
||||
plane[1] = mat[1 * 4 + 3];
|
||||
plane[2] = mat[2 * 4 + 3];
|
||||
plane[3] = mat[3 * 4 + 3];
|
||||
SetVertexParm( RENDERPARM_TEXGEN_0_Q, plane );
|
||||
RENDERLOG_PRINTF( "TEXGEN_Q = %4.3f, %4.3f, %4.3f, %4.3f\n", plane[0], plane[1], plane[2], plane[3] );
|
||||
|
||||
renderLog.Outdent();
|
||||
|
||||
}
|
||||
else if( pStage->texture.texgen == TG_DIFFUSE_CUBE )
|
||||
{
|
||||
// As far as I can tell, this is never used
|
||||
idLib::Warning( "Using Diffuse Cube! Please contact Brian!" );
|
||||
|
||||
}
|
||||
else if( pStage->texture.texgen == TG_GLASSWARP )
|
||||
{
|
||||
// As far as I can tell, this is never used
|
||||
idLib::Warning( "Using GlassWarp! Please contact Brian!" );
|
||||
}
|
||||
|
||||
SetVertexParm( RENDERPARM_TEXGEN_0_ENABLED, useTexGenParm );
|
||||
}
|
||||
|
||||
void IGeometryPass::FinishStageTexturing( const shaderStage_t* stage, const drawSurf_t* surf )
|
||||
{
|
||||
if( stage->texture.cinematic )
|
||||
{
|
||||
// unbind the extra bink textures
|
||||
GL_SelectTexture( 0 );
|
||||
}
|
||||
|
||||
if( stage->texture.texgen == TG_REFLECT_CUBE )
|
||||
{
|
||||
// see if there is also a bump map specified
|
||||
const shaderStage_t* bumpStage = surf->material->GetBumpStage();
|
||||
if( bumpStage != NULL )
|
||||
{
|
||||
// per-pixel reflection mapping with bump mapping
|
||||
GL_SelectTexture( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// per-pixel reflection mapping without bump mapping
|
||||
}
|
||||
renderProgManager.Unbind();
|
||||
}
|
||||
}
|
||||
|
||||
bool IGeometryPass::GL_State( uint64 stateBits, bool forceGlState )
|
||||
{
|
||||
uint64 diff = stateBits ^ glStateBits;
|
||||
|
||||
if( !r_useStateCaching.GetBool() || forceGlState )
|
||||
{
|
||||
// make sure everything is set all the time, so we
|
||||
// can see if our delta checking is screwing up
|
||||
diff = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
else if( diff == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset pipeline
|
||||
auto& currentBlendState = pipelineDesc.renderState.blendState;
|
||||
auto& currentDepthStencilState = pipelineDesc.renderState.depthStencilState;
|
||||
auto& currentRasterState = pipelineDesc.renderState.rasterState;
|
||||
|
||||
//
|
||||
// culling
|
||||
//
|
||||
if( diff & ( GLS_CULL_BITS ) )//| GLS_MIRROR_VIEW ) )
|
||||
{
|
||||
switch( stateBits & GLS_CULL_BITS )
|
||||
{
|
||||
case GLS_CULL_TWOSIDED:
|
||||
currentRasterState.setCullNone();
|
||||
break;
|
||||
|
||||
case GLS_CULL_BACKSIDED:
|
||||
if( viewDef != NULL && viewDef->isMirror )
|
||||
{
|
||||
stateBits |= GLS_MIRROR_VIEW;
|
||||
currentRasterState.setCullFront();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRasterState.setCullBack();
|
||||
}
|
||||
break;
|
||||
|
||||
case GLS_CULL_FRONTSIDED:
|
||||
default:
|
||||
if( viewDef != NULL && viewDef->isMirror )
|
||||
{
|
||||
stateBits |= GLS_MIRROR_VIEW;
|
||||
currentRasterState.setCullBack();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRasterState.setCullFront();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check depthFunc bits
|
||||
//
|
||||
if( diff & GLS_DEPTHFUNC_BITS )
|
||||
{
|
||||
switch( stateBits & GLS_DEPTHFUNC_BITS )
|
||||
{
|
||||
case GLS_DEPTHFUNC_EQUAL:
|
||||
currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Equal;
|
||||
break;
|
||||
case GLS_DEPTHFUNC_ALWAYS:
|
||||
currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Always;
|
||||
break;
|
||||
case GLS_DEPTHFUNC_LESS:
|
||||
currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Less;
|
||||
break;
|
||||
case GLS_DEPTHFUNC_GREATER:
|
||||
currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Greater;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nvrhi::BlendState::RenderTarget renderTarget;
|
||||
|
||||
//
|
||||
// check blend bits
|
||||
//
|
||||
if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
|
||||
{
|
||||
nvrhi::BlendFactor srcFactor = nvrhi::BlendFactor::One;
|
||||
nvrhi::BlendFactor dstFactor = nvrhi::BlendFactor::One;
|
||||
|
||||
switch( stateBits & GLS_SRCBLEND_BITS )
|
||||
{
|
||||
case GLS_SRCBLEND_ZERO:
|
||||
srcFactor = nvrhi::BlendFactor::Zero;
|
||||
break;
|
||||
case GLS_SRCBLEND_ONE:
|
||||
srcFactor = nvrhi::BlendFactor::One;
|
||||
break;
|
||||
case GLS_SRCBLEND_DST_COLOR:
|
||||
srcFactor = nvrhi::BlendFactor::DstColor;
|
||||
break;
|
||||
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
|
||||
srcFactor = nvrhi::BlendFactor::OneMinusDstColor;
|
||||
break;
|
||||
case GLS_SRCBLEND_SRC_ALPHA:
|
||||
srcFactor = nvrhi::BlendFactor::SrcAlpha;
|
||||
break;
|
||||
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
|
||||
srcFactor = nvrhi::BlendFactor::OneMinusSrcAlpha;
|
||||
break;
|
||||
case GLS_SRCBLEND_DST_ALPHA:
|
||||
srcFactor = nvrhi::BlendFactor::DstAlpha;
|
||||
break;
|
||||
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
|
||||
srcFactor = nvrhi::BlendFactor::OneMinusDstAlpha;
|
||||
break;
|
||||
default:
|
||||
assert( !"GL_State: invalid src blend state bits\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
switch( stateBits & GLS_DSTBLEND_BITS )
|
||||
{
|
||||
case GLS_DSTBLEND_ZERO:
|
||||
dstFactor = nvrhi::BlendFactor::Zero;
|
||||
break;
|
||||
case GLS_DSTBLEND_ONE:
|
||||
dstFactor = nvrhi::BlendFactor::One;
|
||||
break;
|
||||
case GLS_DSTBLEND_SRC_COLOR:
|
||||
dstFactor = nvrhi::BlendFactor::SrcColor;
|
||||
break;
|
||||
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
|
||||
dstFactor = nvrhi::BlendFactor::OneMinusSrcColor;
|
||||
break;
|
||||
case GLS_DSTBLEND_SRC_ALPHA:
|
||||
dstFactor = nvrhi::BlendFactor::SrcAlpha;
|
||||
break;
|
||||
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
|
||||
dstFactor = nvrhi::BlendFactor::OneMinusSrcAlpha;
|
||||
break;
|
||||
case GLS_DSTBLEND_DST_ALPHA:
|
||||
dstFactor = nvrhi::BlendFactor::DstAlpha;
|
||||
break;
|
||||
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
|
||||
dstFactor = nvrhi::BlendFactor::OneMinusDstAlpha;
|
||||
break;
|
||||
default:
|
||||
assert( !"GL_State: invalid dst blend state bits\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
// Only actually update GL's blend func if blending is enabled.
|
||||
if( srcFactor == nvrhi::BlendFactor::One && dstFactor == nvrhi::BlendFactor::Zero )
|
||||
{
|
||||
renderTarget.disableBlend();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentBlendState.setAlphaToCoverageEnable( true );
|
||||
nvrhi::BlendState::RenderTarget renderTarget;
|
||||
renderTarget.enableBlend();
|
||||
renderTarget.setSrcBlend( srcFactor );
|
||||
renderTarget.setDestBlend( dstFactor );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check depthmask
|
||||
//
|
||||
if( diff & GLS_DEPTHMASK )
|
||||
{
|
||||
if( stateBits & GLS_DEPTHMASK )
|
||||
{
|
||||
currentDepthStencilState.disableDepthWrite();
|
||||
currentDepthStencilState.disableDepthTest();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDepthStencilState.enableDepthWrite();
|
||||
currentDepthStencilState.enableDepthTest();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check colormask
|
||||
//
|
||||
if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) )
|
||||
{
|
||||
nvrhi::ColorMask mask{ nvrhi::ColorMask::All };
|
||||
|
||||
if( stateBits & GLS_REDMASK )
|
||||
{
|
||||
mask = mask & ~nvrhi::ColorMask::Red;
|
||||
}
|
||||
if( stateBits & GLS_GREENMASK )
|
||||
{
|
||||
mask = mask & ~nvrhi::ColorMask::Green;
|
||||
}
|
||||
if( stateBits & GLS_BLUEMASK )
|
||||
{
|
||||
mask = mask & ~nvrhi::ColorMask::Blue;
|
||||
}
|
||||
if( stateBits & GLS_ALPHAMASK )
|
||||
{
|
||||
mask = mask & ~nvrhi::ColorMask::Alpha;
|
||||
}
|
||||
|
||||
renderTarget.setColorWriteMask( mask );
|
||||
}
|
||||
|
||||
currentBlendState.setRenderTarget( 0, renderTarget );
|
||||
|
||||
//
|
||||
// fill/line mode
|
||||
//
|
||||
if( diff & GLS_POLYMODE_LINE )
|
||||
{
|
||||
if( stateBits & GLS_POLYMODE_LINE )
|
||||
{
|
||||
currentRasterState.setFillMode( nvrhi::RasterFillMode::Line );
|
||||
currentRasterState.setCullNone();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRasterState.setCullNone();
|
||||
currentRasterState.setFillMode( nvrhi::RasterFillMode::Fill );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// polygon offset
|
||||
//
|
||||
if( diff & GLS_POLYGON_OFFSET )
|
||||
{
|
||||
if( stateBits & GLS_POLYGON_OFFSET )
|
||||
{
|
||||
currentRasterState.enableQuadFill();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRasterState.disableQuadFill();
|
||||
}
|
||||
}
|
||||
|
||||
nvrhi::DepthStencilState::StencilOpDesc stencilOp;
|
||||
|
||||
//
|
||||
// stencil
|
||||
//
|
||||
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) )
|
||||
{
|
||||
if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 )
|
||||
{
|
||||
currentDepthStencilState.enableStencil();
|
||||
currentDepthStencilState.enableDepthWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDepthStencilState.disableStencil();
|
||||
//currentDepthStencilState.disableDepthWrite();
|
||||
}
|
||||
}
|
||||
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) )
|
||||
{
|
||||
GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
|
||||
GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
|
||||
GLenum func = 0;
|
||||
|
||||
currentDepthStencilState.setStencilRefValue( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
|
||||
currentDepthStencilState.setStencilReadMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
|
||||
currentDepthStencilState.setStencilWriteMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
|
||||
|
||||
switch( stateBits & GLS_STENCIL_FUNC_BITS )
|
||||
{
|
||||
case GLS_STENCIL_FUNC_NEVER:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Never );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_LESS:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Less );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_EQUAL:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Equal );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_LEQUAL:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::LessOrEqual );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_GREATER:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Greater );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_NOTEQUAL:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::NotEqual );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_GEQUAL:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::GreaterOrEqual );
|
||||
break;
|
||||
case GLS_STENCIL_FUNC_ALWAYS:
|
||||
stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Always );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) )
|
||||
{
|
||||
GLenum sFail = 0;
|
||||
GLenum zFail = 0;
|
||||
GLenum pass = 0;
|
||||
|
||||
switch( stateBits & GLS_STENCIL_OP_FAIL_BITS )
|
||||
{
|
||||
case GLS_STENCIL_OP_FAIL_KEEP:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::Keep );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_ZERO:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::Zero );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_REPLACE:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::Replace );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_INCR:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::IncrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_DECR:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::DecrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_INVERT:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::Invert );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_INCR_WRAP:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::IncrementAndWrap );
|
||||
break;
|
||||
case GLS_STENCIL_OP_FAIL_DECR_WRAP:
|
||||
stencilOp.setFailOp( nvrhi::StencilOp::DecrementAndWrap );
|
||||
break;
|
||||
}
|
||||
switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS )
|
||||
{
|
||||
case GLS_STENCIL_OP_ZFAIL_KEEP:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::Keep );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_ZERO:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::Zero );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_REPLACE:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::Replace );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_INCR:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::IncrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_DECR:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::DecrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_INVERT:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::Invert );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::IncrementAndWrap );
|
||||
break;
|
||||
case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:
|
||||
stencilOp.setDepthFailOp( nvrhi::StencilOp::DecrementAndWrap );
|
||||
break;
|
||||
}
|
||||
switch( stateBits & GLS_STENCIL_OP_PASS_BITS )
|
||||
{
|
||||
case GLS_STENCIL_OP_PASS_KEEP:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::Keep );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_ZERO:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::Zero );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_REPLACE:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::Replace );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_INCR:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::IncrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_DECR:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::DecrementAndClamp );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_INVERT:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::Invert );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_INCR_WRAP:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::IncrementAndWrap );
|
||||
break;
|
||||
case GLS_STENCIL_OP_PASS_DECR_WRAP:
|
||||
stencilOp.setPassOp( nvrhi::StencilOp::DecrementAndWrap );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentDepthStencilState.setFrontFaceStencil( stencilOp );
|
||||
|
||||
glStateBits = stateBits;
|
||||
pipeline = nullptr;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_SelectTexture( int imageParm )
|
||||
{
|
||||
currentImageParm = imageParm;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_BindTexture( idImage* img )
|
||||
{
|
||||
imageParms[currentImageParm] = img;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_BindFramebuffer( Framebuffer* framebuffer )
|
||||
{
|
||||
if( currentFramebuffer != framebuffer )
|
||||
{
|
||||
previousFramebuffer = currentFramebuffer;
|
||||
pipeline = nullptr;
|
||||
}
|
||||
currentFramebuffer = framebuffer;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_BindGraphicsShader( int shaderIndex )
|
||||
{
|
||||
nvrhi::ShaderHandle shader = renderProgManager.GetShader( shaderIndex );
|
||||
if( shader->getDesc().shaderType == nvrhi::ShaderType::Vertex )
|
||||
{
|
||||
if( pipelineDesc.VS != shader )
|
||||
{
|
||||
pipeline = nullptr;
|
||||
}
|
||||
|
||||
pipelineDesc.setVertexShader( shader );
|
||||
}
|
||||
|
||||
if( shader->getDesc().shaderType == nvrhi::ShaderType::Pixel )
|
||||
{
|
||||
if( pipelineDesc.PS != shader )
|
||||
{
|
||||
pipeline = nullptr;
|
||||
}
|
||||
|
||||
pipelineDesc.setPixelShader( shader );
|
||||
}
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_DepthBoundsTest( const float zmin, const float zmax )
|
||||
{
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_PolygonOffset( float scale, float bias )
|
||||
{
|
||||
pipelineDesc.renderState.rasterState.setSlopeScaleDepthBias( scale ).setDepthBias( bias );
|
||||
pipeline = nullptr;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_Viewport( int x, int y, int w, int h )
|
||||
{
|
||||
currentViewport.Clear();
|
||||
currentViewport.AddPoint( x, y );
|
||||
currentViewport.AddPoint( x + w, y + h );
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_Scissor( int x, int y, int w, int h )
|
||||
{
|
||||
currentScissor.Clear();
|
||||
currentScissor.AddPoint( x, y );
|
||||
currentScissor.AddPoint( x + w, y + h );
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_Color( const idVec4 color )
|
||||
{
|
||||
// TODO(Stephen): Hold local copy and then set in a constant buffer later.
|
||||
float parm[4];
|
||||
parm[0] = idMath::ClampFloat( 0.0f, 1.0f, color.x );
|
||||
parm[1] = idMath::ClampFloat( 0.0f, 1.0f, color.y );
|
||||
parm[2] = idMath::ClampFloat( 0.0f, 1.0f, color.z );
|
||||
parm[3] = idMath::ClampFloat( 0.0f, 1.0f, color.w );
|
||||
renderProgManager.SetRenderParm( RENDERPARM_COLOR, parm );
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_ClearColor( const idVec4 color )
|
||||
{
|
||||
clearColor = color;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_ClearDepthStencilValue( float depthValue, byte stencilValue )
|
||||
{
|
||||
depthClearValue = depthValue;
|
||||
stencilClearValue = stencilValue;
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_ClearColor( nvrhi::ICommandList* commandList, int attachmentIndex )
|
||||
{
|
||||
nvrhi::utils::ClearColorAttachment(
|
||||
commandList,
|
||||
currentFramebuffer->GetApiObject(),
|
||||
attachmentIndex,
|
||||
nvrhi::Color( clearColor.x, clearColor.y, clearColor.z, clearColor.w ) );
|
||||
}
|
||||
|
||||
void IGeometryPass::GL_ClearDepthStencil( nvrhi::ICommandList* commandList )
|
||||
{
|
||||
nvrhi::utils::ClearDepthStencilAttachment( commandList, currentFramebuffer->GetApiObject(), depthClearValue, stencilClearValue );
|
||||
}
|
||||
#endif
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef RENDERER_PASSES_GEOMETRYPASSES_H_
|
||||
#define RENDERER_PASSES_GEOMETRYPASSES_H_
|
||||
|
||||
constexpr std::size_t MAX_IMAGE_PARMS = 16;
|
||||
|
||||
#if 0
|
||||
|
||||
class IGeometryPass
|
||||
{
|
||||
public:
|
||||
virtual ~IGeometryPass() = default;
|
||||
|
||||
virtual void SetupView( nvrhi::ICommandList* commandList, viewDef_t* viewDef ) = 0;
|
||||
virtual bool SetupMaterial( const idMaterial* material, nvrhi::RasterCullMode cullMode, nvrhi::GraphicsState& state ) = 0;
|
||||
virtual void SetupInputBuffers( const drawSurf_t* drawSurf, nvrhi::GraphicsState& state ) = 0;
|
||||
virtual void SetPushConstants( nvrhi::ICommandList* commandList, nvrhi::GraphicsState& state, nvrhi::DrawArguments& args ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
void PrepareStageTexturing( const shaderStage_t* stage, const drawSurf_t* surf );
|
||||
void FinishStageTexturing( const shaderStage_t* stage, const drawSurf_t* surf );
|
||||
|
||||
protected:
|
||||
|
||||
int currentImageParm = 0;
|
||||
idArray< idImage*, MAX_IMAGE_PARMS > imageParms;
|
||||
uint64 glStateBits;
|
||||
nvrhi::GraphicsPipelineDesc pipelineDesc;
|
||||
nvrhi::GraphicsPipelineHandle pipeline;
|
||||
BindingCache bindingCache;
|
||||
Framebuffer* previousFramebuffer;
|
||||
Framebuffer* currentFramebuffer;
|
||||
Framebuffer* lastFramebuffer;
|
||||
const viewDef_t* viewDef;
|
||||
const viewEntity_t* currentSpace;
|
||||
idScreenRect currentViewport;
|
||||
idScreenRect currentScissor;
|
||||
idVec4 clearColor;
|
||||
float depthClearValue;
|
||||
byte stencilClearValue;
|
||||
|
||||
// Updates state to bits in stateBits. Only updates the different bits.
|
||||
bool GL_State( uint64 stateBits, bool forceGlState = false );
|
||||
void GL_SelectTexture( int textureNum );
|
||||
void GL_BindTexture( idImage* img );
|
||||
void GL_BindFramebuffer( Framebuffer* framebuffer );
|
||||
void GL_BindGraphicsShader( int shader );
|
||||
void GL_DepthBoundsTest( const float zmin, const float zmax );
|
||||
void GL_PolygonOffset( float scale, float bias );
|
||||
void GL_Viewport( int x, int y, int w, int h );
|
||||
void GL_Scissor( int x, int y, int w, int h );
|
||||
void GL_Color( const idVec4 color );
|
||||
void GL_ClearColor( const idVec4 color );
|
||||
void GL_ClearDepthStencilValue( float depthValue, byte stencilValue = 0xF );
|
||||
void GL_ClearColor( nvrhi::ICommandList* commandList, int attachmentIndex = 0 );
|
||||
void GL_ClearDepthStencil( nvrhi::ICommandList* commandList );
|
||||
|
||||
ID_INLINE uint64 GL_GetCurrentState() const
|
||||
{
|
||||
return glStateBits;
|
||||
}
|
||||
|
||||
ID_INLINE void GL_ViewportAndScissor( int x, int y, int w, int h )
|
||||
{
|
||||
GL_Viewport( x, y, w, h );
|
||||
GL_Scissor( x, y, w, h );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -36,7 +36,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#include "Passes/CommonPasses.h"
|
||||
#include "Passes/MipMapGenPass.h"
|
||||
#include "Passes/FowardShadingPass.h"
|
||||
#include "Passes/SsaoPass.h"
|
||||
#include "Passes/TonemapPass.h"
|
||||
#include "Passes/TemporalAntiAliasingPass.h"
|
||||
|
|
Loading…
Reference in a new issue