OpenBarnyard
 
Loading...
Searching...
No Matches
AWorldShader_DX8.cpp
Go to the documentation of this file.
1#include "pch.h"
2#include "AWorldShader_DX8.h"
4#include "AWorldMesh_DX8.h"
5#include "World/AWorld.h"
6
14#include <d3d8.h>
15
16//-----------------------------------------------------------------------------
17// Enables memory debugging.
18// Note: Should be the last include!
19//-----------------------------------------------------------------------------
20#include <Core/TMemoryDebugOn.h>
21
23
25
27 : m_ShadowColour( 0.3f, 0.3f, 0.3f, 1.0f ), m_AmbientColour( 1.0f, 1.0f, 1.0f, 1.0f )
28{
29 m_hVertexShader = 0;
30 m_pUnk2 = TNULL;
31 m_iAlphaRef = 128;
32
33 m_bIsHighEndMode = TTRUE;
34 m_bAlphaBlendMaterial = TFALSE;
35 m_bUnkFlag3 = TFALSE;
36 m_bUnkFlag4 = TFALSE;
37}
38
42
44{
45 if ( IsValidated() )
46 {
47 auto pRenderInterface = TRenderD3DInterface::Interface();
48 auto pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
49 auto pDevice = pRenderInterface->GetDirect3DDevice();
50
51 if ( IsHighEndMode() )
52 {
53 Validate();
54 pDevice->SetVertexShader( m_hVertexShader );
55 pDevice->SetPixelShader( NULL );
56
57 static constexpr TVector4 s_SomeVector( 1.0f, 1.0f, 1.0f, 1.0f );
58 pDevice->SetVertexShaderConstant( 4, &m_AmbientColour, 1 );
59 pDevice->SetVertexShaderConstant( 5, &m_ShadowColour, 1 );
60 pDevice->SetVertexShaderConstant( 6, &s_SomeVector, 1 );
61
62 pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
63 pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
64 pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
65 pDevice->SetRenderState( D3DRS_ALPHAFUNC, 5 );
66
67 DWORD dwWasSpecularEnabled;
68 pDevice->GetRenderState( D3DRS_SPECULARENABLE, &dwWasSpecularEnabled );
69 pDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
70 pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 4 );
71 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, 2 );
72 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, 0 );
73 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, 4 );
74 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, 2 );
75 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, 0 );
76 pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, 1 );
77 pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, 1 );
78 pDevice->SetRenderState( D3DRS_CULLMODE, m_bRenderEnvMap ? D3DCULL_CCW : D3DCULL_CW );
79 pDevice->SetRenderState( D3DRS_SPECULARENABLE, dwWasSpecularEnabled );
80 pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
81 pDevice->SetPixelShader( 0 );
82 }
83 else
84 {
85 SetupLowEndMode();
86 }
87 }
88}
89
91{
92 if ( IsValidated() )
93 {
94 auto pRenderInterface = TRenderD3DInterface::Interface();
95 auto pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
96 auto pDevice = pRenderInterface->GetDirect3DDevice();
97
98 pDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, 1 );
99 pDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, 1 );
100
101 if ( !IsHighEndMode() )
102 {
103 SetupLowEndMode();
104 return;
105 }
106
107 Validate();
108 pDevice->SetVertexShader( m_hVertexShader );
109 pDevice->SetPixelShader( NULL );
110
111 static constexpr TVector4 s_SomeVector( 1.0f, 1.0f, 1.0f, 1.0f );
112 pDevice->SetVertexShaderConstant( 4, &m_AmbientColour, 1 );
113 pDevice->SetVertexShaderConstant( 5, &m_ShadowColour, 1 );
114 pDevice->SetVertexShaderConstant( 6, &s_SomeVector, 1 );
115
116 pDevice->SetRenderState( D3DRS_ZWRITEENABLE, 1 );
117 pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, 1 );
118 pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, 1 );
119 pDevice->SetRenderState( D3DRS_ALPHAFUNC, 5 );
120
121 DWORD dwWasSpecularEnabled;
122 pDevice->GetRenderState( D3DRS_SPECULARENABLE, &dwWasSpecularEnabled );
123 pDevice->SetRenderState( D3DRS_SPECULARENABLE, 0 );
124 pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 4 );
125 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, 2 );
126 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, 0 );
127 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, 4 );
128 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, 2 );
129 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, 0 );
130 pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, 1 );
131 pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, 1 );
132 pDevice->SetRenderState( D3DRS_CULLMODE, m_bRenderEnvMap ? D3DCULL_CCW : D3DCULL_CW );
133 }
134}
135
137{
138 auto pRenderInterface = TRenderD3DInterface::Interface();
139 auto pDevice = pRenderInterface->GetDirect3DDevice();
140
141 pDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
142 pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
143 pDevice->SetPixelShader( NULL );
144}
145
147{
148 m_aOrderTables[ 0 ].Create( this, -3000 );
149 m_aOrderTables[ 1 ].Create( this, 100 );
150 m_aOrderTables[ 2 ].Create( this, 101 );
151 m_aOrderTables[ 3 ].Create( this, 601 );
152 m_aOrderTables[ 4 ].Create( this, -400 );
153 m_aOrderTables[ 5 ].Create( this, 500 );
154 m_aOrderTables[ 6 ].Create( this, -6005 );
155 m_aOrderTables[ 7 ].Create( this, -7000 );
156 return AWorldShader::Create();
157}
158
159static TBOOL CreateWorldVertexShader( const char* a_szFileName, const DWORD* a_pFunction, DWORD* a_pOutVertexShader )
160{
161 static constexpr DWORD s_ShaderDeclaration[] = {
162 0x20000000, 0x40020000, 0x40020001, 0x40020002,
163 0x40010003, 0xFFFFFFFF
164 };
165
166 return TRenderD3DInterface::CreateVertexShader( s_ShaderDeclaration, a_pFunction, a_pOutVertexShader );
167}
168
170{
171 if ( IsValidated() )
172 {
173 return TTRUE;
174 }
175
176 // Enable high end mode if it is supported
178
179 if ( IsHighEndMode() )
180 {
181 constexpr static DWORD s_VertexShaderFunction[] = {
182 0xFFFE0101, 0x14, 0xC00F0000, 0x90E40000,
183 0xA0E40000, 0x2, 0x800F0001, 0xA0E40006,
184 0x91E40002, 0x5, 0x800F0000, 0x90E40002,
185 0xA0E40004, 0x5, 0x800F0002, 0x80E40001,
186 0xA0E40005, 0x2, 0x800F0000, 0x80E40000,
187 0x80E40002, 0x1, 0x80080000, 0xA0FF0006,
188 0x1, 0xD00F0000, 0x80E40000, 0x5,
189 0x80010001, 0x90000002, 0xA0000008, 0x4,
190 0xD0080000, 0x80FF0000, 0xA0550008, 0x80000001,
191 0x2, 0xE0030000, 0xA0540007, 0x90540003,
192 0x2, 0xE0030001, 0xA0FE0007, 0x90540003,
193 0xFFFF
194 };
195
196 if ( !CreateWorldVertexShader( "AWorldShader_D3D8_Win.vsh", s_VertexShaderFunction, &m_hVertexShader ) )
197 {
198 TASSERT( !"Couldn't create vertex shader" );
199 return TFALSE;
200 }
201 }
202
203 return AWorldShader::Validate();
204}
205
207{
208 if ( !IsValidated() ) return;
209
210 if ( !IsHighEndMode() )
211 {
212 m_SomeList.DeleteAll();
213 }
214 else if ( m_hVertexShader != 0 )
215 {
217 m_hVertexShader = 0;
218 }
219
221}
222
228
230{
231 Validate();
232 return TTRUE;
233}
234
236{
237 if ( IsHighEndMode() && a_pRenderPacket && a_pRenderPacket->GetMesh() )
238 {
239 auto pRenderInterface = TRenderD3DInterface::Interface();
240 auto pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
241 auto pDevice = pRenderInterface->GetDirect3DDevice();
242
243 D3DXMATRIX mMVP;
244 D3DXMatrixMultiply( &mMVP, a_pRenderPacket->GetModelViewMatrix(), pCurrentContext->GetProjectionMatrix() );
245 D3DXMatrixTranspose( &mMVP, &mMVP );
246
247 pDevice->SetVertexShaderConstant( 0, &mMVP, 4 );
248
249 if ( a_pRenderPacket->GetAlpha() >= 1.0f || isnan( a_pRenderPacket->GetAlpha() ) )
250 {
251 if ( s_RenderStateFlags & 24 )
252 {
253 pDevice->SetRenderState( D3DRS_ALPHAREF, m_iAlphaRef );
254 s_RenderStateFlags &= ~24;
255 }
256 }
257 else
258 {
259 pDevice->SetRenderState( D3DRS_ALPHAREF, TUINT8( m_iAlphaRef * a_pRenderPacket->GetAlpha() ) );
260 s_RenderStateFlags |= 24;
261 }
262
263 auto pMesh = TSTATICCAST( AWorldMeshHAL, a_pRenderPacket->GetMesh() );
264 auto pMaterial = TSTATICCAST( AWorldMaterialHAL, pMesh->GetMaterial() );
265
266 if ( pMaterial->GetBlendMode() != 0 || a_pRenderPacket->GetAlpha() < 1.0f )
267 {
268 if ( ISZERO( s_RenderStateFlags & 0x1b ) )
269 {
270 pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
271 s_RenderStateFlags |= 0x1b;
272 }
273 }
274 else if ( !ISZERO( s_RenderStateFlags & 0x1b ) )
275 {
276 pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
277 s_RenderStateFlags &= ~0x1b;
278 }
279
280 TVector4 vSomeConst;
281 vSomeConst.x = 0.0f;
282 vSomeConst.y = 1.0f;
283
284 if ( pMesh->IsUnknownState1() )
285 {
286 vSomeConst.x = 1.0f;
287 vSomeConst.y = 0.0f;
288 }
289
290 vSomeConst.w = 1.0f;
291 vSomeConst.z = 0.0f;
292
293 pDevice->SetVertexShaderConstant( 8, &vSomeConst, 1 );
294
295 // Set vertices
296 auto pVertexPool = TSTATICCAST( TVertexPoolResource, pMesh->GetVertexPool() );
297 TVALIDPTR( pVertexPool );
298
300 pVertexPool->GetHALBuffer( &vertexBuffer );
301
302 pDevice->SetStreamSource( 0, vertexBuffer.apVertexBuffers[ 0 ], sizeof( WorldVertex ) );
303
304 // Set indices
305 auto pIndexPool = TSTATICCAST( TIndexPoolResource, pMesh->GetSubMesh( 0 )->pIndexPool );
306 TVALIDPTR( pIndexPool );
307
309 pIndexPool->GetHALBuffer( &indexBuffer );
310
311 pDevice->SetIndices( indexBuffer.pIndexBuffer, vertexBuffer.uiVertexOffset );
312
313 // Draw mesh
314 pDevice->DrawIndexedPrimitive(
315 D3DPT_TRIANGLESTRIP,
316 0,
317 pVertexPool->GetNumVertices(),
318 indexBuffer.uiIndexOffset,
319 pIndexPool->GetNumIndices() - 2
320 );
321 }
322}
323
325{
326 m_bRenderEnvMap = a_bEnable;
327}
328
330{
331 return m_bAlphaBlendMaterial;
332}
333
334void AWorldShaderHAL::SetAlphaBlendMaterial( TBOOL a_bIsAlphaBlendMaterial )
335{
336 m_bAlphaBlendMaterial = a_bIsAlphaBlendMaterial;
337}
338
340{
341 Validate();
342
343 auto pMaterial = new AWorldMaterialHAL();
344 pMaterial->SetShader( this );
345
347 {
348 auto pAlphaBlendMaterial = new AWorldMaterialHAL();
349 pAlphaBlendMaterial->SetShader( this );
350 pAlphaBlendMaterial->Create( 1 );
351
352 pMaterial->SetAlphaBlendMaterial( pAlphaBlendMaterial );
353 }
354
355 return pMaterial;
356}
357
359{
360 Validate();
361
362 auto pMesh = new AWorldMeshHAL();
363 pMesh->SetOwnerShader( this );
364
365 return pMesh;
366}
367
369{
370 return m_bIsHighEndMode;
371}
372
374{
375 m_bIsHighEndMode = a_bEnable && IsCapableShaders();
376}
377
379{
380 D3DCAPS8 caps;
381
382 auto pRenderInterface = TRenderD3DInterface::Interface();
383 auto pDevice = pRenderInterface->GetDirect3DDevice();
384
385 if ( !pDevice )
386 {
387 auto pDirect3D = pRenderInterface->GetDirect3D();
388
389 TVALIDPTR( pDirect3D );
390 if ( !pDirect3D ) return TFALSE;
391
392 pDirect3D->GetDeviceCaps( 0, D3DDEVTYPE_HAL, &caps );
393 }
394 else
395 {
396 pDevice->GetDeviceCaps( &caps );
397 }
398
399 return ( ( caps.VertexShaderVersion & 0xFFFF ) > 256 ) && ( caps.DevCaps & 0x10000 );
400}
401
403{
404 return m_bRenderEnvMap;
405}
406
407void* AWorldShaderHAL::CreateUnknown( void*, void*, void*, void* )
408{
409 TASSERT( !"What's this?" );
410 return TNULL;
411}
412
413void AWorldShaderHAL::SetColours( const Toshi::TVector4& a_rShadowColour, const Toshi::TVector4 a_rAmbientColour )
414{
415 m_ShadowColour = a_rShadowColour;
416 m_AmbientColour = a_rAmbientColour;
417
418 Toshi::TMath::Clip( m_ShadowColour.x, 0.0f, 1.0f );
419 Toshi::TMath::Clip( m_ShadowColour.y, 0.0f, 1.0f );
420 Toshi::TMath::Clip( m_ShadowColour.z, 0.0f, 1.0f );
421 Toshi::TMath::Clip( m_AmbientColour.x, 0.0f, 1.0f );
422 Toshi::TMath::Clip( m_AmbientColour.y, 0.0f, 1.0f );
423 Toshi::TMath::Clip( m_AmbientColour.z, 0.0f, 1.0f );
424}
425
426void AWorldShaderHAL::SetupLowEndMode()
427{
428 auto pRenderInterface = TRenderD3DInterface::Interface();
429 auto pCurrentContext = TRenderContextD3D::Upcast( pRenderInterface->GetCurrentContext() );
430 auto pDevice = pRenderInterface->GetDirect3DDevice();
431
432 pDevice->SetVertexShader( D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_NORMAL | D3DFVF_XYZ );
433 pDevice->SetPixelShader( NULL );
434 pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
435 pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
436 pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
437 pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
438 pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
439 pDevice->SetRenderState( D3DRS_SRCBLEND, 5 );
440 pDevice->SetRenderState( D3DRS_DESTBLEND, 6 );
441 pDevice->SetRenderState( D3DRS_ALPHAFUNC, 5 );
442
443 DWORD dwWasSpecularEnabled;
444 pDevice->GetRenderState( D3DRS_SPECULARENABLE, &dwWasSpecularEnabled );
445 pDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
446
447 pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, 4 );
448 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, 2 );
449 pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, 0 );
450 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, 4 );
451 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, 2 );
452 pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, 0 );
453 pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, 1 );
454 pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, 1 );
455
456 pDevice->SetRenderState( D3DRS_CULLMODE, m_bRenderEnvMap ? D3DCULL_CCW : D3DCULL_CW );
457
458 static TMatrix44 s_IdentityMatrix = TMatrix44::IDENTITY;
459
460 pDevice->SetTransform( D3DTS_VIEW, s_IdentityMatrix );
461 pDevice->SetTransform( D3DTS_PROJECTION, pCurrentContext->GetProjectionMatrix() );
462 pDevice->SetRenderState( D3DRS_SPECULARENABLE, dwWasSpecularEnabled );
463 pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
464}
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TOSHI_NAMESPACE_USING
Definition Defines.h:46
#define ISZERO(X)
Definition Defines.h:3
#define TVALIDPTR(PTR)
Definition Defines.h:139
#define TDEFINE_CLASS(...)
Definition TObject.h:120
char TCHAR
Definition Typedefs.h:20
uint8_t TUINT8
Definition Typedefs.h:17
#define TNULL
Definition Typedefs.h:23
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
static constinit TMatrix44 IDENTITY
Definition TMatrix44.h:357
TFLOAT w
Definition TVector4.h:367
TFLOAT x
Definition TVector4.h:367
TFLOAT y
Definition TVector4.h:367
TFLOAT z
Definition TVector4.h:367
static TRenderContextD3D * Upcast(TRenderContext *a_pRenderContext)
static TBOOL CreateVertexShader(const DWORD *a_ShaderDeclaration, const DWORD *a_pFunction, DWORD *a_pOutVertexShader)
Creates a vertex shader.
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]
TFLOAT GetAlpha() const
TMatrix44 & GetModelViewMatrix()
TMesh * GetMesh() const
virtual void Invalidate()
Definition TShader.cpp:46
virtual TBOOL TryInvalidate() override
virtual void SetAlphaBlendMaterial(TBOOL a_bIsAlphaBlendMaterial) override
virtual void * CreateUnknown(void *, void *, void *, void *)
virtual void StartFlush() override
virtual TBOOL Validate() override
virtual void SetHighEndMode(TBOOL a_bEnable)
virtual void Flush() override
virtual void EndFlush() override
virtual TBOOL Create() override
virtual void Render(Toshi::TRenderPacket *a_pRenderPacket) override
virtual TBOOL IsHighEndMode()
virtual AWorldMaterial * CreateMaterial(const TCHAR *a_szName) override
virtual TBOOL TryValidate() override
virtual TBOOL IsAlphaBlendMaterial() override
virtual void Invalidate() override
void SetColours(const Toshi::TVector4 &a_rShadowColour, const Toshi::TVector4 a_rAmbientColour)
virtual void EnableRenderEnvMap(TBOOL a_bEnable) override
virtual AWorldMesh * CreateMesh(const TCHAR *a_szName) override
virtual TBOOL IsRenderEnvMapEnabled()
virtual TBOOL IsCapableShaders()
static TUINT s_RenderStateFlags