OpenBarnyard
 
Loading...
Searching...
No Matches
AGrassShaderHAL_DX8.cpp
Go to the documentation of this file.
1#include "pch.h"
4#include "AGrassMeshHAL_DX8.h"
8
9#include <Toshi/TScheduler.h>
17
18//-----------------------------------------------------------------------------
19// Enables memory debugging.
20// Note: Should be the last include!
21//-----------------------------------------------------------------------------
22#include <Core/TMemoryDebugOn.h>
23
25
27
29static TVector3 g_vecAnimationDataOffset;
30static TVector4 g_vecAnimOffset;
31static const TFLOAT g_fAnimationSpeed = 2.25f;
32
33// $Barnyard: FUNCTION 005f7c10
35 : m_hVertexShader( 0 )
36{
37}
38
39// $Barnyard: FUNCTION 005f7c70
40// $Barnyard: FUNCTION 005f8310
44
45// $Barnyard: FUNCTION 005f7ee0
47{
48 Validate();
49
51 TRenderContextD3D* pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
52 IDirect3DDevice8* pD3DDevice = pRenderInterface->GetDirect3DDevice();
53
54 pD3DDevice->SetVertexShader( m_hVertexShader );
55 pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, 2 );
56 pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, 2 );
57 pD3DDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, 1 );
58 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 4 );
59 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, 2 );
60 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, 1 );
61 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, 4 );
62 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, 2 );
63 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, 1 );
64 pD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, 1 );
65 pD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, 1 );
66 pD3DDevice->SetVertexShader( D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_XYZ );
67
68 static TMatrix44 s_ViewMatrix = TMatrix44::IDENTITY;
69
70 pD3DDevice->SetTransform( D3DTS_PROJECTION, pCurrentContext->GetProjectionMatrix() );
71 pD3DDevice->SetTransform( D3DTS_VIEW, s_ViewMatrix );
72
73 pD3DDevice->SetPixelShader( 0 );
74 pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
75 pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
76 pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
77 pD3DDevice->SetRenderState( D3DRS_ALPHAREF, 1 );
78 pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, 5 );
79 pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
80 pD3DDevice->SetRenderState( D3DRS_LIGHTING, 0 );
81
82 m_oOrderTable.Render();
83 pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
84}
85
86// $Barnyard: FUNCTION 005f8660
88{
89 if ( IsValidated() )
90 {
92 IDirect3DDevice8* pD3DDevice = pRenderInterface->GetDirect3DDevice();
93
94 pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, 1 );
95 pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, 1 );
96 pD3DDevice->SetVertexShader( m_hVertexShader );
97 pD3DDevice->SetPixelShader( 0 );
98
99 AWorldShaderHAL* pWorldShader = TSTATICCAST( AWorldShaderHAL, AWorldShader::GetSingleton() );
100 TVector4 vecShadowColor = pWorldShader->GetShadowColour();
101 TVector4 vecAmbientColor = pWorldShader->GetAmbientColour();
102 static constexpr TVector4 vecColor = TVector4( 1.0f, 1.0f, 1.0f, 1.0f );
103
104 pD3DDevice->SetVertexShaderConstant( 4, &vecAmbientColor, 1 );
105 pD3DDevice->SetVertexShaderConstant( 5, &vecShadowColor, 1 );
106 pD3DDevice->SetVertexShaderConstant( 6, &vecColor, 1 );
107
108 pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
109 pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
110 pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
111 pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, 5 );
112
113 DWORD dwWasSpecularEnabled;
114 pD3DDevice->GetRenderState( D3DRS_SPECULARENABLE, &dwWasSpecularEnabled );
115 pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
116 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 4 );
117 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, 2 );
118 pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, 0 );
119 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, 4 );
120 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, 2 );
121 pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, 0 );
122 pD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, 1 );
123 pD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, 1 );
124
125 UpdateAnimation();
126 }
127}
128
129// $Barnyard: FUNCTION 005f7ea0
131{
133 IDirect3DDevice8* pD3DDevice = pRenderInterface->GetDirect3DDevice();
134
135 pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
136 pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
137 pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
138}
139
140// $Barnyard: FUNCTION 005f7cd0
142{
143 m_oOrderTable.Create( this, -2000 );
144 AGrassShader::Create();
145
146 return Validate();
147}
148
149// $Barnyard: FUNCTION 005f7d00
150static TBOOL CreateGrassVertexShader( const char* a_szFileName, const DWORD* a_pFunction, DWORD* a_pOutVertexShader )
151{
152 static constexpr DWORD s_ShaderDeclaration[] = {
153 0x20000000, 0x40020000, 0x40020001, 0x40020002,
154 0x40010003, 0xFFFFFFFF
155 };
156
157 return TRenderD3DInterface::CreateVertexShader( s_ShaderDeclaration, a_pFunction, a_pOutVertexShader );
158}
159
160// $Barnyard: FUNCTION 005f7d60
162{
163 constexpr static TUINT8 s_VertexShaderFunction[] = { 0x01, 0x01, 0xfe, 0xff, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x07, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0f, 0x80, 0x08, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0f, 0x80, 0x05, 0x00, 0xe4, 0x80, 0x07, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x80, 0x06, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0xe4, 0x91, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0x90, 0x04, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x06, 0x00, 0xff, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0x90, 0x08, 0x00, 0xff, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x04, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00 };
164
165 if ( IsValidated() )
166 return TTRUE;
167
168 if ( !CreateGrassVertexShader( "AGrassShader_D3D8_Win.vsh", (DWORD*)s_VertexShaderFunction, &m_hVertexShader ) )
169 return TFALSE;
170
171 return AGrassShader::Validate();
172}
173
174// $Barnyard: FUNCTION 005f7da0
176{
177 if ( IsValidated() )
178 {
179 if ( m_hVertexShader != 0 )
180 {
182 }
183
184 AGrassShader::Invalidate();
185 }
186}
187
193
195{
196 Validate();
197 return TTRUE;
198}
199
200// $Barnyard: FUNCTION 005f8330
201void AGrassShaderHAL::Render( Toshi::TRenderPacket* a_pRenderPacket )
202{
203 AGrassMeshHAL* pMesh;
204
205 if ( a_pRenderPacket && ( pMesh = TSTATICCAST( AGrassMeshHAL, a_pRenderPacket->GetMesh() ), pMesh != TNULL ) )
206 {
208 TRenderContextD3D* pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
209 IDirect3DDevice8* pD3DDevice = pRenderInterface->GetDirect3DDevice();
210
211 D3DXMATRIX matMVP;
212 D3DXMatrixMultiply( &matMVP, a_pRenderPacket->GetModelViewMatrix(), pCurrentContext->GetProjectionMatrix() );
213 D3DXMatrixTranspose( &matMVP, &matMVP );
214
215 pD3DDevice->SetVertexShaderConstant( 0, &matMVP, 4 );
216
219 pVertexPool->GetHALBuffer( &oVertexBuffer );
220 pD3DDevice->SetStreamSource( 0, oVertexBuffer.apVertexBuffers[ 0 ], sizeof( WorldVertex ) );
221
224 pIndexPool->GetHALBuffer( &oIndexBuffer );
225 pD3DDevice->SetIndices( oIndexBuffer.pIndexBuffer, oVertexBuffer.uiVertexOffset );
226
227 TVector4 vecOffset = TVector4( 0.0f, 0.0f, 0.0f, 0.0f );
228 g_vecAnimOffset.w = 1.0f;
229
230 pD3DDevice->SetVertexShaderConstant( 8, &g_vecAnimOffset, 1 );
231 pD3DDevice->SetVertexShaderConstant( 7, &vecOffset, 1 );
232 pD3DDevice->SetTexture( 0, g_pGrassShaderTerrainTexture->GetD3DTexture() );
233 pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, pVertexPool->GetNumVertices(), oIndexBuffer.uiIndexOffset, pIndexPool->GetNumIndices() - 2 );
234
235 ACamera* pCamera = ACameraManager::GetSingleton()->GetCurrentCamera();
236 TVector4 vecCamPos = pCamera->GetMatrix().GetTranslation();
237
238 // Transform coordinates to the actual world position, since they are exported rotated
239 TVector4 vecMeshBounding;
240 vecMeshBounding.x = pMesh->GetCellMeshSphere()->m_BoundingSphere.AsVector4().x;
241 vecMeshBounding.y = -pMesh->GetCellMeshSphere()->m_BoundingSphere.AsVector4().z;
242 vecMeshBounding.z = pMesh->GetCellMeshSphere()->m_BoundingSphere.AsVector4().y;
243 vecMeshBounding.w = pMesh->GetCellMeshSphere()->m_BoundingSphere.GetRadius();
244
245 TFLOAT fDistanceToCamera = TVector4::DistanceXZ( vecMeshBounding, vecCamPos ) - vecMeshBounding.w;
246
247 if ( fDistanceToCamera <= 100.0f )
248 {
249 constexpr TINT MAX_LAYERS = 5;
250 TINT iNumLayers = MAX_LAYERS;
251
252 if ( fDistanceToCamera > 20.0f )
253 {
254 iNumLayers = ( fDistanceToCamera >= 50.0f ) ?
255 1 :
256 MAX_LAYERS - 1 - TMath::Min( TINT( ( fDistanceToCamera - 20.0f ) / 10.0f ), MAX_LAYERS - 2 );
257 }
258
259 g_vecAnimOffset.w = 2.0f;
260 TFLOAT fStepSize = 0.25f / iNumLayers;
261
262 for ( TINT i = 1; i <= iNumLayers; i++ )
263 {
264 extern T2Texture* g_aGrassLayers[ 7 ]; // AModelLoader_World.cpp
265
266 pD3DDevice->SetTexture( 0, g_aGrassLayers[ i ]->GetD3DTexture() );
267 pD3DDevice->SetVertexShaderConstant( 8, &g_vecAnimOffset, 1 );
268
269 vecOffset.x += fStepSize;
270 vecOffset.y += fStepSize;
271 vecOffset.z += fStepSize;
272 pD3DDevice->SetVertexShaderConstant( 7, &vecOffset, 1 );
273 pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, pVertexPool->GetNumVertices(), oIndexBuffer.uiIndexOffset, pIndexPool->GetNumIndices() - 2 );
274 }
275 }
276 }
277}
278
279// $Barnyard: FUNCTION 005f8b10
281{
282 Validate();
283
284 AGrassMaterialHAL* pMaterial = new AGrassMaterialHAL();
285 pMaterial->SetShader( this );
286
287 m_oOrderTable.RegisterMaterial( pMaterial );
288 return pMaterial;
289}
290
291// $Barnyard: FUNCTION 005f8a80
293{
294 Validate();
295
296 AGrassMeshHAL* pMesh = new AGrassMeshHAL();
297 pMesh->SetOwnerShader( this );
298
299 return pMesh;
300}
301
302// $Barnyard: FUNCTION 005f7de0
303void AGrassShaderHAL::UpdateAnimation()
304{
305 TFLOAT fCurrentTime = g_oSystemManager.GetScheduler()->GetTotalTime();
306
307 TVector3 vecAnim = TVector3(
308 fCurrentTime * 0.70f * g_fAnimationSpeed,
309 fCurrentTime * 0.92f * g_fAnimationSpeed,
310 fCurrentTime * 0.20f * g_fAnimationSpeed
311 );
312
313 TMath::NormaliseAngle( vecAnim.x );
314 TMath::NormaliseAngle( vecAnim.y );
315 TMath::NormaliseAngle( vecAnim.z );
316
317 g_vecAnimationDataOffset.x = TMath::Sin( vecAnim.x );
318 g_vecAnimationDataOffset.y = TMath::Sin( vecAnim.y );
319 g_vecAnimationDataOffset.z = TMath::Sin( vecAnim.z );
320 g_vecAnimationDataOffset.Multiply( 0.075f );
321
322 g_vecAnimOffset.x = g_vecAnimationDataOffset.x;
323 g_vecAnimOffset.y = g_vecAnimationDataOffset.y;
324 g_vecAnimOffset.z = g_vecAnimationDataOffset.z;
325}
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TOSHI_NAMESPACE_USING
Definition Defines.h:46
#define TDEFINE_CLASS(...)
Definition TObject.h:120
char TCHAR
Definition Typedefs.h:20
uint8_t TUINT8
Definition Typedefs.h:17
float TFLOAT
Definition Typedefs.h:4
#define TNULL
Definition Typedefs.h:23
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
Toshi::T2Texture * g_aGrassLayers[7]
TTextureResourceHAL * g_pGrassShaderTerrainTexture
TSystemManager g_oSystemManager
Definition TSystem.cpp:15
TFORCEINLINE void NormaliseAngle(TFLOAT &a_rfValue)
TFORCEINLINE const T & Min(const T &a, const T &b)
TFORCEINLINE TFLOAT Sin(TFLOAT fVal)
Definition TMathInline.h:42
static constinit TMatrix44 IDENTITY
Definition TMatrix44.h:357
TFLOAT y
Definition TVector3.h:163
TFLOAT z
Definition TVector3.h:163
TFLOAT x
Definition TVector3.h:163
TFLOAT w
Definition TVector4.h:367
static TFLOAT DistanceXZ(const TVector4 &vec1, const TVector4 &vec2)
Definition TVector4.h:333
TFLOAT x
Definition TVector4.h:367
TFLOAT y
Definition TVector4.h:367
TFLOAT z
Definition TVector4.h:367
TBOOL GetHALBuffer(TIndexBlockResource::HALBuffer *a_pHALBuffer)
static TRenderContextD3D * Upcast(TRenderContext *a_pRenderContext)
const TMatrix44 & GetProjectionMatrix() const
DirectX 8 implementation of the render interface Handles DirectX 8 specific rendering functionality a...
static TBOOL CreateVertexShader(const DWORD *a_ShaderDeclaration, const DWORD *a_pFunction, DWORD *a_pOutVertexShader)
Creates a vertex shader.
TFORCEINLINE IDirect3DDevice8 * GetDirect3DDevice() const
Gets the Direct3D device.
static TFORCEINLINE TRenderD3DInterface * Interface()
Gets the render interface singleton.
static void DestroyVertexShader(DWORD a_hVertexShader)
Destroys a vertex shader.
IDirect3DVertexBuffer8 * apVertexBuffers[TVertexFactoryFormat::MAX_NUM_STREAMS]
TBOOL GetHALBuffer(TVertexBlockResource::HALBuffer *a_pHALBuffer)
TRenderContext * GetCurrentContext() const
Toshi::TMatrix44 & GetMatrix()
Definition ACamera.cpp:58
CellMeshSphere * GetCellMeshSphere() const
virtual void EndFlush() override
virtual void Flush() override
virtual TBOOL TryInvalidate() override
virtual void StartFlush() override
virtual TBOOL TryValidate() override
virtual TBOOL Validate() override
virtual void Invalidate() override
virtual AGrassMesh * CreateMesh(const TCHAR *a_szName) override
virtual TBOOL Create() override
virtual AGrassMaterial * CreateMaterial(const TCHAR *a_szName) override
virtual void Render(Toshi::TRenderPacket *a_pRenderPacket) override
const Toshi::TVector4 & GetShadowColour() const
const Toshi::TVector4 & GetAmbientColour() const
virtual Toshi::TVertexPoolResourceInterface * GetVertexPool()
AWorldMesh::SubMesh * GetSubMesh(TUINT a_uiIndex)
Definition AGrassMesh.h:38
Toshi::TIndexPoolResourceInterface * pIndexPool
Definition AWorldMesh.h:16
Toshi::TSphere m_BoundingSphere
Definition AWorld.h:82