Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
dx8wrapper.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/dx8wrapper.cpp $*
26 * *
27 * Original Author:: Jani Penttinen *
28 * *
29 * $Author:: Kenny Mitchell *
30 * *
31 * $Modtime:: 08/05/02 1:27p $*
32 * *
33 * $Revision:: 170 $*
34 * *
35 * 06/26/02 KM Matrix name change to avoid MAX conflicts *
36 * 06/27/02 KM Render to shadow buffer texture support *
37 * 06/27/02 KM Shader system updates *
38 * 08/05/02 KM Texture class redesign
39 *---------------------------------------------------------------------------------------------*
40 * Functions: *
41 * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory *
42 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
43
44//#define CREATE_DX8_MULTI_THREADED
45//#define CREATE_DX8_FPU_PRESERVE
46#define WW3D_DEVTYPE D3DDEVTYPE_HAL
47
48#include "dx8wrapper.h"
49#include "dx8webbrowser.h"
50#include "dx8fvf.h"
51#include "dx8vertexbuffer.h"
52#include "dx8indexbuffer.h"
53#include "dx8renderer.h"
54#include "ww3d.h"
55#include "camera.h"
56#include "wwstring.h"
57#include "matrix4.h"
58#include "vertmaterial.h"
59#include "rddesc.h"
60#include "lightenvironment.h"
61#include "statistics.h"
62#include "registry.h"
63#include "boxrobj.h"
64#include "pointgr.h"
65#include "render2d.h"
66#include "sortingrenderer.h"
67#include "shattersystem.h"
68#include "light.h"
69#include "assetmgr.h"
70#include "textureloader.h"
71#include "missingtexture.h"
72#include "thread.h"
73#include <stdio.h>
74#include <D3dx8core.h>
75#include "pot.h"
76#include "wwprofile.h"
77#include "ffactory.h"
78#include "dx8caps.h"
79#include "formconv.h"
80#include "dx8texman.h"
81#include "bound.h"
82#include "dx8webbrowser.h"
83
84#include "shdlib.h"
85
88const int DEFAULT_BIT_DEPTH = 32;
90
92
93// FPU_PRESERVE
95
96/***********************************************************************************
97**
98** DX8Wrapper Static Variables
99**
100***********************************************************************************/
101
102static HWND _Hwnd = NULL;
103bool DX8Wrapper::IsInitted = false;
105
111bool DX8Wrapper::IsWindowed = false;
112D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN;
113
114D3DMATRIX DX8Wrapper::old_world;
115D3DMATRIX DX8Wrapper::old_view;
116D3DMATRIX DX8Wrapper::old_prj;
117
118// shader system additions KJM v
121
124
127
130
132// shader system additions KJM ^
133
135unsigned DX8Wrapper::RenderStates[256];
137IDirect3DBaseTexture8 * DX8Wrapper::Textures[MAX_TEXTURE_STAGES];
140
141bool DX8Wrapper::FogEnable = false;
142D3DCOLOR DX8Wrapper::FogColor = 0;
143
144IDirect3D8 * DX8Wrapper::D3DInterface = NULL;
145IDirect3DDevice8 * DX8Wrapper::D3DDevice = NULL;
146IDirect3DSurface8 * DX8Wrapper::CurrentRenderTarget = NULL;
147IDirect3DSurface8 * DX8Wrapper::CurrentDepthBuffer = NULL;
148IDirect3DSurface8 * DX8Wrapper::DefaultRenderTarget = NULL;
149IDirect3DSurface8 * DX8Wrapper::DefaultDepthBuffer = NULL;
151
152unsigned DX8Wrapper::matrix_changes = 0;
156unsigned DX8Wrapper::light_changes = 0;
157unsigned DX8Wrapper::texture_changes = 0;
160unsigned DX8Wrapper::draw_calls = 0;
161unsigned DX8Wrapper::_MainThreadID = 0;
166float DX8Wrapper::ZFar;
169
171
172// Hack test... this disables rendering of batches of too few polygons.
174
175D3DADAPTER_IDENTIFIER8 DX8Wrapper::CurrentAdapterIdentifier;
176
177unsigned long DX8Wrapper::FrameCount = 0;
178
180
182static unsigned last_frame_matrix_changes = 0;
183static unsigned last_frame_material_changes = 0;
184static unsigned last_frame_vertex_buffer_changes = 0;
185static unsigned last_frame_index_buffer_changes = 0;
186static unsigned last_frame_light_changes = 0;
187static unsigned last_frame_texture_changes = 0;
188static unsigned last_frame_render_state_changes = 0;
189static unsigned last_frame_texture_stage_state_changes = 0;
190static unsigned last_frame_number_of_DX8_calls = 0;
191static unsigned last_frame_draw_calls = 0;
192
193static D3DDISPLAYMODE DesktopMode;
194
195static D3DPRESENT_PARAMETERS _PresentParameters;
196static DynamicVectorClass<StringClass> _RenderDeviceNameTable;
197static DynamicVectorClass<StringClass> _RenderDeviceShortNameTable;
198static DynamicVectorClass<RenderDeviceDescClass> _RenderDeviceDescriptionTable;
199
200
201typedef IDirect3D8* (WINAPI *Direct3DCreate8Type) (UINT SDKVersion);
203HINSTANCE D3D8Lib = NULL;
204
206#ifdef EXTENDED_STATS
207DX8_Stats DX8Wrapper::stats;
208#endif
209/***********************************************************************************
210**
211** DX8Wrapper Implementation
212**
213***********************************************************************************/
214
215void Log_DX8_ErrorCode(unsigned res)
216{
217 char tmp[256]="";
218
219 HRESULT new_res=D3DXGetErrorStringA(
220 res,
221 tmp,
222 sizeof(tmp));
223
224 if (new_res==D3D_OK) {
225 WWDEBUG_SAY((tmp));
226 }
227
228 WWASSERT(0);
229}
230
231void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line)
232{
233 char tmp[256]="";
234
235 HRESULT new_res=D3DXGetErrorStringA(
236 res,
237 tmp,
238 sizeof(tmp));
239
240 if (new_res==D3D_OK) {
241 WWDEBUG_SAY(("DX8 Error: %s, File: %s, Line: %d\n",tmp,file,line));
242 }
243}
244
245
246
247bool DX8Wrapper::Init(void * hwnd, bool lite)
248{
250
251 // zero memory
252 memset(Textures,0,sizeof(IDirect3DBaseTexture8*)*MAX_TEXTURE_STAGES);
253 memset(RenderStates,0,sizeof(unsigned)*256);
254 memset(TextureStageStates,0,sizeof(unsigned)*32*MAX_TEXTURE_STAGES);
257 memset(&render_state,0,sizeof(RenderStateStruct));
258 memset(Shadow_Map,0,sizeof(ZTextureClass*)*MAX_SHADOW_MAPS);
259
260 /*
261 ** Initialize all variables!
262 */
263 _Hwnd = (HWND)hwnd;
265 WWDEBUG_SAY(("DX8Wrapper main thread: 0x%x\n",_MainThreadID));
266 CurRenderDevice = -1;
269 // Initialize Render2DClass Screen Resolution
272 IsWindowed = false;
273 DX8Wrapper_IsWindowed = false;
274
275 for (int light=0;light<4;++light) CurrentDX8LightEnables[light]=false;
276
277 ::ZeroMemory(&old_world, sizeof(D3DMATRIX));
278 ::ZeroMemory(&old_view, sizeof(D3DMATRIX));
279 ::ZeroMemory(&old_prj, sizeof(D3DMATRIX));
280
281 //old_vertex_shader; TODO
282 //old_sr_shader;
283 //current_shader;
284
285 //world_identity;
286 //CurrentFogColor;
287
289 D3DDevice = NULL;
290
291 WWDEBUG_SAY(("Reset DX8Wrapper statistics\n"));
293
295
296 if (!lite) {
297 D3D8Lib = LoadLibrary("D3D8.DLL");
298
299 if (D3D8Lib == NULL) return false; // Return false at this point if init failed
300
301 Direct3DCreate8Ptr = (Direct3DCreate8Type) GetProcAddress(D3D8Lib, "Direct3DCreate8");
302 if (Direct3DCreate8Ptr == NULL) return false;
303
304 /*
305 ** Create the D3D interface object
306 */
307 WWDEBUG_SAY(("Create Direct3D8\n"));
308 D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
309 if (D3DInterface == NULL) {
310 return(false);
311 }
312 IsInitted = true;
313
314 /*
315 ** Enumerate the available devices
316 */
317 WWDEBUG_SAY(("Enumerate devices\n"));
319 WWDEBUG_SAY(("DX8Wrapper Init completed\n"));
320 }
321
322 return(true);
323}
324
326{
327 if (D3DDevice) {
328
329 Set_Render_Target ((IDirect3DSurface8 *)NULL);
331 }
332
333 if (D3DInterface) {
334 D3DInterface->Release();
336
337 }
338
339 if (CurrentCaps)
340 {
341 int max=CurrentCaps->Get_Max_Textures_Per_Pass();
342 for (int i = 0; i < max; i++)
343 {
344 if (Textures[i])
345 {
346 Textures[i]->Release();
347 Textures[i] = NULL;
348 }
349 }
350 }
351
352 if (D3DInterface) {
353 UINT newRefCount=D3DInterface->Release();
355 }
356
357 if (D3D8Lib) {
358 FreeLibrary(D3D8Lib);
359 D3D8Lib = NULL;
360 }
361
362 _RenderDeviceNameTable.Clear(); // note - Delete_All() resizes the vector, causing a reallocation. Clear is better. jba.
363 _RenderDeviceShortNameTable.Clear();
364 _RenderDeviceDescriptionTable.Clear();
365
367 IsInitted = false; // 010803 srj
368}
369
371{
372 /*
373 ** Set Global render states (some of which depend on caps)
374 */
376
377 /*
378 ** Initalize any other subsystems inside of WW3D
379 */
382 TheDX8MeshRenderer.Init();
383 SHD_INIT;
386 PointGroupClass::_Init(); // This needs the VertexMaterialClass to be initted
389
391}
392
393inline DWORD F2DW(float f) { return *((unsigned*)&f); }
395{
397 const D3DCAPS8 &caps = Get_Current_Caps()->Get_DX8_Caps();
398
399 Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, (caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE) ? TRUE : FALSE);
400 Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
401 Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
402 Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
403 Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE);
404 Set_DX8_Render_State(D3DRS_ZBIAS,0);
405 Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLSCALE, F2DW(1.0f));
406 Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f));
407 Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT00,F2DW(1.0f));
408 Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT01,F2DW(0.0f));
409 Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT10,F2DW(0.0f));
410 Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT11,F2DW(1.0f));
411
412// Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW);
413 // Set dither mode here?
414}
415
416//MW: I added this for 'Generals'.
418{ DWORD numPasses=0;
419 HRESULT hRes;
420
421 hRes=_Get_D3D_Device8()->ValidateDevice(&numPasses);
422
423 return (hRes == D3D_OK);
424}
425
427{
429
430 int a;
431 for (a=0;a<sizeof(RenderStates)/sizeof(unsigned);++a) {
432 RenderStates[a]=0x12345678;
433 }
434 for (a=0;a<MAX_TEXTURE_STAGES;++a)
435 {
436 for (int b=0; b<32;b++)
437 {
438 TextureStageStates[a][b]=0x12345678;
439 }
440 //Need to explicitly set texture to NULL, otherwise app will not be able to
441 //set it to null because of redundant state checker. MW
442 if (_Get_D3D_Device8())
443 _Get_D3D_Device8()->SetTexture(a,NULL);
444 if (Textures[a] != NULL) {
445 Textures[a]->Release();
446 }
447 Textures[a]=NULL;
448 }
449
451
452 //Need to explicitly set render_state texture pointers to NULL. MW
454
455 // (gth) clear the matrix shadows too
456 for (int i=0; i<D3DTS_WORLD+1; i++) {
457 DX8Transforms[i][0].Set(0,0,0,0);
458 DX8Transforms[i][1].Set(0,0,0,0);
459 DX8Transforms[i][2].Set(0,0,0,0);
460 DX8Transforms[i][3].Set(0,0,0,0);
461 }
462
463}
464
466{
467 /*
468 ** Shutdown ww3d systems
469 */
470 int i;
471 for (i=0;i<MAX_VERTEX_STREAMS;++i) {
472 if (render_state.vertex_buffers[i]) render_state.vertex_buffers[i]->Release_Engine_Ref();
473 REF_PTR_RELEASE(render_state.vertex_buffers[i]);
474 }
475 if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
476 REF_PTR_RELEASE(render_state.index_buffer);
478 for (i=0;i<CurrentCaps->Get_Max_Textures_Per_Pass();++i) REF_PTR_RELEASE(render_state.Textures[i]);
479
480
490 TheDX8MeshRenderer.Shutdown();
492
493 if (CurrentCaps) {
494 delete CurrentCaps;
496 }
497
498}
499
500
502{
503 WWASSERT(D3DDevice==NULL); // for now, once you've created a device, you're stuck with it!
504
505 D3DCAPS8 caps;
506 if
507 (
508 FAILED
509 (
510 D3DInterface->GetDeviceCaps
511 (
514 &caps
515 )
516 )
517 )
518 {
519 return false;
520 }
521
522 ::ZeroMemory(&CurrentAdapterIdentifier, sizeof(D3DADAPTER_IDENTIFIER8));
523
524 if
525 (
526 FAILED
527 (
528 D3DInterface->GetAdapterIdentifier
529 (
531 D3DENUM_NO_WHQL_LEVEL,
533 )
534 )
535 )
536 {
537 return false;
538 }
539
540#ifndef _XBOX
541
542 Vertex_Processing_Behavior=(caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
543 D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
544
545 // enable this when all 'get' dx calls are removed KJM
546 /*if (caps.DevCaps&D3DDEVCAPS_PUREDEVICE)
547 {
548 Vertex_Processing_Behavior|=D3DCREATE_PUREDEVICE;
549 }*/
550
551#else // XBOX
552 Vertex_Processing_Behavior=D3DCREATE_PUREDEVICE;
553#endif // XBOX
554
555#ifdef CREATE_DX8_MULTI_THREADED
556 Vertex_Processing_Behavior|=D3DCREATE_MULTITHREADED;
557 _DX8SingleThreaded=false;
558#else
560#endif
561
563 Vertex_Processing_Behavior |= D3DCREATE_FPU_PRESERVE;
564
565#ifdef CREATE_DX8_FPU_PRESERVE
566 Vertex_Processing_Behavior|=D3DCREATE_FPU_PRESERVE;
567#endif
568
569 HRESULT hr=D3DInterface->CreateDevice
570 (
573 _Hwnd,
575 &_PresentParameters,
576 &D3DDevice
577 );
578
579 if (FAILED(hr))
580 {
581 // The device selection may fail because the device lied that it supports 32 bit zbuffer with 16 bit
582 // display. This happens at least on Voodoo2.
583
584 if ((_PresentParameters.BackBufferFormat==D3DFMT_R5G6B5 ||
585 _PresentParameters.BackBufferFormat==D3DFMT_X1R5G5B5 ||
586 _PresentParameters.BackBufferFormat==D3DFMT_A1R5G5B5) &&
587 (_PresentParameters.AutoDepthStencilFormat==D3DFMT_D32 ||
588 _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24S8 ||
589 _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24X8))
590 {
591 _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16;
592 hr = D3DInterface->CreateDevice
593 (
596 _Hwnd,
598 &_PresentParameters,
599 &D3DDevice
600 );
601
602 if (FAILED(hr))
603 {
604 return false;
605 }
606 }
607 else
608 {
609 return false;
610 }
611 }
612
613 /*
614 ** Initialize all subsystems
615 */
617 return true;
618}
619
620bool DX8Wrapper::Reset_Device(bool reload_assets)
621{
622 WWDEBUG_SAY(("Resetting device.\n"));
624 if ((IsInitted) && (D3DDevice != NULL)) {
625 // Release all non-MANAGED stuff
627
628 for (unsigned i=0;i<MAX_VERTEX_STREAMS;++i)
629 {
631 }
633 if (m_pCleanupHook) {
634 m_pCleanupHook->ReleaseResources();
635 }
640
641 // Reset frame count to reflect the flipping chain being reset by Reset()
642 FrameCount = 0;
643
646
647 HRESULT hr=_Get_D3D_Device8()->TestCooperativeLevel();
648 if (hr != D3DERR_DEVICELOST )
649 { DX8CALL_HRES(Reset(&_PresentParameters),hr)
650 if (hr != D3D_OK)
651 return false; //reset failed.
652 }
653 else
654 return false; //device is lost and can't be reset.
655
656 if (reload_assets)
657 {
659 if (m_pCleanupHook) {
660 m_pCleanupHook->ReAcquireResources();
661 }
662 }
666 WWDEBUG_SAY(("Device reset completed\n"));
667 return true;
668 }
669 WWDEBUG_SAY(("Device reset failed\n"));
670 return false;
671}
672
674{
675 if (D3DDevice) {
676
677 for (int a=0;a<MAX_TEXTURE_STAGES;++a)
678 { //release references to any textures that were used in last rendering call
679 DX8CALL(SetTexture(a,NULL));
680 }
681
682 DX8CALL(SetStreamSource(0, NULL, 0)); //release reference count on last rendered vertex buffer
683 DX8CALL(SetIndices(NULL,0)); //release reference count on last rendered index buffer
684
685
686 /*
687 ** Release the current vertex and index buffers
688 */
689 for (unsigned i=0;i<MAX_VERTEX_STREAMS;++i)
690 {
691 if (render_state.vertex_buffers[i]) render_state.vertex_buffers[i]->Release_Engine_Ref();
692 REF_PTR_RELEASE(render_state.vertex_buffers[i]);
693 }
694 if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
695 REF_PTR_RELEASE(render_state.index_buffer);
696
697 /*
698 ** Shutdown all subsystems
699 */
701
702 /*
703 ** Release the device
704 */
705
706 D3DDevice->Release();
708 }
709}
710
713 DX8_Assert();
714
715 int adapter_count = D3DInterface->GetAdapterCount();
716 for (int adapter_index=0; adapter_index<adapter_count; adapter_index++) {
717
718 D3DADAPTER_IDENTIFIER8 id;
719 ::ZeroMemory(&id, sizeof(D3DADAPTER_IDENTIFIER8));
720 HRESULT res = D3DInterface->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&id);
721
722 if (res == D3D_OK) {
723
724 /*
725 ** Set up the render device description
726 ** TODO: Fill in more fields of the render device description? (need some lookup tables)
727 */
729 desc.set_device_name(id.Description);
730 desc.set_driver_name(id.Driver);
731
732 char buf[64];
733 sprintf(buf,"%d.%d.%d.%d", //"%04x.%04x.%04x.%04x",
734 HIWORD(id.DriverVersion.HighPart),
735 LOWORD(id.DriverVersion.HighPart),
736 HIWORD(id.DriverVersion.LowPart),
737 LOWORD(id.DriverVersion.LowPart));
738
739 desc.set_driver_version(buf);
740
741 D3DInterface->GetDeviceCaps(adapter_index,WW3D_DEVTYPE,&desc.Caps);
742 D3DInterface->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&desc.AdapterIdentifier);
743
744 DX8Caps dx8caps(D3DInterface,desc.Caps,WW3D_FORMAT_UNKNOWN,desc.AdapterIdentifier);
745
746 /*
747 ** Enumerate the resolutions
748 */
749 desc.reset_resolution_list();
750 int mode_count = D3DInterface->GetAdapterModeCount(adapter_index);
751 for (int mode_index=0; mode_index<mode_count; mode_index++) {
752 D3DDISPLAYMODE d3dmode;
753 ::ZeroMemory(&d3dmode, sizeof(D3DDISPLAYMODE));
754 HRESULT res = D3DInterface->EnumAdapterModes(adapter_index,mode_index,&d3dmode);
755
756 if (res == D3D_OK) {
757 int bits = 0;
758 switch (d3dmode.Format)
759 {
760 case D3DFMT_R8G8B8:
761 case D3DFMT_A8R8G8B8:
762 case D3DFMT_X8R8G8B8: bits = 32; break;
763
764 case D3DFMT_R5G6B5:
765 case D3DFMT_X1R5G5B5: bits = 16; break;
766 }
767
768 // Some cards fail in certain modes, DX8Caps keeps list of those.
769 if (!dx8caps.Is_Valid_Display_Format(d3dmode.Width,d3dmode.Height,D3DFormat_To_WW3DFormat(d3dmode.Format))) {
770 bits=0;
771 }
772
773 /*
774 ** If we recognize the format, add it to the list
775 ** TODO: should we handle more formats? will any cards report more than 24 or 16 bit?
776 */
777 if (bits != 0) {
778 desc.add_resolution(d3dmode.Width,d3dmode.Height,bits);
779 }
780 }
781 }
782
783 // IML: If the device has one or more valid resolutions add it to the device list.
784 // NOTE: Testing has shown that there are drivers with zero resolutions.
785 if (desc.Enumerate_Resolutions().Count() > 0) {
786
787 /*
788 ** Set up the device name
789 */
790 StringClass device_name(id.Description,true);
791 _RenderDeviceNameTable.Add(device_name);
792 _RenderDeviceShortNameTable.Add(device_name); // for now, just add the same name to the "pretty name table"
793
794 /*
795 ** Add the render device to our table
796 */
797 _RenderDeviceDescriptionTable.Add(desc);
798 }
799 }
800 }
801}
802
804{
805 // Then fullscreen
806 for (int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
807 if (Set_Render_Device(dev_number,-1,-1,-1,0,false)) {
808 return true;
809 }
810 }
811
812 // Try windowed first
813 for (dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
814 if (Set_Render_Device(dev_number,-1,-1,-1,1,false)) {
815 return true;
816 }
817 }
818
819 return false;
820}
821
823(
824 const char * dev_name,
825 int width,
826 int height,
827 int bits,
828 int windowed,
829 bool resize_window
830)
831{
832 for ( int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
833 if ( strcmp( dev_name, _RenderDeviceNameTable[dev_number]) == 0) {
834 return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window );
835 }
836
837 if ( strcmp( dev_name, _RenderDeviceShortNameTable[dev_number]) == 0) {
838 return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window );
839 }
840 }
841 return false;
842}
843
844void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass *tex_format)
845{
846 *tex_format="Unknown";
847 switch (format) {
848 case D3DFMT_A8R8G8B8: *tex_format="D3DFMT_A8R8G8B8"; break;
849 case D3DFMT_R8G8B8: *tex_format="D3DFMT_R8G8B8"; break;
850 case D3DFMT_A4R4G4B4: *tex_format="D3DFMT_A4R4G4B4"; break;
851 case D3DFMT_A1R5G5B5: *tex_format="D3DFMT_A1R5G5B5"; break;
852 case D3DFMT_R5G6B5: *tex_format="D3DFMT_R5G6B5"; break;
853 case D3DFMT_L8: *tex_format="D3DFMT_L8"; break;
854 case D3DFMT_A8: *tex_format="D3DFMT_A8"; break;
855 case D3DFMT_P8: *tex_format="D3DFMT_P8"; break;
856 case D3DFMT_X8R8G8B8: *tex_format="D3DFMT_X8R8G8B8"; break;
857 case D3DFMT_X1R5G5B5: *tex_format="D3DFMT_X1R5G5B5"; break;
858 case D3DFMT_R3G3B2: *tex_format="D3DFMT_R3G3B2"; break;
859 case D3DFMT_A8R3G3B2: *tex_format="D3DFMT_A8R3G3B2"; break;
860 case D3DFMT_X4R4G4B4: *tex_format="D3DFMT_X4R4G4B4"; break;
861 case D3DFMT_A8P8: *tex_format="D3DFMT_A8P8"; break;
862 case D3DFMT_A8L8: *tex_format="D3DFMT_A8L8"; break;
863 case D3DFMT_A4L4: *tex_format="D3DFMT_A4L4"; break;
864 case D3DFMT_V8U8: *tex_format="D3DFMT_V8U8"; break;
865 case D3DFMT_L6V5U5: *tex_format="D3DFMT_L6V5U5"; break;
866 case D3DFMT_X8L8V8U8: *tex_format="D3DFMT_X8L8V8U8"; break;
867 case D3DFMT_Q8W8V8U8: *tex_format="D3DFMT_Q8W8V8U8"; break;
868 case D3DFMT_V16U16: *tex_format="D3DFMT_V16U16"; break;
869 case D3DFMT_W11V11U10: *tex_format="D3DFMT_W11V11U10"; break;
870 case D3DFMT_UYVY: *tex_format="D3DFMT_UYVY"; break;
871 case D3DFMT_YUY2: *tex_format="D3DFMT_YUY2"; break;
872 case D3DFMT_DXT1: *tex_format="D3DFMT_DXT1"; break;
873 case D3DFMT_DXT2: *tex_format="D3DFMT_DXT2"; break;
874 case D3DFMT_DXT3: *tex_format="D3DFMT_DXT3"; break;
875 case D3DFMT_DXT4: *tex_format="D3DFMT_DXT4"; break;
876 case D3DFMT_DXT5: *tex_format="D3DFMT_DXT5"; break;
877 case D3DFMT_D16_LOCKABLE: *tex_format="D3DFMT_D16_LOCKABLE"; break;
878 case D3DFMT_D32: *tex_format="D3DFMT_D32"; break;
879 case D3DFMT_D15S1: *tex_format="D3DFMT_D15S1"; break;
880 case D3DFMT_D24S8: *tex_format="D3DFMT_D24S8"; break;
881 case D3DFMT_D16: *tex_format="D3DFMT_D16"; break;
882 case D3DFMT_D24X8: *tex_format="D3DFMT_D24X8"; break;
883 case D3DFMT_D24X4S4: *tex_format="D3DFMT_D24X4S4"; break;
884 default: break;
885 }
886}
887
888bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed,
889 bool resize_window,bool reset_device, bool restore_assets)
890{
892 WWASSERT(dev >= -1);
893 WWASSERT(dev < _RenderDeviceNameTable.Count());
894
895 /*
896 ** If user has never selected a render device, start out with device 0
897 */
898 if ((CurRenderDevice == -1) && (dev == -1)) {
899 CurRenderDevice = 0;
900 } else if (dev != -1) {
901 CurRenderDevice = dev;
902 }
903
904 /*
905 ** If user doesn't want to change res, set the res variables to match the
906 ** current resolution
907 */
908 if (width != -1) ResolutionWidth = width;
909 if (height != -1) ResolutionHeight = height;
910
911 // Initialize Render2DClass Screen Resolution
913
914 if (bits != -1) BitDepth = bits;
915 if (windowed != -1) IsWindowed = (windowed != 0);
917
918 WWDEBUG_SAY(("Attempting Set_Render_Device: name: %s (%s:%s), width: %d, height: %d, windowed: %d\n",
919 _RenderDeviceNameTable[CurRenderDevice],_RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Name(),
920 _RenderDeviceDescriptionTable[CurRenderDevice].Get_Driver_Version(),ResolutionWidth,ResolutionHeight,(IsWindowed ? 1 : 0)));
921
922#ifdef _WINDOWS
923 // PWG 4/13/2000 - changed so that if you say to resize the window it resizes
924 // regardless of whether its windowed or not as OpenGL resizes its self around
925 // the caption and edges of the window type you provide, so its important to
926 // push the client area to be the size you really want.
927 // if ( resize_window && windowed ) {
928 if (resize_window) {
929
930 // Get the current dimensions of the 'render area' of the window
931 RECT rect = { 0 };
932 ::GetClientRect (_Hwnd, &rect);
933
934 // Is the window the correct size for this resolution?
935 if ((rect.right-rect.left) != ResolutionWidth ||
936 (rect.bottom-rect.top) != ResolutionHeight) {
937
938 // Calculate what the main window's bounding rectangle should be to
939 // accomodate this resolution
940 rect.left = 0;
941 rect.top = 0;
942 rect.right = ResolutionWidth;
943 rect.bottom = ResolutionHeight;
944 DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
945 AdjustWindowRect (&rect, dwstyle, FALSE);
946
947 // Resize the window to fit this resolution
948 if (!windowed)
949 ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE);
950 else
951 ::SetWindowPos (_Hwnd,
952 NULL,
953 0,
954 0,
955 rect.right-rect.left,
956 rect.bottom-rect.top,
957 SWP_NOZORDER | SWP_NOMOVE);
958 }
959 }
960#endif
961 //must be either resetting existing device or creating a new one.
962 WWASSERT(reset_device || D3DDevice == NULL);
963
964 /*
965 ** Initialize values for D3DPRESENT_PARAMETERS members.
966 */
967 ::ZeroMemory(&_PresentParameters, sizeof(D3DPRESENT_PARAMETERS));
968
969 _PresentParameters.BackBufferWidth = ResolutionWidth;
970 _PresentParameters.BackBufferHeight = ResolutionHeight;
971 _PresentParameters.BackBufferCount = IsWindowed ? 1 : 2;
972
973 _PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
974 //I changed this to discard all the time (even when full-screen) since that the most efficient. 07-16-03 MW:
975 _PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;//IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP?
976 _PresentParameters.hDeviceWindow = _Hwnd;
977 _PresentParameters.Windowed = IsWindowed;
978
979 _PresentParameters.EnableAutoDepthStencil = TRUE; // Driver will attempt to match Z-buffer depth
980 _PresentParameters.Flags=0; // We're not going to lock the backbuffer
981
982 _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
983 _PresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
984
985 /*
986 ** Set up the buffer formats. Several issues here:
987 ** - if in windowed mode, the backbuffer must use the current display format.
988 ** - the depth buffer must use
989 */
990 if (IsWindowed) {
991
992 D3DDISPLAYMODE desktop_mode;
993 ::ZeroMemory(&desktop_mode, sizeof(D3DDISPLAYMODE));
994 D3DInterface->GetAdapterDisplayMode( CurRenderDevice, &desktop_mode );
995
996 DisplayFormat=_PresentParameters.BackBufferFormat = desktop_mode.Format;
997
998 // In windowed mode, define the bitdepth from desktop mode (as it can't be changed)
999 switch (_PresentParameters.BackBufferFormat) {
1000 case D3DFMT_X8R8G8B8:
1001 case D3DFMT_A8R8G8B8:
1002 case D3DFMT_R8G8B8: BitDepth=32; break;
1003 case D3DFMT_A4R4G4B4:
1004 case D3DFMT_A1R5G5B5:
1005 case D3DFMT_R5G6B5: BitDepth=16; break;
1006 case D3DFMT_L8:
1007 case D3DFMT_A8:
1008 case D3DFMT_P8: BitDepth=8; break;
1009 default:
1010 // Unknown backbuffer format probably means the device can't do windowed
1011 return false;
1012 }
1013
1014 if (BitDepth==32 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,desktop_mode.Format,D3DFMT_A8R8G8B8, TRUE) == D3D_OK)
1015 { //promote 32-bit modes to include destination alpha
1016 _PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
1017 }
1018
1019 /*
1020 ** Find a appropriate Z buffer
1021 */
1022 if (!Find_Z_Mode(DisplayFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat))
1023 {
1024 // If opening 32 bit mode failed, try 16 bit, even if the desktop happens to be 32 bit
1025 if (BitDepth==32) {
1026 BitDepth=16;
1027 _PresentParameters.BackBufferFormat=D3DFMT_R5G6B5;
1028 if (!Find_Z_Mode(_PresentParameters.BackBufferFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) {
1029 _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN;
1030 }
1031 }
1032 else {
1033 _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN;
1034 }
1035 }
1036
1037 } else {
1038
1039 /*
1040 ** Try to find a mode that matches the user's desired bit-depth.
1041 */
1043 &_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat);
1044 }
1045
1046 /*
1047 ** Time to actually create the device.
1048 */
1049 if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) {
1050 if (BitDepth==32) {
1051 _PresentParameters.AutoDepthStencilFormat=D3DFMT_D32;
1052 }
1053 else {
1054 _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16;
1055 }
1056 }
1057
1058 StringClass displayFormat;
1059 StringClass backbufferFormat;
1060
1061 Get_Format_Name(DisplayFormat,&displayFormat);
1062 Get_Format_Name(_PresentParameters.BackBufferFormat,&backbufferFormat);
1063
1064 WWDEBUG_SAY(("Using Display/BackBuffer Formats: %s/%s\n",displayFormat,backbufferFormat));
1065
1066 bool ret;
1067
1068 if (reset_device)
1069 ret = Reset_Device(restore_assets); //reset device without restoring data - we're likely switching out of the app.
1070 else
1071 ret = Create_Device();
1072
1073 WWDEBUG_SAY(("Reset/Create_Device done, reset_device=%d, restore_assets=%d\n", reset_device, restore_assets));
1074
1075 return ret;
1076}
1077
1079{
1080 int new_dev = (CurRenderDevice + 1) % _RenderDeviceNameTable.Count();
1081 return Set_Render_Device(new_dev);
1082}
1083
1085{
1086#ifdef WW3D_DX8
1087 // State OK?
1088 assert (IsInitted);
1089 if (IsInitted) {
1090
1091 // Get information about the current render device's resolutions
1092 const RenderDeviceDescClass &render_device = Get_Render_Device_Desc ();
1093 const DynamicVectorClass<ResolutionDescClass> &resolutions = render_device.Enumerate_Resolutions ();
1094
1095 // Loop through all the resolutions supported by the current device.
1096 // If we aren't currently running under one of these resolutions,
1097 // then we should probably to the closest resolution before
1098 // toggling the windowed state.
1099 int curr_res = -1;
1100 for (int res = 0;
1101 (res < resolutions.Count ()) && (curr_res == -1);
1102 res ++) {
1103
1104 // Is this the resolution we are looking for?
1105 if ((resolutions[res].Width == ResolutionWidth) &&
1106 (resolutions[res].Height == ResolutionHeight) &&
1107 (resolutions[res].BitDepth == BitDepth)) {
1108 curr_res = res;
1109 }
1110 }
1111
1112 if (curr_res == -1) {
1113
1114 // We don't match any of the standard resolutions,
1115 // so set the first resolution and toggle the windowed state.
1116 return Set_Device_Resolution (resolutions[0].Width,
1117 resolutions[0].Height,
1118 resolutions[0].BitDepth,
1119 !IsWindowed, true);
1120 } else {
1121
1122 // Toggle the windowed state
1123 return Set_Device_Resolution (-1, -1, -1, !IsWindowed, true);
1124 }
1125 }
1126#endif //WW3D_DX8
1127
1128 return false;
1129}
1130
1132{
1133 switch (swap) {
1134 case 0: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break;
1135 case 1: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break;
1136 case 2: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_TWO; break;
1137 case 3: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_THREE; break;
1138 default: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break;
1139 }
1140
1141 Reset_Device();
1142}
1143
1145{
1146 return _PresentParameters.FullScreen_PresentationInterval;
1147}
1148
1150{
1151 bool has_stencil = (_PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 ||
1152 _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4);
1153 return has_stencil;
1154}
1155
1157{
1158 return _RenderDeviceNameTable.Count();
1159
1160}
1162{
1163 assert(IsInitted);
1164 return CurRenderDevice;
1165}
1166
1168{
1170
1171 if ((deviceidx == -1) && (CurRenderDevice == -1)) {
1172 CurRenderDevice = 0;
1173 }
1174
1175 // if the device index is -1 then we want the current device
1176 if (deviceidx == -1) {
1178 WWASSERT(CurRenderDevice < _RenderDeviceNameTable.Count());
1179 return _RenderDeviceDescriptionTable[CurRenderDevice];
1180 }
1181
1182 // We can only ask for multiple device information if the devices
1183 // have been detected.
1184 WWASSERT(deviceidx >= 0);
1185 WWASSERT(deviceidx < _RenderDeviceNameTable.Count());
1186 return _RenderDeviceDescriptionTable[deviceidx];
1187}
1188
1189const char * DX8Wrapper::Get_Render_Device_Name(int device_index)
1190{
1191 device_index = device_index % _RenderDeviceShortNameTable.Count();
1192 return _RenderDeviceShortNameTable[device_index];
1193}
1194
1195bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window)
1196{
1197 if (D3DDevice != NULL) {
1198
1199 if (width != -1) {
1200 _PresentParameters.BackBufferWidth = ResolutionWidth = width;
1201 }
1202 if (height != -1) {
1203 _PresentParameters.BackBufferHeight = ResolutionHeight = height;
1204 }
1205 if (resize_window)
1206 {
1207
1208 // Get the current dimensions of the 'render area' of the window
1209 RECT rect = { 0 };
1210 ::GetClientRect (_Hwnd, &rect);
1211
1212 // Is the window the correct size for this resolution?
1213 if ((rect.right-rect.left) != ResolutionWidth ||
1214 (rect.bottom-rect.top) != ResolutionHeight)
1215 {
1216
1217 // Calculate what the main window's bounding rectangle should be to
1218 // accomodate this resolution
1219 rect.left = 0;
1220 rect.top = 0;
1221 rect.right = ResolutionWidth;
1222 rect.bottom = ResolutionHeight;
1223 DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
1224 AdjustWindowRect (&rect, dwstyle, FALSE);
1225
1226 // Resize the window to fit this resolution
1227 if (!windowed)
1228 ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE);
1229 else
1230 ::SetWindowPos (_Hwnd,
1231 NULL,
1232 0,
1233 0,
1234 rect.right-rect.left,
1235 rect.bottom-rect.top,
1236 SWP_NOZORDER | SWP_NOMOVE);
1237 }
1238 }
1239#pragma message("TODO: support changing windowed status and changing the bit depth")
1240 return Reset_Device();
1241 } else {
1242 return false;
1243 }
1244}
1245
1246void DX8Wrapper::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
1247{
1249
1250 set_w = ResolutionWidth;
1251 set_h = ResolutionHeight;
1252 set_bits = BitDepth;
1253 set_windowed = IsWindowed;
1254
1255 return ;
1256}
1257
1258void DX8Wrapper::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
1259{
1261
1262 if (CurrentRenderTarget != NULL) {
1263 D3DSURFACE_DESC info;
1264 CurrentRenderTarget->GetDesc (&info);
1265
1266 set_w = info.Width;
1267 set_h = info.Height;
1268 set_bits = BitDepth; // should we get the actual bit depth of the target?
1269 set_windowed = IsWindowed; // this doesn't really make sense for render targets (shouldn't matter)...
1270
1271 } else {
1272 Get_Device_Resolution (set_w, set_h, set_bits, set_windowed);
1273 }
1274
1275 return ;
1276}
1277
1279{
1280 int width, height, depth;
1281 bool windowed;
1282 Get_Device_Resolution(width, height, depth, windowed);
1284}
1285
1286bool DX8Wrapper::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth)
1287{
1288 RegistryClass * registry = W3DNEW RegistryClass( sub_key );
1289 WWASSERT( registry );
1290
1291 if ( !registry->Is_Valid() ) {
1292 delete registry;
1293 WWDEBUG_SAY(( "Error getting Registry\n" ));
1294 return false;
1295 }
1296
1298 _RenderDeviceShortNameTable[device] );
1299 registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, width );
1300 registry->Set_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, height );
1301 registry->Set_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, depth );
1302 registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, windowed );
1303 registry->Set_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, texture_depth );
1304
1305 delete registry;
1306 return true;
1307}
1308
1309bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_window )
1310{
1311 char name[ 200 ];
1312 int width,height,depth,windowed;
1313
1314 if ( Registry_Load_Render_Device( sub_key,
1315 name,
1316 sizeof(name),
1317 width,
1318 height,
1319 depth,
1320 windowed,
1321 TextureBitDepth) &&
1322 (*name != 0))
1323 {
1324 WWDEBUG_SAY(( "Device %s (%d X %d) %d bit windowed:%d\n", name,width,height,depth,windowed));
1325
1326 if (TextureBitDepth==16 || TextureBitDepth==32) {
1327// WWDEBUG_SAY(( "Texture depth %d\n", TextureBitDepth));
1328 } else {
1329 WWDEBUG_SAY(( "Invalid texture depth %d, switching to 16 bits\n", TextureBitDepth));
1330 TextureBitDepth=16;
1331 }
1332
1333
1334// _RenderDeviceDescriptionTable.
1335
1336
1337 if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) {
1338 if (depth==16) depth=32;
1339 else depth=16;
1340 if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) {
1341 return true;
1342 }
1343 if (depth==16) depth=32;
1344 else depth=16;
1345 // we'll test resolutions down, so if start is 640, increase to begin with...
1346 if (width==640) {
1347 width=1024;
1348 height=768;
1349 }
1350 for(;;) {
1351 if (width>2048) {
1352 width=2048;
1353 height=1536;
1354 }
1355 else if (width>1920) {
1356 width=1920;
1357 height=1440;
1358 }
1359 else if (width>1600) {
1360 width=1600;
1361 height=1200;
1362 }
1363 else if (width>1280) {
1364 width=1280;
1365 height=1024;
1366 }
1367 else if (width>1024) {
1368 width=1024;
1369 height=768;
1370 }
1371 else if (width>800) {
1372 width=800;
1373 height=600;
1374 }
1375 else if (width!=640) {
1376 width=640;
1377 height=480;
1378 }
1379 else {
1380 return Set_Any_Render_Device();
1381 }
1382 for (int i=0;i<2;++i) {
1383 if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) {
1384 return true;
1385 }
1386 if (depth==16) depth=32;
1387 else depth=16;
1388 }
1389 }
1390 }
1391
1392 return true;
1393 }
1394
1395 WWDEBUG_SAY(( "Error getting Registry\n" ));
1396
1397 return Set_Any_Render_Device();
1398}
1399
1400bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth)
1401{
1402 RegistryClass registry( sub_key );
1403
1404 if ( registry.Is_Valid() ) {
1406 device, device_len);
1407
1408 width = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, -1 );
1409 height = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, -1 );
1410 depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, -1 );
1411 windowed = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, -1 );
1412 texture_depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, -1 );
1413 return true;
1414 }
1415 *device=0;
1416 width=-1;
1417 height=-1;
1418 depth=-1;
1419 windowed=-1;
1420 texture_depth=-1;
1421 return false;
1422}
1423
1424
1425bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer,D3DFORMAT * set_zmode)
1426{
1427 static D3DFORMAT _formats16[] =
1428 {
1429 D3DFMT_R5G6B5,
1430 D3DFMT_X1R5G5B5,
1431 D3DFMT_A1R5G5B5
1432 };
1433
1434 static D3DFORMAT _formats32[] =
1435 {
1436 D3DFMT_A8R8G8B8,
1437 D3DFMT_X8R8G8B8,
1438 D3DFMT_R8G8B8,
1439 };
1440
1441 /*
1442 ** Select the table that we're going to use to search for a valid backbuffer format
1443 */
1444 D3DFORMAT * format_table = NULL;
1445 int format_count = 0;
1446
1447 if (BitDepth == 16) {
1448 format_table = _formats16;
1449 format_count = sizeof(_formats16) / sizeof(D3DFORMAT);
1450 } else {
1451 format_table = _formats32;
1452 format_count = sizeof(_formats32) / sizeof(D3DFORMAT);
1453 }
1454
1455 /*
1456 ** now search for a valid format
1457 */
1458 bool found = false;
1459 unsigned int mode = 0;
1460
1461 for (int format_index=0; format_index < format_count; format_index++) {
1462 found |= Find_Color_Mode(format_table[format_index],resx,resy,&mode);
1463 if (found) break;
1464 }
1465
1466 if (!found) {
1467 return false;
1468 } else {
1469 *set_backbuffer=*set_colorbuffer = format_table[format_index];
1470 }
1471
1472 if (bitdepth==32 && *set_colorbuffer == D3DFMT_X8R8G8B8 && D3DInterface->CheckDeviceType(0,D3DDEVTYPE_HAL,*set_colorbuffer,D3DFMT_A8R8G8B8, TRUE) == D3D_OK)
1473 { //promote 32-bit modes to include destination alpha when supported
1474 *set_backbuffer = D3DFMT_A8R8G8B8;
1475 }
1476
1477 /*
1478 ** We found a backbuffer format, now find a zbuffer format
1479 */
1480 return Find_Z_Mode(*set_colorbuffer,*set_backbuffer, set_zmode);
1481};
1482
1483
1484// find the resolution mode with at least resx,resy with the highest supported
1485// refresh rate
1486bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode)
1487{
1488 UINT i,j,modemax;
1489 UINT rx,ry;
1490 D3DDISPLAYMODE dmode;
1491 ::ZeroMemory(&dmode, sizeof(D3DDISPLAYMODE));
1492
1493 rx=(unsigned int) resx;
1494 ry=(unsigned int) resy;
1495
1496 bool found=false;
1497
1498 modemax=D3DInterface->GetAdapterModeCount(D3DADAPTER_DEFAULT);
1499
1500 i=0;
1501
1502 while (i<modemax && !found)
1503 {
1504 D3DInterface->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &dmode);
1505 if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) {
1506 WWDEBUG_SAY(("Found valid color mode. Width = %d Height = %d Format = %d\r\n",dmode.Width,dmode.Height,dmode.Format));
1507 found=true;
1508 }
1509 i++;
1510 }
1511
1512 i--; // this is the first valid mode
1513
1514 // no match
1515 if (!found) {
1516 WWDEBUG_SAY(("Failed to find a valid color mode\r\n"));
1517 return false;
1518 }
1519
1520 // go to the highest refresh rate in this mode
1521 bool stillok=true;
1522
1523 j=i;
1524 while (j<modemax && stillok)
1525 {
1526 D3DInterface->EnumAdapterModes(D3DADAPTER_DEFAULT, j, &dmode);
1527 if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer)
1528 stillok=true; else stillok=false;
1529 j++;
1530 }
1531
1532 if (stillok==false) *mode=j-2;
1533 else *mode=i;
1534
1535 return true;
1536}
1537
1538// Helper function to find a Z buffer mode for the colorbuffer
1539// Will look for greatest Z precision
1540bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode)
1541{
1542 //MW: Swapped the next 2 tests so that Stencil modes get tested first.
1543 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24S8))
1544 {
1545 *zmode=D3DFMT_D24S8;
1546 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24S8\n"));
1547 return true;
1548 }
1549
1550 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D32))
1551 {
1552 *zmode=D3DFMT_D32;
1553 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D32\n"));
1554 return true;
1555 }
1556
1557 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X8))
1558 {
1559 *zmode=D3DFMT_D24X8;
1560 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X8\n"));
1561 return true;
1562 }
1563
1564 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X4S4))
1565 {
1566 *zmode=D3DFMT_D24X4S4;
1567 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X4S4\n"));
1568 return true;
1569 }
1570
1571 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D16))
1572 {
1573 *zmode=D3DFMT_D16;
1574 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D16\n"));
1575 return true;
1576 }
1577
1578 if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D15S1))
1579 {
1580 *zmode=D3DFMT_D15S1;
1581 WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D15S1\n"));
1582 return true;
1583 }
1584
1585 // can't find a match
1586 WWDEBUG_SAY(("Failed to find a valid zbuffer mode\r\n"));
1587 return false;
1588}
1589
1590bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode)
1591{
1592 // See if we have this mode first
1593 if (FAILED(D3DInterface->CheckDeviceFormat(D3DADAPTER_DEFAULT,WW3D_DEVTYPE,
1594 colorbuffer,D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,zmode)))
1595 {
1596 WWDEBUG_SAY(("CheckDeviceFormat failed. Colorbuffer format = %d Zbufferformat = %d\n",colorbuffer,zmode));
1597 return false;
1598 }
1599
1600 // Then see if it matches the color buffer
1601 if(FAILED(D3DInterface->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, WW3D_DEVTYPE,
1602 colorbuffer,backbuffer,zmode)))
1603 {
1604 WWDEBUG_SAY(("CheckDepthStencilMatch failed. Colorbuffer format = %d Backbuffer format = %d Zbufferformat = %d\n",colorbuffer,backbuffer,zmode));
1605 return false;
1606 }
1607 return true;
1608}
1609
1610
1612{
1613 matrix_changes = 0;
1614 material_changes = 0;
1617 light_changes = 0;
1618 texture_changes = 0;
1621 draw_calls =0;
1622
1624 last_frame_matrix_changes = 0;
1625 last_frame_material_changes = 0;
1626 last_frame_vertex_buffer_changes = 0;
1627 last_frame_index_buffer_changes = 0;
1628 last_frame_light_changes = 0;
1629 last_frame_texture_changes = 0;
1630 last_frame_render_state_changes = 0;
1631 last_frame_texture_stage_state_changes = 0;
1632 last_frame_number_of_DX8_calls = 0;
1633 last_frame_draw_calls =0;
1634}
1635
1649
1651{
1652 last_frame_matrix_changes=matrix_changes;
1653 last_frame_material_changes=material_changes;
1654 last_frame_vertex_buffer_changes=vertex_buffer_changes;
1655 last_frame_index_buffer_changes=index_buffer_changes;
1656 last_frame_light_changes=light_changes;
1657 last_frame_texture_changes = texture_changes;
1658 last_frame_render_state_changes = render_state_changes;
1659 last_frame_texture_stage_state_changes = texture_stage_state_changes;
1660 last_frame_number_of_DX8_calls=number_of_DX8_calls;
1661 last_frame_draw_calls=draw_calls;
1662}
1663
1664unsigned DX8Wrapper::Get_Last_Frame_Matrix_Changes() { return last_frame_matrix_changes; }
1665unsigned DX8Wrapper::Get_Last_Frame_Material_Changes() { return last_frame_material_changes; }
1666unsigned DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes() { return last_frame_vertex_buffer_changes; }
1667unsigned DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes() { return last_frame_index_buffer_changes; }
1668unsigned DX8Wrapper::Get_Last_Frame_Light_Changes() { return last_frame_light_changes; }
1669unsigned DX8Wrapper::Get_Last_Frame_Texture_Changes() { return last_frame_texture_changes; }
1670unsigned DX8Wrapper::Get_Last_Frame_Render_State_Changes() { return last_frame_render_state_changes; }
1671unsigned DX8Wrapper::Get_Last_Frame_Texture_Stage_State_Changes() { return last_frame_texture_stage_state_changes; }
1672unsigned DX8Wrapper::Get_Last_Frame_DX8_Calls() { return last_frame_number_of_DX8_calls; }
1673unsigned DX8Wrapper::Get_Last_Frame_Draw_Calls() { return last_frame_draw_calls; }
1674unsigned long DX8Wrapper::Get_FrameCount(void) {return FrameCount;}
1675
1681
1683{
1685
1686#if ENABLE_EMBEDDED_BROWSER
1688#endif
1689
1690 DX8CALL(BeginScene());
1691
1693}
1694
1695void DX8Wrapper::End_Scene(bool flip_frames)
1696{
1698 DX8CALL(EndScene());
1699
1701
1702 if (flip_frames) {
1703 DX8_Assert();
1704 HRESULT hr;
1705 {
1706 WWPROFILE("DX8Device::Present()");
1707 hr=_Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL);
1708 }
1709
1711
1712 if (SUCCEEDED(hr)) {
1713#ifdef EXTENDED_STATS
1714 if (stats.m_sleepTime) {
1715 ::Sleep(stats.m_sleepTime);
1716 }
1717#endif
1718 IsDeviceLost=false;
1719 FrameCount++;
1720 }
1721 else {
1722 IsDeviceLost=true;
1723 }
1724
1725 // If the device was lost we need to check for cooperative level and possibly reset the device
1726 if (hr==D3DERR_DEVICELOST) {
1727 hr=_Get_D3D_Device8()->TestCooperativeLevel();
1728 if (hr==D3DERR_DEVICENOTRESET) {
1729 Reset_Device();
1730 }
1731 else {
1732 // Sleep it not active
1734 }
1735 }
1736 else {
1737 DX8_ErrorCode(hr);
1738 }
1739 }
1740
1741 // Each frame, release all of the buffers and textures.
1744 for (int i=0;i<CurrentCaps->Get_Max_Textures_Per_Pass();++i) Set_Texture(i,NULL);
1746}
1747
1748
1750{
1751 // If we are fullscreen and the current frame is odd then we need
1752 // to force a page flip to ensure that the first buffer in the flipping
1753 // chain is the one visible.
1754 if (!IsWindowed) {
1755 DX8_Assert();
1756
1757 int numBuffers = (_PresentParameters.BackBufferCount + 1);
1758 int visibleBuffer = (FrameCount % numBuffers);
1759 int flipCount = ((numBuffers - visibleBuffer) % numBuffers);
1760 int resetAttempts = 0;
1761
1762 while ((flipCount > 0) && (resetAttempts < 3)) {
1763 HRESULT hr = _Get_D3D_Device8()->TestCooperativeLevel();
1764
1765 if (FAILED(hr)) {
1766 WWDEBUG_SAY(("TestCooperativeLevel Failed!\n"));
1767
1768 if (D3DERR_DEVICELOST == hr) {
1769 IsDeviceLost=true;
1770 WWDEBUG_SAY(("DEVICELOST: Cannot flip to primary.\n"));
1771 return;
1772 }
1773 IsDeviceLost=false;
1774
1775 if (D3DERR_DEVICENOTRESET == hr) {
1776 WWDEBUG_SAY(("DEVICENOTRESET\n"));
1777 Reset_Device();
1778 resetAttempts++;
1779 }
1780 } else {
1781 WWDEBUG_SAY(("Flipping: %ld\n", FrameCount));
1782 hr = _Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL);
1783
1784 if (SUCCEEDED(hr)) {
1785 IsDeviceLost=false;
1786 FrameCount++;
1787 WWDEBUG_SAY(("Flip to primary succeeded %ld\n", FrameCount));
1788 }
1789 else {
1790 IsDeviceLost=true;
1791 }
1792 }
1793
1794 --flipCount;
1795 }
1796 }
1797}
1798
1799
1800//**********************************************************************************************
1802
1805void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha, float z, unsigned int stencil)
1806{
1808
1809 // If we try to clear a stencil buffer which is not there, the entire call will fail
1810 // KJM fixed this to get format from back buffer (incase render to texture is used)
1811 /*bool has_stencil = ( _PresentParameters.AutoDepthStencilFormat == D3DFMT_D15S1 ||
1812 _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 ||
1813 _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4);*/
1814 bool has_stencil=false;
1815 IDirect3DSurface8* depthbuffer;
1816
1817 _Get_D3D_Device8()->GetDepthStencilSurface(&depthbuffer);
1819
1820 if (depthbuffer)
1821 {
1822 D3DSURFACE_DESC desc;
1823 depthbuffer->GetDesc(&desc);
1824 has_stencil=
1825 (
1826 desc.Format==D3DFMT_D15S1 ||
1827 desc.Format==D3DFMT_D24S8 ||
1828 desc.Format==D3DFMT_D24X4S4
1829 );
1830
1831 // release ref
1832 depthbuffer->Release();
1833 }
1834
1835 DWORD flags = 0;
1836 if (clear_color) flags |= D3DCLEAR_TARGET;
1837 if (clear_z_stencil) flags |= D3DCLEAR_ZBUFFER;
1838 if (clear_z_stencil && has_stencil) flags |= D3DCLEAR_STENCIL;
1839 if (flags)
1840 {
1841 DX8CALL(Clear(0, NULL, flags, Convert_Color(color,dest_alpha), z, stencil));
1842 }
1843}
1844
1845void DX8Wrapper::Set_Viewport(CONST D3DVIEWPORT8* pViewport)
1846{
1848 DX8CALL(SetViewport(pViewport));
1849}
1850
1851// ----------------------------------------------------------------------------
1852//
1853// Set vertex buffer. A reference to previous vertex buffer is released and
1854// this one is assigned the current vertex buffer. The DX8 vertex buffer will
1855// actually be set in Apply() which is called by Draw_Indexed_Triangles().
1856//
1857// ----------------------------------------------------------------------------
1858
1859void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb, unsigned stream)
1860{
1861 render_state.vba_offset=0;
1862 render_state.vba_count=0;
1863 if (render_state.vertex_buffers[stream]) {
1864 render_state.vertex_buffers[stream]->Release_Engine_Ref();
1865 }
1866 REF_PTR_SET(render_state.vertex_buffers[stream],const_cast<VertexBufferClass*>(vb));
1867 if (vb) {
1868 vb->Add_Engine_Ref();
1869 render_state.vertex_buffer_types[stream]=vb->Type();
1870 }
1871 else {
1872 render_state.vertex_buffer_types[stream]=BUFFER_TYPE_INVALID;
1873 }
1874 render_state_changed|=VERTEX_BUFFER_CHANGED;
1875}
1876
1877// ----------------------------------------------------------------------------
1878//
1879// Set index buffer. A reference to previous index buffer is released and
1880// this one is assigned the current index buffer. The DX8 index buffer will
1881// actually be set in Apply() which is called by Draw_Indexed_Triangles().
1882//
1883// ----------------------------------------------------------------------------
1884
1885void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset)
1886{
1887 render_state.iba_offset=0;
1888 if (render_state.index_buffer) {
1889 render_state.index_buffer->Release_Engine_Ref();
1890 }
1891 REF_PTR_SET(render_state.index_buffer,const_cast<IndexBufferClass*>(ib));
1892 render_state.index_base_offset=index_base_offset;
1893 if (ib) {
1894 ib->Add_Engine_Ref();
1895 render_state.index_buffer_type=ib->Type();
1896 }
1897 else {
1898 render_state.index_buffer_type=BUFFER_TYPE_INVALID;
1899 }
1900 render_state_changed|=INDEX_BUFFER_CHANGED;
1901}
1902
1903// ----------------------------------------------------------------------------
1904//
1905// Set vertex buffer using dynamic access object.
1906//
1907// ----------------------------------------------------------------------------
1908
1910{
1911 // Release all streams (only one stream allowed in the legacy pipeline)
1912 for (int i=1;i<MAX_VERTEX_STREAMS;++i) {
1914 }
1915
1916 if (render_state.vertex_buffers[0]) render_state.vertex_buffers[0]->Release_Engine_Ref();
1917 DynamicVBAccessClass& vba=const_cast<DynamicVBAccessClass&>(vba_);
1918 render_state.vertex_buffer_types[0]=vba.Get_Type();
1919 render_state.vba_offset=vba.VertexBufferOffset;
1920 render_state.vba_count=vba.Get_Vertex_Count();
1921 REF_PTR_SET(render_state.vertex_buffers[0],vba.VertexBuffer);
1922 render_state.vertex_buffers[0]->Add_Engine_Ref();
1923 render_state_changed|=VERTEX_BUFFER_CHANGED;
1924 render_state_changed|=INDEX_BUFFER_CHANGED; // vba_offset changes so index buffer needs to be reset as well.
1925}
1926
1927// ----------------------------------------------------------------------------
1928//
1929// Set index buffer using dynamic access object.
1930//
1931// ----------------------------------------------------------------------------
1932
1933void DX8Wrapper::Set_Index_Buffer(const DynamicIBAccessClass& iba_,unsigned short index_base_offset)
1934{
1935 if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
1936
1937 DynamicIBAccessClass& iba=const_cast<DynamicIBAccessClass&>(iba_);
1938 render_state.index_base_offset=index_base_offset;
1939 render_state.index_buffer_type=iba.Get_Type();
1940 render_state.iba_offset=iba.IndexBufferOffset;
1941 REF_PTR_SET(render_state.index_buffer,iba.IndexBuffer);
1942 render_state.index_buffer->Add_Engine_Ref();
1943 render_state_changed|=INDEX_BUFFER_CHANGED;
1944}
1945
1946// ----------------------------------------------------------------------------
1947//
1948// Private function for the special case of rendering polygons from sorting
1949// index and vertex buffers.
1950//
1951// ----------------------------------------------------------------------------
1952
1953void DX8Wrapper::Draw_Sorting_IB_VB(
1954 unsigned primitive_type,
1955 unsigned short start_index,
1956 unsigned short polygon_count,
1957 unsigned short min_vertex_index,
1958 unsigned short vertex_count)
1959{
1962
1963 // Fill dynamic vertex buffer with sorting vertex buffer vertices
1965 {
1966 DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access);
1967 VertexFormatXYZNDUV2* src = static_cast<SortingVertexBufferClass*>(render_state.vertex_buffers[0])->VertexBuffer;
1968 VertexFormatXYZNDUV2* dest= lock.Get_Formatted_Vertex_Array();
1969 src += render_state.vba_offset + render_state.index_base_offset + min_vertex_index;
1970 unsigned size = dyn_vb_access.FVF_Info().Get_FVF_Size()*vertex_count/sizeof(unsigned);
1971 unsigned *dest_u =(unsigned*) dest;
1972 unsigned *src_u = (unsigned*) src;
1973
1974 for (unsigned i=0;i<size;++i) {
1975 *dest_u++=*src_u++;
1976 }
1977 }
1978
1979 DX8CALL(SetStreamSource(
1980 0,
1981 static_cast<DX8VertexBufferClass*>(dyn_vb_access.VertexBuffer)->Get_DX8_Vertex_Buffer(),
1982 dyn_vb_access.FVF_Info().Get_FVF_Size()));
1983 // If using FVF format VB, set the FVF as vertex shader (may not be needed here KM)
1984 unsigned fvf=dyn_vb_access.FVF_Info().Get_FVF();
1985 if (fvf!=0) {
1986 DX8CALL(SetVertexShader(fvf));
1987 }
1989
1990 unsigned index_count=0;
1991 switch (primitive_type) {
1992 case D3DPT_TRIANGLELIST: index_count=polygon_count*3; break;
1993 case D3DPT_TRIANGLESTRIP: index_count=polygon_count+2; break;
1994 case D3DPT_TRIANGLEFAN: index_count=polygon_count+2; break;
1995 default: WWASSERT(0); break; // Unsupported primitive type
1996 }
1997
1998 // Fill dynamic index buffer with sorting index buffer vertices
1999 DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,index_count);
2000 {
2001 DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access);
2002 unsigned short* dest=lock.Get_Index_Array();
2003 unsigned short* src=NULL;
2004 src=static_cast<SortingIndexBufferClass*>(render_state.index_buffer)->index_buffer;
2005 src+=render_state.iba_offset+start_index;
2006
2007 try {
2008 for (unsigned short i=0;i<index_count;++i) {
2009 unsigned short index=*src++;
2010 index-=min_vertex_index;
2011 WWASSERT(index<vertex_count);
2012 *dest++=index;
2013 }
2015 } catch(...) {
2017 }
2018 }
2019
2020 DX8CALL(SetIndices(
2021 static_cast<DX8IndexBufferClass*>(dyn_ib_access.IndexBuffer)->Get_DX8_Index_Buffer(),
2022 dyn_vb_access.VertexBufferOffset));
2024
2026 DX8CALL(DrawIndexedPrimitive(
2027 D3DPT_TRIANGLELIST,
2028 0, // start vertex
2029 vertex_count,
2030 dyn_ib_access.IndexBufferOffset,
2031 polygon_count));
2032
2033 DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader);
2034}
2035
2036// ----------------------------------------------------------------------------
2037//
2038//
2039//
2040// ----------------------------------------------------------------------------
2041
2042void DX8Wrapper::Draw(
2043 unsigned primitive_type,
2044 unsigned short start_index,
2045 unsigned short polygon_count,
2046 unsigned short min_vertex_index,
2047 unsigned short vertex_count)
2048{
2049 if (DrawPolygonLowBoundLimit && DrawPolygonLowBoundLimit>=polygon_count) return;
2050
2052 SNAPSHOT_SAY(("DX8 - draw\n"));
2053
2055
2056 // Debug feature to disable triangle drawing...
2057 if (!_Is_Triangle_Draw_Enabled()) return;
2058
2059#ifdef MESH_RENDER_SNAPSHOT_ENABLED
2061 unsigned long passes=0;
2062 SNAPSHOT_SAY(("ValidateDevice: "));
2063 HRESULT res=D3DDevice->ValidateDevice(&passes);
2064 switch (res) {
2065 case D3D_OK:
2066 SNAPSHOT_SAY(("OK\n"));
2067 break;
2068
2069 case D3DERR_CONFLICTINGTEXTUREFILTER:
2070 SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREFILTER\n"));
2071 break;
2072 case D3DERR_CONFLICTINGTEXTUREPALETTE:
2073 SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREPALETTE\n"));
2074 break;
2075 case D3DERR_DEVICELOST:
2076 SNAPSHOT_SAY(("D3DERR_DEVICELOST\n"));
2077 break;
2078 case D3DERR_TOOMANYOPERATIONS:
2079 SNAPSHOT_SAY(("D3DERR_TOOMANYOPERATIONS\n"));
2080 break;
2081 case D3DERR_UNSUPPORTEDALPHAARG:
2082 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAARG\n"));
2083 break;
2084 case D3DERR_UNSUPPORTEDALPHAOPERATION:
2085 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAOPERATION\n"));
2086 break;
2087 case D3DERR_UNSUPPORTEDCOLORARG:
2088 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLORARG\n"));
2089 break;
2090 case D3DERR_UNSUPPORTEDCOLOROPERATION:
2091 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLOROPERATION\n"));
2092 break;
2093 case D3DERR_UNSUPPORTEDFACTORVALUE:
2094 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDFACTORVALUE\n"));
2095 break;
2096 case D3DERR_UNSUPPORTEDTEXTUREFILTER:
2097 SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDTEXTUREFILTER\n"));
2098 break;
2099 case D3DERR_WRONGTEXTUREFORMAT:
2100 SNAPSHOT_SAY(("D3DERR_WRONGTEXTUREFORMAT\n"));
2101 break;
2102 default:
2103 SNAPSHOT_SAY(("UNKNOWN Error\n"));
2104 break;
2105 }
2106 }
2107#endif // MESH_RENDER_SHAPSHOT_ENABLED
2108
2109
2110 SNAPSHOT_SAY(("DX8 - draw %d polygons (%d vertices)\n",polygon_count,vertex_count));
2111
2112 if (vertex_count<3) {
2113 min_vertex_index=0;
2114 switch (render_state.vertex_buffer_types[0]) {
2115 case BUFFER_TYPE_DX8:
2117 vertex_count=render_state.vertex_buffers[0]->Get_Vertex_Count()-render_state.index_base_offset-render_state.vba_offset-min_vertex_index;
2118 break;
2121 vertex_count=render_state.vba_count;
2122 break;
2123 }
2124 }
2125
2126 switch (render_state.vertex_buffer_types[0]) {
2127 case BUFFER_TYPE_DX8:
2129 switch (render_state.index_buffer_type) {
2130 case BUFFER_TYPE_DX8:
2132 {
2133/* if ((start_index+render_state.iba_offset+polygon_count*3) > render_state.index_buffer->Get_Index_Count())
2134 { WWASSERT_PRINT(0,"OVERFLOWING INDEX BUFFER");
2136 break;
2137 }*/
2138 DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader);
2140 DX8CALL(DrawIndexedPrimitive(
2141 (D3DPRIMITIVETYPE)primitive_type,
2142 min_vertex_index,
2143 vertex_count,
2144 start_index+render_state.iba_offset,
2145 polygon_count));
2146 }
2147 break;
2150 WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)");
2151 break;
2153 WWASSERT(0);
2154 break;
2155 }
2156 break;
2159 switch (render_state.index_buffer_type) {
2160 case BUFFER_TYPE_DX8:
2162 WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)");
2163 break;
2166 Draw_Sorting_IB_VB(primitive_type,start_index,polygon_count,min_vertex_index,vertex_count);
2167 break;
2169 WWASSERT(0);
2170 break;
2171 }
2172 break;
2174 WWASSERT(0);
2175 break;
2176 }
2177}
2178
2179// ----------------------------------------------------------------------------
2180//
2181//
2182//
2183// ----------------------------------------------------------------------------
2184
2186 unsigned buffer_type,
2187 unsigned short start_index,
2188 unsigned short polygon_count,
2189 unsigned short min_vertex_index,
2190 unsigned short vertex_count)
2191{
2192 if (buffer_type==BUFFER_TYPE_SORTING || buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) {
2193 SortingRendererClass::Insert_Triangles(start_index,polygon_count,min_vertex_index,vertex_count);
2194 }
2195 else {
2196 Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count);
2197 }
2198}
2199
2200// ----------------------------------------------------------------------------
2201//
2202//
2203//
2204// ----------------------------------------------------------------------------
2205
2207 unsigned short start_index,
2208 unsigned short polygon_count,
2209 unsigned short min_vertex_index,
2210 unsigned short vertex_count)
2211{
2212 Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count);
2213}
2214
2215// ----------------------------------------------------------------------------
2216//
2217//
2218//
2219// ----------------------------------------------------------------------------
2220
2222 unsigned short start_index,
2223 unsigned short polygon_count,
2224 unsigned short min_vertex_index,
2225 unsigned short vertex_count)
2226{
2227 Draw(D3DPT_TRIANGLESTRIP,start_index,polygon_count,min_vertex_index,vertex_count);
2228}
2229
2230// ----------------------------------------------------------------------------
2231//
2232//
2233//
2234// ----------------------------------------------------------------------------
2235
2237{
2238 SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes()\n"));
2239
2240 if (!render_state_changed) return;
2241 if (render_state_changed&SHADER_CHANGED) {
2242 SNAPSHOT_SAY(("DX8 - apply shader\n"));
2243 render_state.shader.Apply();
2244 }
2245
2246 unsigned mask=TEXTURE0_CHANGED;
2247 for (int i=0;i<CurrentCaps->Get_Max_Textures_Per_Pass();++i,mask<<=1)
2248 {
2249 if (render_state_changed&mask)
2250 {
2251 SNAPSHOT_SAY(("DX8 - apply texture %d (%s)\n",i,render_state.Textures[i] ? render_state.Textures[i]->Get_Full_Path() : "NULL"));
2252
2253 if (render_state.Textures[i])
2254 {
2255 render_state.Textures[i]->Apply(i);
2256 }
2257 else
2258 {
2260 }
2261 }
2262 }
2263
2264 if (render_state_changed&MATERIAL_CHANGED)
2265 {
2266 SNAPSHOT_SAY(("DX8 - apply material\n"));
2267 VertexMaterialClass* material=const_cast<VertexMaterialClass*>(render_state.material);
2268 if (material)
2269 {
2270 material->Apply();
2271 }
2272 else VertexMaterialClass::Apply_Null();
2273 }
2274
2275 if (render_state_changed&LIGHTS_CHANGED)
2276 {
2277 unsigned mask=LIGHT0_CHANGED;
2278 for (unsigned index=0;index<4;++index,mask<<=1) {
2279 if (render_state_changed&mask) {
2280 SNAPSHOT_SAY(("DX8 - apply light %d\n",index));
2281 if (render_state.LightEnable[index]) {
2282#ifdef MESH_RENDER_SNAPSHOT_ENABLED
2284 D3DLIGHT8 * light = &(render_state.Lights[index]);
2285 static char * _light_types[] = { "Unknown", "Point","Spot", "Directional" };
2286 WWASSERT((light->Type >= 0) && (light->Type <= 3));
2287
2288 SNAPSHOT_SAY((" type = %s amb = %4.2f,%4.2f,%4.2f diff = %4.2f,%4.2f,%4.2f spec = %4.2f, %4.2f, %4.2f\n",
2289 _light_types[light->Type],
2290 light->Ambient.r,light->Ambient.g,light->Ambient.b,
2291 light->Diffuse.r,light->Diffuse.g,light->Diffuse.b,
2292 light->Specular.r,light->Specular.g,light->Specular.b ));
2293 SNAPSHOT_SAY((" pos = %f, %f, %f dir = %f, %f, %f\n",
2294 light->Position.x, light->Position.y, light->Position.z,
2295 light->Direction.x, light->Direction.y, light->Direction.z ));
2296 }
2297#endif
2298
2299 Set_DX8_Light(index,&render_state.Lights[index]);
2300 }
2301 else {
2302 Set_DX8_Light(index,NULL);
2303 SNAPSHOT_SAY((" clearing light to NULL\n"));
2304 }
2305 }
2306 }
2307 }
2308
2309 if (render_state_changed&WORLD_CHANGED) {
2310 SNAPSHOT_SAY(("DX8 - apply world matrix\n"));
2311 _Set_DX8_Transform(D3DTS_WORLD,render_state.world);
2312 }
2313 if (render_state_changed&VIEW_CHANGED) {
2314 SNAPSHOT_SAY(("DX8 - apply view matrix\n"));
2315 _Set_DX8_Transform(D3DTS_VIEW,render_state.view);
2316 }
2317 if (render_state_changed&VERTEX_BUFFER_CHANGED) {
2318 SNAPSHOT_SAY(("DX8 - apply vb change\n"));
2319 for (i=0;i<MAX_VERTEX_STREAMS;++i) {
2320 if (render_state.vertex_buffers[i]) {
2321 switch (render_state.vertex_buffer_types[i]) {//->Type()) {
2322 case BUFFER_TYPE_DX8:
2324 DX8CALL(SetStreamSource(
2325 i,
2326 static_cast<DX8VertexBufferClass*>(render_state.vertex_buffers[i])->Get_DX8_Vertex_Buffer(),
2327 render_state.vertex_buffers[i]->FVF_Info().Get_FVF_Size()));
2329 {
2330 // If the VB format is FVF, set the FVF as a vertex shader
2331 unsigned fvf=render_state.vertex_buffers[i]->FVF_Info().Get_FVF();
2332 if (fvf!=0) {
2333 Set_Vertex_Shader(fvf);
2334 }
2335 }
2336 break;
2339 break;
2340 default:
2341 WWASSERT(0);
2342 }
2343 } else {
2344 DX8CALL(SetStreamSource(i,NULL,0));
2346 }
2347 }
2348 }
2349 if (render_state_changed&INDEX_BUFFER_CHANGED) {
2350 SNAPSHOT_SAY(("DX8 - apply ib change\n"));
2351 if (render_state.index_buffer) {
2352 switch (render_state.index_buffer_type) {//->Type()) {
2353 case BUFFER_TYPE_DX8:
2355 DX8CALL(SetIndices(
2356 static_cast<DX8IndexBufferClass*>(render_state.index_buffer)->Get_DX8_Index_Buffer(),
2357 render_state.index_base_offset+render_state.vba_offset));
2359 break;
2362 break;
2363 default:
2364 WWASSERT(0);
2365 }
2366 }
2367 else {
2368 DX8CALL(SetIndices(
2369 NULL,
2370 0));
2372 }
2373 }
2374
2375 render_state_changed&=((unsigned)WORLD_IDENTITY|(unsigned)VIEW_IDENTITY);
2376
2377 SNAPSHOT_SAY(("DX8Wrapper::Apply_Render_State_Changes() - finished\n"));
2378}
2379
2381(
2382 unsigned int width,
2383 unsigned int height,
2384 WW3DFormat format,
2385 MipCountType mip_level_count,
2386 D3DPOOL pool,
2387 bool rendertarget
2388)
2389{
2391 DX8_Assert();
2392 IDirect3DTexture8 *texture = NULL;
2393
2394 // Paletted textures not supported!
2395 WWASSERT(format!=D3DFMT_P8);
2396
2397 // NOTE: If 'format' is not supported as a texture format, this function will find the closest
2398 // format that is supported and use that instead.
2399
2400 // Render target may return NOTAVAILABLE, in
2401 // which case we return NULL.
2402 if (rendertarget) {
2403 unsigned ret=D3DXCreateTexture(
2405 width,
2406 height,
2407 mip_level_count,
2408 D3DUSAGE_RENDERTARGET,
2410 pool,
2411 &texture);
2412
2413 if (ret==D3DERR_NOTAVAILABLE) {
2414 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2415 return NULL;
2416 }
2417
2418 // If ran out of texture ram, try invalidating some textures and mesh cache.
2419 if (ret==D3DERR_OUTOFVIDEOMEMORY) {
2420 WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...\n"));
2421 // Free all textures that haven't been used in the last 5 seconds
2423
2424 // Invalidate the mesh cache
2426
2427 ret=D3DXCreateTexture(
2429 width,
2430 height,
2431 mip_level_count,
2432 D3DUSAGE_RENDERTARGET,
2434 pool,
2435 &texture);
2436
2437 if (SUCCEEDED(ret)) {
2438 WWDEBUG_SAY(("...Render target creation succesful.\n"));
2439 }
2440 else {
2441 WWDEBUG_SAY(("...Render target creation failed.\n"));
2442 }
2443 if (ret==D3DERR_OUTOFVIDEOMEMORY) {
2444 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2445 return NULL;
2446 }
2447 }
2448
2449 DX8_ErrorCode(ret);
2450 // Just return the texture, no reduction
2451 // allowed for render targets.
2452 return texture;
2453 }
2454
2455 // We should never run out of video memory when allocating a non-rendertarget texture.
2456 // However, it seems to happen sometimes when there are a lot of textures in memory and so
2457 // if it happens we'll release assets and try again (anything is better than crashing).
2458 unsigned ret=D3DXCreateTexture(
2460 width,
2461 height,
2462 mip_level_count,
2463 0,
2465 pool,
2466 &texture);
2467
2468 // If ran out of texture ram, try invalidating some textures and mesh cache.
2469 if (ret==D3DERR_OUTOFVIDEOMEMORY) {
2470 WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...\n"));
2471 // Free all textures that haven't been used in the last 5 seconds
2473
2474 // Invalidate the mesh cache
2476
2477 ret=D3DXCreateTexture(
2479 width,
2480 height,
2481 mip_level_count,
2482 0,
2484 pool,
2485 &texture);
2486 if (SUCCEEDED(ret)) {
2487 WWDEBUG_SAY(("...Texture creation succesful.\n"));
2488 }
2489 else {
2490 StringClass format_name(0,true);
2491 Get_WW3D_Format_Name(format, format_name);
2492 WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d\n",width,height,format_name,mip_level_count));
2493 }
2494
2495 }
2496 DX8_ErrorCode(ret);
2497
2498 return texture;
2499}
2500
2502(
2503 const char *filename,
2504 MipCountType mip_level_count
2505)
2506{
2508 DX8_Assert();
2509 IDirect3DTexture8 *texture = NULL;
2510
2511 // NOTE: If the original image format is not supported as a texture format, it will
2512 // automatically be converted to an appropriate format.
2513 // NOTE: It is possible to get the size and format of the original image file from this
2514 // function as well, so if we later want to second-guess D3DX's format conversion decisions
2515 // we can do so after this function is called..
2516 unsigned result = D3DXCreateTextureFromFileExA(
2518 filename,
2519 D3DX_DEFAULT,
2520 D3DX_DEFAULT,
2521 mip_level_count,//create_mipmaps ? 0 : 1,
2522 0,
2523 D3DFMT_UNKNOWN,
2524 D3DPOOL_MANAGED,
2525 D3DX_FILTER_BOX,
2526 D3DX_FILTER_BOX,
2527 0,
2528 NULL,
2529 NULL,
2530 &texture);
2531
2532 if (result != D3D_OK) {
2534 }
2535
2536 // Make sure texture wasn't paletted!
2537 D3DSURFACE_DESC desc;
2538 texture->GetLevelDesc(0,&desc);
2539 if (desc.Format==D3DFMT_P8) {
2540 texture->Release();
2542 }
2543 return texture;
2544}
2545
2547(
2548 IDirect3DSurface8 *surface,
2549 MipCountType mip_level_count
2550)
2551{
2553 DX8_Assert();
2554 IDirect3DTexture8 *texture = NULL;
2555
2556 D3DSURFACE_DESC surface_desc;
2557 ::ZeroMemory(&surface_desc, sizeof(D3DSURFACE_DESC));
2558 surface->GetDesc(&surface_desc);
2559
2560 // This function will create a texture with a different (but similar) format if the surface is
2561 // not in a supported texture format.
2562 WW3DFormat format=D3DFormat_To_WW3DFormat(surface_desc.Format);
2563 texture = _Create_DX8_Texture(surface_desc.Width, surface_desc.Height, format, mip_level_count);
2564
2565 // Copy the surface to the texture
2566 IDirect3DSurface8 *tex_surface = NULL;
2567 texture->GetSurfaceLevel(0, &tex_surface);
2568 DX8_ErrorCode(D3DXLoadSurfaceFromSurface(tex_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_BOX, 0));
2569 tex_surface->Release();
2570
2571 // Create mipmaps if needed
2572 if (mip_level_count!=MIP_LEVELS_1)
2573 {
2574 DX8_ErrorCode(D3DXFilterTexture(texture, NULL, 0, D3DX_FILTER_BOX));
2575 }
2576
2577 return texture;
2578
2579}
2580
2585(
2586 unsigned int width,
2587 unsigned int height,
2588 WW3DZFormat zformat,
2589 MipCountType mip_level_count,
2590 D3DPOOL pool
2591)
2592{
2594 DX8_Assert();
2595 IDirect3DTexture8* texture = NULL;
2596
2597 D3DFORMAT zfmt=WW3DZFormat_To_D3DFormat(zformat);
2598
2599 unsigned ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture
2600 (
2601 width,
2602 height,
2603 mip_level_count,
2604 D3DUSAGE_DEPTHSTENCIL,
2605 zfmt,
2606 pool,
2607 &texture
2608 );
2609
2610 if (ret==D3DERR_NOTAVAILABLE)
2611 {
2612 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2613 return NULL;
2614 }
2615
2616 // If ran out of texture ram, try invalidating some textures and mesh cache.
2617 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2618 {
2619 WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...\n"));
2620 // Free all textures that haven't been used in the last 5 seconds
2622
2623 // Invalidate the mesh cache
2625
2626 ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture
2627 (
2628 width,
2629 height,
2630 mip_level_count,
2631 D3DUSAGE_DEPTHSTENCIL,
2632 zfmt,
2633 pool,
2634 &texture
2635 );
2636
2637 if (SUCCEEDED(ret))
2638 {
2639 WWDEBUG_SAY(("...Render target creation succesful.\n"));
2640 }
2641 else
2642 {
2643 WWDEBUG_SAY(("...Render target creation failed.\n"));
2644 }
2645 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2646 {
2647 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2648 return NULL;
2649 }
2650 }
2651
2652 DX8_ErrorCode(ret);
2653
2654 texture->AddRef(); // don't release this texture
2655
2656 // Just return the texture, no reduction
2657 // allowed for render targets.
2658
2659 return texture;
2660}
2661
2666(
2667 unsigned int width,
2668 unsigned int height,
2669 WW3DFormat format,
2670 MipCountType mip_level_count,
2671 D3DPOOL pool,
2672 bool rendertarget
2673)
2674{
2675 WWASSERT(width==height);
2677 DX8_Assert();
2678 IDirect3DCubeTexture8* texture=NULL;
2679
2680 // Paletted textures not supported!
2681 WWASSERT(format!=D3DFMT_P8);
2682
2683 // NOTE: If 'format' is not supported as a texture format, this function will find the closest
2684 // format that is supported and use that instead.
2685
2686 // Render target may return NOTAVAILABLE, in
2687 // which case we return NULL.
2688 if (rendertarget)
2689 {
2690 unsigned ret=D3DXCreateCubeTexture
2691 (
2693 width,
2694 mip_level_count,
2695 D3DUSAGE_RENDERTARGET,
2697 pool,
2698 &texture
2699 );
2700
2701 if (ret==D3DERR_NOTAVAILABLE)
2702 {
2703 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2704 return NULL;
2705 }
2706
2707 // If ran out of texture ram, try invalidating some textures and mesh cache.
2708 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2709 {
2710 WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...\n"));
2711 // Free all textures that haven't been used in the last 5 seconds
2713
2714 // Invalidate the mesh cache
2716
2717 ret=D3DXCreateCubeTexture
2718 (
2720 width,
2721 mip_level_count,
2722 D3DUSAGE_RENDERTARGET,
2724 pool,
2725 &texture
2726 );
2727
2728 if (SUCCEEDED(ret))
2729 {
2730 WWDEBUG_SAY(("...Render target creation succesful.\n"));
2731 }
2732 else
2733 {
2734 WWDEBUG_SAY(("...Render target creation failed.\n"));
2735 }
2736 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2737 {
2738 Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
2739 return NULL;
2740 }
2741 }
2742
2743 DX8_ErrorCode(ret);
2744 // Just return the texture, no reduction
2745 // allowed for render targets.
2746 return texture;
2747 }
2748
2749 // We should never run out of video memory when allocating a non-rendertarget texture.
2750 // However, it seems to happen sometimes when there are a lot of textures in memory and so
2751 // if it happens we'll release assets and try again (anything is better than crashing).
2752 unsigned ret=D3DXCreateCubeTexture
2753 (
2755 width,
2756 mip_level_count,
2757 0,
2759 pool,
2760 &texture
2761 );
2762
2763 // If ran out of texture ram, try invalidating some textures and mesh cache.
2764 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2765 {
2766 WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...\n"));
2767 // Free all textures that haven't been used in the last 5 seconds
2769
2770 // Invalidate the mesh cache
2772
2773 ret=D3DXCreateCubeTexture
2774 (
2776 width,
2777 mip_level_count,
2778 0,
2780 pool,
2781 &texture
2782 );
2783 if (SUCCEEDED(ret))
2784 {
2785 WWDEBUG_SAY(("...Texture creation succesful.\n"));
2786 }
2787 else
2788 {
2789 StringClass format_name(0,true);
2790 Get_WW3D_Format_Name(format, format_name);
2791 WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d\n",width,height,format_name,mip_level_count));
2792 }
2793
2794 }
2795 DX8_ErrorCode(ret);
2796
2797 return texture;
2798}
2799
2804(
2805 unsigned int width,
2806 unsigned int height,
2807 unsigned int depth,
2808 WW3DFormat format,
2809 MipCountType mip_level_count,
2810 D3DPOOL pool
2811)
2812{
2814 DX8_Assert();
2815 IDirect3DVolumeTexture8* texture=NULL;
2816
2817 // Paletted textures not supported!
2818 WWASSERT(format!=D3DFMT_P8);
2819
2820 // NOTE: If 'format' is not supported as a texture format, this function will find the closest
2821 // format that is supported and use that instead.
2822
2823
2824 // We should never run out of video memory when allocating a non-rendertarget texture.
2825 // However, it seems to happen sometimes when there are a lot of textures in memory and so
2826 // if it happens we'll release assets and try again (anything is better than crashing).
2827 unsigned ret=D3DXCreateVolumeTexture
2828 (
2830 width,
2831 height,
2832 depth,
2833 mip_level_count,
2834 0,
2836 pool,
2837 &texture
2838 );
2839
2840 // If ran out of texture ram, try invalidating some textures and mesh cache.
2841 if (ret==D3DERR_OUTOFVIDEOMEMORY)
2842 {
2843 WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...\n"));
2844 // Free all textures that haven't been used in the last 5 seconds
2846
2847 // Invalidate the mesh cache
2849
2850 ret=D3DXCreateVolumeTexture
2851 (
2853 width,
2854 height,
2855 depth,
2856 mip_level_count,
2857 0,
2859 pool,
2860 &texture
2861 );
2862 if (SUCCEEDED(ret))
2863 {
2864 WWDEBUG_SAY(("...Texture creation succesful.\n"));
2865 }
2866 else
2867 {
2868 StringClass format_name(0,true);
2869 Get_WW3D_Format_Name(format, format_name);
2870 WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d\n",width,height,format_name,mip_level_count));
2871 }
2872
2873 }
2874 DX8_ErrorCode(ret);
2875
2876 return texture;
2877}
2878
2879
2880IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format)
2881{
2883 DX8_Assert();
2884
2885 IDirect3DSurface8 *surface = NULL;
2886
2887 // Paletted surfaces not supported!
2888 WWASSERT(format!=D3DFMT_P8);
2889
2890 DX8CALL(CreateImageSurface(width, height, WW3DFormat_To_D3DFormat(format), &surface));
2891
2892 return surface;
2893}
2894
2895IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_)
2896{
2898 DX8_Assert();
2899
2900 // Note: Since there is no "D3DXCreateSurfaceFromFile" and no "GetSurfaceInfoFromFile" (the
2901 // latter is supposed to be added to D3DX in a future version), we create a texture from the
2902 // file (w/o mipmaps), check that its surface is equal to the original file data (which it
2903 // will not be if the file is not in a texture-supported format or size). If so, copy its
2904 // surface (we might be able to just get its surface and add a ref to it but I'm not sure so
2905 // I'm not going to risk it) and release the texture. If not, create a surface according to
2906 // the file data and use D3DXLoadSurfaceFromFile. This is a horrible hack, but it saves us
2907 // having to write file loaders. Will fix this when D3DX provides us with the right functions.
2908 // Create a surface the size of the file image data
2909 IDirect3DSurface8 *surface = NULL;
2910
2911 {
2912
2913 file_auto_ptr myfile(_TheFileFactory,filename_);
2914 // If file not found, create a surface with missing texture in it
2915
2916 if (!myfile->Is_Available()) {
2917 // If file not found, try the dds format
2918 // else create a surface with missing texture in it
2919 char compressed_name[200];
2920 strncpy(compressed_name,filename_, 200);
2921 char *ext = strstr(compressed_name, ".");
2922 if ( (strlen(ext)==4) &&
2923 ( (ext[1] == 't') || (ext[1] == 'T') ) &&
2924 ( (ext[2] == 'g') || (ext[2] == 'G') ) &&
2925 ( (ext[3] == 'a') || (ext[3] == 'A') ) ) {
2926 ext[1]='d';
2927 ext[2]='d';
2928 ext[3]='s';
2929 }
2930 file_auto_ptr myfile2(_TheFileFactory,compressed_name);
2931 if (!myfile2->Is_Available())
2933 }
2934 }
2935
2936 StringClass filename_string(filename_,true);
2938 filename_string,
2940 true);
2941 return surface;
2942}
2943
2944
2945/***********************************************************************************************
2946 * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory *
2947 * *
2948 * *
2949 * *
2950 * *
2951 * INPUT: *
2952 * *
2953 * OUTPUT: *
2954 * *
2955 * WARNINGS: *
2956 * *
2957 * HISTORY: *
2958 * 4/26/2001 hy : Created. *
2959 *=============================================================================================*/
2961{
2962 WWASSERT(system);
2963 WWASSERT(video);
2966 DX8CALL(UpdateTexture(system->Peek_D3D_Base_Texture(),video->Peek_D3D_Base_Texture()));
2967}
2968
2970{
2972 DX8_Assert();
2973 delete CurrentCaps;
2975}
2976
2977
2978void DX8Wrapper::Set_Light(unsigned index, const D3DLIGHT8* light)
2979{
2980 if (light) {
2981 render_state.Lights[index]=*light;
2982 render_state.LightEnable[index]=true;
2983 }
2984 else {
2985 render_state.LightEnable[index]=false;
2986 }
2987 render_state_changed|=(LIGHT0_CHANGED<<index);
2988}
2989
2990void DX8Wrapper::Set_Light(unsigned index,const LightClass &light)
2991{
2992 D3DLIGHT8 dlight;
2993 Vector3 temp;
2994 memset(&dlight,0,sizeof(D3DLIGHT8));
2995
2996 switch (light.Get_Type())
2997 {
2998 case LightClass::POINT:
2999 {
3000 dlight.Type=D3DLIGHT_POINT;
3001 }
3002 break;
3004 {
3005 dlight.Type=D3DLIGHT_DIRECTIONAL;
3006 }
3007 break;
3008 case LightClass::SPOT:
3009 {
3010 dlight.Type=D3DLIGHT_SPOT;
3011 }
3012 break;
3013 }
3014
3015 light.Get_Diffuse(&temp);
3016 temp*=light.Get_Intensity();
3017 dlight.Diffuse.r=temp.X;
3018 dlight.Diffuse.g=temp.Y;
3019 dlight.Diffuse.b=temp.Z;
3020 dlight.Diffuse.a=1.0f;
3021
3022 light.Get_Specular(&temp);
3023 temp*=light.Get_Intensity();
3024 dlight.Specular.r=temp.X;
3025 dlight.Specular.g=temp.Y;
3026 dlight.Specular.b=temp.Z;
3027 dlight.Specular.a=1.0f;
3028
3029 light.Get_Ambient(&temp);
3030 temp*=light.Get_Intensity();
3031 dlight.Ambient.r=temp.X;
3032 dlight.Ambient.g=temp.Y;
3033 dlight.Ambient.b=temp.Z;
3034 dlight.Ambient.a=1.0f;
3035
3036 temp=light.Get_Position();
3037 dlight.Position=*(D3DVECTOR*) &temp;
3038
3039 light.Get_Spot_Direction(temp);
3040 dlight.Direction=*(D3DVECTOR*) &temp;
3041
3042 dlight.Range=light.Get_Attenuation_Range();
3043 dlight.Falloff=light.Get_Spot_Exponent();
3044 dlight.Theta=light.Get_Spot_Angle();
3045 dlight.Phi=light.Get_Spot_Angle();
3046
3047 // Inverse linear light 1/(1+D)
3048 double a,b;
3049 light.Get_Far_Attenuation_Range(a,b);
3050 dlight.Attenuation0=1.0f;
3051 if (fabs(a-b)<1e-5)
3052 // if the attenuation range is too small assume uniform with cutoff
3053 dlight.Attenuation1=0.0f;
3054 else
3055 // this will cause the light to drop to half intensity at the first far attenuation
3056 dlight.Attenuation1=(float) 1.0/a;
3057 dlight.Attenuation2=0.0f;
3058
3059 Set_Light(index,&dlight);
3060}
3061
3062//**********************************************************************************************
3065
3068{
3069 // Shader light environment support *
3070// if (Light_Environment && light_env && (*Light_Environment)==(*light_env)) return;
3071
3072 Light_Environment=light_env;
3073
3074 if (light_env)
3075 {
3076 int light_count = light_env->Get_Light_Count();
3077 unsigned int color=Convert_Color(light_env->Get_Equivalent_Ambient(),0.0f);
3078 if (RenderStates[D3DRS_AMBIENT]!=color)
3079 {
3080 Set_DX8_Render_State(D3DRS_AMBIENT,color);
3081//buggy Radeon 9700 driver doesn't apply new ambient unless the material also changes.
3082#if 1
3083 render_state_changed|=MATERIAL_CHANGED;
3084#endif
3085 }
3086
3087 D3DLIGHT8 light;
3088 for (int l=0;l<light_count;++l) {
3089
3090 ::ZeroMemory(&light, sizeof(D3DLIGHT8));
3091
3092 light.Type=D3DLIGHT_DIRECTIONAL;
3093 (Vector3&)light.Diffuse=light_env->Get_Light_Diffuse(l);
3094 Vector3 dir=-light_env->Get_Light_Direction(l);
3095 light.Direction=(const D3DVECTOR&)(dir);
3096
3097 // (gth) TODO: put specular into LightEnvironment? Much work to be done on lights :-)'
3098 if (l==0) {
3099 light.Specular.r = light.Specular.g = light.Specular.b = 1.0f;
3100 }
3101
3102 if (light_env->isPointLight(l)) {
3103 light.Type = D3DLIGHT_POINT;
3104 (Vector3&)light.Diffuse=light_env->getPointDiffuse(l);
3105 (Vector3&)light.Ambient=light_env->getPointAmbient(l);
3106 light.Position = (const D3DVECTOR&)light_env->getPointCenter(l);
3107 light.Range = light_env->getPointOrad(l);
3108
3109 // Inverse linear light 1/(1+D)
3110 double a,b;
3111 b = light_env->getPointOrad(l);
3112 a = light_env->getPointIrad(l);
3113
3114//(gth) CNC3 Generals code for the attenuation factors is causing the lights to over-brighten
3115//I'm changing the Attenuation0 parameter to 1.0 to avoid this problem.
3116#if 0
3117 light.Attenuation0=0.01f;
3118#else
3119 light.Attenuation0=1.0f;
3120#endif
3121 if (fabs(a-b)<1e-5)
3122 // if the attenuation range is too small assume uniform with cutoff
3123 light.Attenuation1=0.0f;
3124 else
3125 // this will cause the light to drop to half intensity at the first far attenuation
3126 light.Attenuation1=(float) 0.1/a;
3127
3128 light.Attenuation2=8.0f/(b*b);
3129 }
3130
3131 Set_Light(l,&light);
3132 }
3133
3134 for (;l<4;++l) {
3135 Set_Light(l,NULL);
3136 }
3137 }
3138/* else {
3139 for (int l=0;l<4;++l) {
3140 Set_Light(l,NULL);
3141 }
3142 }
3143*/
3144}
3145
3147{
3149 D3DDISPLAYMODE mode;
3150
3151 DX8CALL(GetDisplayMode(&mode));
3152
3153 IDirect3DSurface8 * fb=NULL;
3154
3155 DX8CALL(CreateImageSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,&fb));
3156
3157 DX8CALL(GetFrontBuffer(fb));
3158 return fb;
3159}
3160
3162{
3164
3165 IDirect3DSurface8 * bb;
3166 SurfaceClass *surf=NULL;
3167 DX8CALL(GetBackBuffer(num,D3DBACKBUFFER_TYPE_MONO,&bb));
3168 if (bb)
3169 {
3170 surf=NEW_REF(SurfaceClass,(bb));
3171 bb->Release();
3172 }
3173
3174 return surf;
3175}
3176
3177
3179DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format)
3180{
3182 DX8_Assert();
3184
3185 // Use the current display format if format isn't specified
3186 if (format==WW3D_FORMAT_UNKNOWN) {
3187 D3DDISPLAYMODE mode;
3188 DX8CALL(GetDisplayMode(&mode));
3189 format=D3DFormat_To_WW3DFormat(mode.Format);
3190 }
3191
3192 // If render target format isn't supported return NULL
3193 if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format)) {
3194 WWDEBUG_SAY(("DX8Wrapper - Render target format is not supported\r\n"));
3195 return NULL;
3196 }
3197
3198 //
3199 // Note: We're going to force the width and height to be powers of two and equal
3200 //
3201 const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps();
3202 float poweroftwosize = width;
3203 if (height > 0 && height < width) {
3204 poweroftwosize = height;
3205 }
3206 poweroftwosize = ::Find_POT (poweroftwosize);
3207
3208 if (poweroftwosize>dx8caps.MaxTextureWidth) {
3209 poweroftwosize=dx8caps.MaxTextureWidth;
3210 }
3211 if (poweroftwosize>dx8caps.MaxTextureHeight) {
3212 poweroftwosize=dx8caps.MaxTextureHeight;
3213 }
3214
3215 width = height = poweroftwosize;
3216
3217 //
3218 // Attempt to create the render target
3219 //
3220 TextureClass * tex = NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true));
3221
3222 // 3dfx drivers are lying in the CheckDeviceFormat call and claiming
3223 // that they support render targets!
3224 if (tex->Peek_D3D_Base_Texture() == NULL)
3225 {
3226 WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!\r\n"));
3227 REF_PTR_RELEASE(tex);
3228 }
3229
3230 return tex;
3231}
3232
3233//**********************************************************************************************
3235
3238(
3239 int width,
3240 int height,
3241 WW3DFormat format,
3242 WW3DZFormat zformat,
3243 TextureClass** target,
3244 ZTextureClass** depth_buffer
3245)
3246{
3248 DX8_Assert();
3250
3251 // Use the current display format if format isn't specified
3252 if (format==WW3D_FORMAT_UNKNOWN)
3253 {
3254 *target=NULL;
3255 *depth_buffer=NULL;
3256 return;
3257/* D3DDISPLAYMODE mode;
3258 DX8CALL(GetDisplayMode(&mode));
3259 format=D3DFormat_To_WW3DFormat(mode.Format);*/
3260 }
3261
3262 // If render target format isn't supported return NULL
3263 if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format) ||
3264 !Get_Current_Caps()->Support_Depth_Stencil_Format(zformat))
3265 {
3266 WWDEBUG_SAY(("DX8Wrapper - Render target with depth format is not supported\r\n"));
3267 return;
3268 }
3269
3270 // Note: We're going to force the width and height to be powers of two and equal
3271 const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps();
3272 float poweroftwosize = width;
3273 if (height > 0 && height < width)
3274 {
3275 poweroftwosize = height;
3276 }
3277 poweroftwosize = ::Find_POT (poweroftwosize);
3278
3279 if (poweroftwosize>dx8caps.MaxTextureWidth)
3280 {
3281 poweroftwosize=dx8caps.MaxTextureWidth;
3282 }
3283
3284 if (poweroftwosize>dx8caps.MaxTextureHeight)
3285 {
3286 poweroftwosize=dx8caps.MaxTextureHeight;
3287 }
3288
3289 width = height = poweroftwosize;
3290
3291 // Attempt to create the render target
3293
3294 // 3dfx drivers are lying in the CheckDeviceFormat call and claiming
3295 // that they support render targets!
3296 if (tex->Peek_D3D_Base_Texture() == NULL)
3297 {
3298 WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!\r\n"));
3299 REF_PTR_RELEASE(tex);
3300 }
3301
3302 *target=tex;
3303
3304 // attempt to create the depth stencil buffer
3305 *depth_buffer=NEW_REF
3306 (
3308 (
3309 width,
3310 height,
3311 zformat,
3314 )
3315 );
3316}
3317
3323(
3324 TextureClass* texture,
3325 ZTextureClass* ztexture
3326)
3327{
3328 WWASSERT(texture!=NULL);
3329 IDirect3DSurface8 * d3d_surf = texture->Get_D3D_Surface_Level();
3330 WWASSERT(d3d_surf != NULL);
3331
3332 IDirect3DSurface8* d3d_zbuf=NULL;
3333 if (ztexture!=NULL)
3334 {
3335
3336 d3d_zbuf=ztexture->Get_D3D_Surface_Level();
3337 WWASSERT(d3d_zbuf!=NULL);
3338 Set_Render_Target(d3d_surf,d3d_zbuf);
3339 d3d_zbuf->Release();
3340 }
3341 else
3342 {
3343 Set_Render_Target(d3d_surf,true);
3344 }
3345 d3d_surf->Release();
3346
3347 IsRenderToTexture = true;
3348}
3349
3350void
3351DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain)
3352{
3354 WWASSERT (swap_chain != NULL);
3355
3356 //
3357 // Get the back buffer for the swap chain
3358 //
3359 LPDIRECT3DSURFACE8 render_target = NULL;
3360 swap_chain->GetBackBuffer (0, D3DBACKBUFFER_TYPE_MONO, &render_target);
3361
3362 //
3363 // Set this back buffer as the render targer
3364 //
3365 Set_Render_Target (render_target, true);
3366
3367 //
3368 // Release our hold on the back buffer
3369 //
3370 if (render_target != NULL) {
3371 render_target->Release ();
3372 render_target = NULL;
3373 }
3374
3375 IsRenderToTexture = false;
3376
3377 return ;
3378}
3379
3380void
3381DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default_depth_buffer)
3382{
3383//#ifndef _XBOX
3385 DX8_Assert();
3386
3387 //
3388 // Should we restore the default render target set a new one?
3389 //
3390 if (render_target == NULL || render_target == DefaultRenderTarget)
3391 {
3392 // If there is currently a custom render target, default must NOT be NULL.
3394 {
3396 }
3397
3398 //
3399 // Restore the default render target
3400 //
3401 if (DefaultRenderTarget != NULL)
3402 {
3404 DefaultRenderTarget->Release ();
3406 if (DefaultDepthBuffer)
3407 {
3408 DefaultDepthBuffer->Release ();
3410 }
3411 }
3412
3413 //
3414 // Release our hold on the "current" render target
3415 //
3416 if (CurrentRenderTarget != NULL)
3417 {
3418 CurrentRenderTarget->Release ();
3420 }
3421
3423 {
3424 CurrentDepthBuffer->Release();
3426 }
3427
3428 }
3429 else if (render_target != CurrentRenderTarget)
3430 {
3432
3433 //
3434 // We'll need the depth buffer later...
3435 //
3436 if (DefaultDepthBuffer == NULL)
3437 {
3438// IDirect3DSurface8 *depth_buffer = NULL;
3439 DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer));
3440 }
3441
3442 //
3443 // Get a pointer to the default render target (if necessary)
3444 //
3445 if (DefaultRenderTarget == NULL)
3446 {
3447 DX8CALL(GetRenderTarget (&DefaultRenderTarget));
3448 }
3449
3450 //
3451 // Release our hold on the old "current" render target
3452 //
3453 if (CurrentRenderTarget != NULL)
3454 {
3455 CurrentRenderTarget->Release ();
3457 }
3458
3460 {
3461 CurrentDepthBuffer->Release();
3463 }
3464
3465 //
3466 // Keep a copy of the current render target (for housekeeping)
3467 //
3468 CurrentRenderTarget = render_target;
3470 if (CurrentRenderTarget != NULL)
3471 {
3472 CurrentRenderTarget->AddRef ();
3473
3474 //
3475 // Switch render targets
3476 //
3477 if (use_default_depth_buffer)
3478 {
3480 }
3481 else
3482 {
3483 DX8CALL(SetRenderTarget (CurrentRenderTarget, NULL));
3484 }
3485 }
3486 }
3487
3488 //
3489 // Free our hold on the depth buffer
3490 //
3491// if (depth_buffer != NULL) {
3492// depth_buffer->Release ();
3493// depth_buffer = NULL;
3494// }
3495
3496 IsRenderToTexture = false;
3497 return ;
3498//#endif // XBOX
3499}
3500
3501
3502//**********************************************************************************************
3504
3507(
3508 IDirect3DSurface8* render_target,
3509 IDirect3DSurface8* depth_buffer
3510)
3511{
3512//#ifndef _XBOX
3514 DX8_Assert();
3515
3516 //
3517 // Should we restore the default render target set a new one?
3518 //
3519 if (render_target == NULL || render_target == DefaultRenderTarget)
3520 {
3521 // If there is currently a custom render target, default must NOT be NULL.
3523 {
3525 }
3526
3527 //
3528 // Restore the default render target
3529 //
3530 if (DefaultRenderTarget != NULL)
3531 {
3533 DefaultRenderTarget->Release ();
3535 if (DefaultDepthBuffer)
3536 {
3537 DefaultDepthBuffer->Release ();
3539 }
3540 }
3541
3542 //
3543 // Release our hold on the "current" render target
3544 //
3545 if (CurrentRenderTarget != NULL)
3546 {
3547 CurrentRenderTarget->Release ();
3549 }
3550
3552 {
3553 CurrentDepthBuffer->Release();
3555 }
3556 }
3557 else if (render_target != CurrentRenderTarget)
3558 {
3560
3561 //
3562 // We'll need the depth buffer later...
3563 //
3564 if (DefaultDepthBuffer == NULL)
3565 {
3566// IDirect3DSurface8 *depth_buffer = NULL;
3567 DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer));
3568 }
3569
3570 //
3571 // Get a pointer to the default render target (if necessary)
3572 //
3573 if (DefaultRenderTarget == NULL)
3574 {
3575 DX8CALL(GetRenderTarget (&DefaultRenderTarget));
3576 }
3577
3578 //
3579 // Release our hold on the old "current" render target
3580 //
3581 if (CurrentRenderTarget != NULL)
3582 {
3583 CurrentRenderTarget->Release ();
3585 }
3586
3588 {
3589 CurrentDepthBuffer->Release();
3591 }
3592
3593 //
3594 // Keep a copy of the current render target (for housekeeping)
3595 //
3596 CurrentRenderTarget = render_target;
3597 CurrentDepthBuffer = depth_buffer;
3599 if (CurrentRenderTarget != NULL)
3600 {
3601 CurrentRenderTarget->AddRef ();
3602 CurrentDepthBuffer->AddRef();
3603
3604 //
3605 // Switch render targets
3606 //
3608 }
3609 }
3610
3611 IsRenderToTexture=true;
3612//#endif // XBOX
3613}
3614
3615
3616IDirect3DSwapChain8 *
3618{
3619 DX8_Assert();
3620
3621 //
3622 // Configure the presentation parameters for a windowed render target
3623 //
3624 D3DPRESENT_PARAMETERS params = { 0 };
3625 params.BackBufferFormat = _PresentParameters.BackBufferFormat;
3626 params.BackBufferCount = 1;
3627 params.MultiSampleType = D3DMULTISAMPLE_NONE;
3628 params.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
3629 params.hDeviceWindow = render_window;
3630 params.Windowed = TRUE;
3631 params.EnableAutoDepthStencil = TRUE;
3632 params.AutoDepthStencilFormat = _PresentParameters.AutoDepthStencilFormat;
3633 params.Flags = 0;
3634 params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
3635 params.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
3636
3637 //
3638 // Create the swap chain
3639 //
3640 IDirect3DSwapChain8 *swap_chain = NULL;
3641 DX8CALL(CreateAdditionalSwapChain(&params, &swap_chain));
3642 return swap_chain;
3643}
3644
3646{
3647 DX8_Assert();
3648 DX8CALL(ResourceManagerDiscardBytes(bytes));
3649}
3650
3652{
3653 DX8_Assert();
3655 return DX8Wrapper::_Get_D3D_Device8()->GetAvailableTextureMem();
3656}
3657
3658// Converts a linear gamma ramp to one that is controlled by:
3659// Gamma - controls the curvature of the middle of the curve
3660// Bright - controls the minimum value of the curve
3661// Contrast - controls the difference between the maximum and the minimum of the curve
3662void DX8Wrapper::Set_Gamma(float gamma,float bright,float contrast,bool calibrate,bool uselimit)
3663{
3664 gamma=Bound(gamma,0.6f,6.0f);
3665 bright=Bound(bright,-0.5f,0.5f);
3666 contrast=Bound(contrast,0.5f,2.0f);
3667 float oo_gamma=1.0f/gamma;
3668
3669 DX8_Assert();
3671
3672 DWORD flag=(calibrate?D3DSGR_CALIBRATE:D3DSGR_NO_CALIBRATION);
3673
3674 D3DGAMMARAMP ramp;
3675 float limit;
3676
3677 // IML: I'm not really sure what the intent of the 'limit' variable is. It does not produce useful results for my purposes.
3678 if (uselimit) {
3679 limit=(contrast-1)/2*contrast;
3680 } else {
3681 limit = 0.0f;
3682 }
3683
3684 // HY - arrived at this equation after much trial and error.
3685 for (int i=0; i<256; i++) {
3686 float in,out;
3687 in=i/256.0f;
3688 float x=in-limit;
3689 x=Bound(x,0.0f,1.0f);
3690 x=powf(x,oo_gamma);
3691 out=contrast*x+bright;
3692 out=Bound(out,0.0f,1.0f);
3693 ramp.red[i]=(WORD) (out*65535);
3694 ramp.green[i]=(WORD) (out*65535);
3695 ramp.blue[i]=(WORD) (out*65535);
3696 }
3697
3698 if (Get_Current_Caps()->Support_Gamma()) {
3699 DX8Wrapper::_Get_D3D_Device8()->SetGammaRamp(flag,&ramp);
3700 } else {
3701 HWND hwnd = GetDesktopWindow();
3702 HDC hdc = GetDC(hwnd);
3703 if (hdc)
3704 {
3705 SetDeviceGammaRamp (hdc, &ramp);
3706 ReleaseDC (hwnd, hdc);
3707 }
3708 }
3709}
3710
3711//**********************************************************************************************
3713
3716{
3717 SNAPSHOT_SAY(("DX8Wrapper::Apply_Default_State()\n"));
3718
3719 // only set states used in game
3720 Set_DX8_Render_State(D3DRS_ZENABLE, TRUE);
3721// Set_DX8_Render_State(D3DRS_FILLMODE, D3DFILL_SOLID);
3722 Set_DX8_Render_State(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3723 //Set_DX8_Render_State(D3DRS_LINEPATTERN, 0);
3724 Set_DX8_Render_State(D3DRS_ZWRITEENABLE, TRUE);
3725 Set_DX8_Render_State(D3DRS_ALPHATESTENABLE, FALSE);
3726 //Set_DX8_Render_State(D3DRS_LASTPIXEL, FALSE);
3727 Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ONE);
3728 Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ZERO);
3729 Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW);
3730 Set_DX8_Render_State(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3731 Set_DX8_Render_State(D3DRS_ALPHAREF, 0);
3732 Set_DX8_Render_State(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL);
3733 Set_DX8_Render_State(D3DRS_DITHERENABLE, FALSE);
3734 Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE, FALSE);
3735 Set_DX8_Render_State(D3DRS_FOGENABLE, FALSE);
3736 Set_DX8_Render_State(D3DRS_SPECULARENABLE, FALSE);
3737// Set_DX8_Render_State(D3DRS_ZVISIBLE, FALSE);
3738// Set_DX8_Render_State(D3DRS_FOGCOLOR, 0);
3739// Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3740// Set_DX8_Render_State(D3DRS_FOGSTART, 0);
3741
3742// Set_DX8_Render_State(D3DRS_FOGEND, WWMath::Float_As_Int(1.0f));
3743// Set_DX8_Render_State(D3DRS_FOGDENSITY, WWMath::Float_As_Int(1.0f));
3744
3745 //Set_DX8_Render_State(D3DRS_EDGEANTIALIAS, FALSE);
3746 Set_DX8_Render_State(D3DRS_ZBIAS, 0);
3747// Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, FALSE);
3748 Set_DX8_Render_State(D3DRS_STENCILENABLE, FALSE);
3749 Set_DX8_Render_State(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3750 Set_DX8_Render_State(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3751 Set_DX8_Render_State(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3752 Set_DX8_Render_State(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3753 Set_DX8_Render_State(D3DRS_STENCILREF, 0);
3754 Set_DX8_Render_State(D3DRS_STENCILMASK, 0xffffffff);
3755 Set_DX8_Render_State(D3DRS_STENCILWRITEMASK, 0xffffffff);
3756 Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0);
3757/* Set_DX8_Render_State(D3DRS_WRAP0, D3DWRAP_U| D3DWRAP_V);
3758 Set_DX8_Render_State(D3DRS_WRAP1, D3DWRAP_U| D3DWRAP_V);
3759 Set_DX8_Render_State(D3DRS_WRAP2, D3DWRAP_U| D3DWRAP_V);
3760 Set_DX8_Render_State(D3DRS_WRAP3, D3DWRAP_U| D3DWRAP_V);
3761 Set_DX8_Render_State(D3DRS_WRAP4, D3DWRAP_U| D3DWRAP_V);
3762 Set_DX8_Render_State(D3DRS_WRAP5, D3DWRAP_U| D3DWRAP_V);
3763 Set_DX8_Render_State(D3DRS_WRAP6, D3DWRAP_U| D3DWRAP_V);
3764 Set_DX8_Render_State(D3DRS_WRAP7, D3DWRAP_U| D3DWRAP_V);*/
3765 Set_DX8_Render_State(D3DRS_CLIPPING, TRUE);
3766 Set_DX8_Render_State(D3DRS_LIGHTING, FALSE);
3767 //Set_DX8_Render_State(D3DRS_AMBIENT, 0);
3768// Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3769 Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE);
3770/* Set_DX8_Render_State(D3DRS_LOCALVIEWER, TRUE);
3771 Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE);
3772 Set_DX8_Render_State(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3773 Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3774 Set_DX8_Render_State(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
3775 Set_DX8_Render_State(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3776 Set_DX8_Render_State(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);*/
3777 //Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, 0);
3778 Set_DX8_Render_State(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3779 //Set_DX8_Render_State(D3DRS_POINTSIZE, 0x3f800000);
3780 //Set_DX8_Render_State(D3DRS_POINTSIZE_MIN, 0);
3781 //Set_DX8_Render_State(D3DRS_POINTSPRITEENABLE, FALSE);
3782 //Set_DX8_Render_State(D3DRS_POINTSCALEENABLE, FALSE);
3783 //Set_DX8_Render_State(D3DRS_POINTSCALE_A, 0);
3784 //Set_DX8_Render_State(D3DRS_POINTSCALE_B, 0);
3785 //Set_DX8_Render_State(D3DRS_POINTSCALE_C, 0);
3786 //Set_DX8_Render_State(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3787 //Set_DX8_Render_State(D3DRS_MULTISAMPLEMASK, 0xffffffff);
3788 //Set_DX8_Render_State(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3789 //Set_DX8_Render_State(D3DRS_PATCHSEGMENTS, 0x3f800000);
3790 //Set_DX8_Render_State(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
3791 //Set_DX8_Render_State(D3DRS_POINTSIZE_MAX, Float_At_Int(64.0f));
3792 //Set_DX8_Render_State(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3793 Set_DX8_Render_State(D3DRS_COLORWRITEENABLE, 0x0000000f);
3794 //Set_DX8_Render_State(D3DRS_TWEENFACTOR, 0);
3795 Set_DX8_Render_State(D3DRS_BLENDOP, D3DBLENDOP_ADD);
3796 //Set_DX8_Render_State(D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3797 //Set_DX8_Render_State(D3DRS_NORMALORDER, D3DORDER_LINEAR);
3798
3799 // disable TSS stages
3800 int i;
3801 for (i=0; i<CurrentCaps->Get_Max_Textures_Per_Pass(); i++)
3802 {
3803 Set_DX8_Texture_Stage_State(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
3804 Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3805 Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
3806
3807 Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
3808 Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
3809 Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
3810
3811 /*Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT00, 0);
3812 Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT01, 0);
3813 Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT10, 0);
3814 Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVMAT11, 0);
3815 Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVLSCALE, 0);
3816 Set_DX8_Texture_Stage_State(i, D3DTSS_BUMPENVLOFFSET, 0);*/
3817
3818 Set_DX8_Texture_Stage_State(i, D3DTSS_TEXCOORDINDEX, i);
3819
3820
3821 Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3822 Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3823 Set_DX8_Texture_Stage_State(i, D3DTSS_BORDERCOLOR, 0);
3824// Set_DX8_Texture_Stage_State(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
3825// Set_DX8_Texture_Stage_State(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
3826// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
3827// Set_DX8_Texture_Stage_State(i, D3DTSS_MIPMAPLODBIAS, 0);
3828// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXMIPLEVEL, 0);
3829// Set_DX8_Texture_Stage_State(i, D3DTSS_MAXANISOTROPY, 1);
3830 //Set_DX8_Texture_Stage_State(i, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP);
3831 //Set_DX8_Texture_Stage_State(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
3832 //Set_DX8_Texture_Stage_State(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
3833 //Set_DX8_Texture_Stage_State(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
3834
3835 Set_DX8_Texture_Stage_State(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3836 Set_Texture(i,NULL);
3837 }
3838
3839// DX8Wrapper::Set_Material(NULL);
3840 VertexMaterialClass::Apply_Null();
3841
3842 for (unsigned index=0;index<4;++index) {
3843 SNAPSHOT_SAY(("Clearing light %d to NULL\n",index));
3844 Set_DX8_Light(index,NULL);
3845 }
3846
3847 // set up simple default TSS
3849 memset(vconst,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS);
3851
3853 memset(pconst,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS);
3855
3858
3860}
3861
3862const char* DX8Wrapper::Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state)
3863{
3864 switch (state) {
3865 case D3DRS_ZENABLE : return "D3DRS_ZENABLE";
3866 case D3DRS_FILLMODE : return "D3DRS_FILLMODE";
3867 case D3DRS_SHADEMODE : return "D3DRS_SHADEMODE";
3868 case D3DRS_LINEPATTERN : return "D3DRS_LINEPATTERN";
3869 case D3DRS_ZWRITEENABLE : return "D3DRS_ZWRITEENABLE";
3870 case D3DRS_ALPHATESTENABLE : return "D3DRS_ALPHATESTENABLE";
3871 case D3DRS_LASTPIXEL : return "D3DRS_LASTPIXEL";
3872 case D3DRS_SRCBLEND : return "D3DRS_SRCBLEND";
3873 case D3DRS_DESTBLEND : return "D3DRS_DESTBLEND";
3874 case D3DRS_CULLMODE : return "D3DRS_CULLMODE";
3875 case D3DRS_ZFUNC : return "D3DRS_ZFUNC";
3876 case D3DRS_ALPHAREF : return "D3DRS_ALPHAREF";
3877 case D3DRS_ALPHAFUNC : return "D3DRS_ALPHAFUNC";
3878 case D3DRS_DITHERENABLE : return "D3DRS_DITHERENABLE";
3879 case D3DRS_ALPHABLENDENABLE : return "D3DRS_ALPHABLENDENABLE";
3880 case D3DRS_FOGENABLE : return "D3DRS_FOGENABLE";
3881 case D3DRS_SPECULARENABLE : return "D3DRS_SPECULARENABLE";
3882 case D3DRS_ZVISIBLE : return "D3DRS_ZVISIBLE";
3883 case D3DRS_FOGCOLOR : return "D3DRS_FOGCOLOR";
3884 case D3DRS_FOGTABLEMODE : return "D3DRS_FOGTABLEMODE";
3885 case D3DRS_FOGSTART : return "D3DRS_FOGSTART";
3886 case D3DRS_FOGEND : return "D3DRS_FOGEND";
3887 case D3DRS_FOGDENSITY : return "D3DRS_FOGDENSITY";
3888 case D3DRS_EDGEANTIALIAS : return "D3DRS_EDGEANTIALIAS";
3889 case D3DRS_ZBIAS : return "D3DRS_ZBIAS";
3890 case D3DRS_RANGEFOGENABLE : return "D3DRS_RANGEFOGENABLE";
3891 case D3DRS_STENCILENABLE : return "D3DRS_STENCILENABLE";
3892 case D3DRS_STENCILFAIL : return "D3DRS_STENCILFAIL";
3893 case D3DRS_STENCILZFAIL : return "D3DRS_STENCILZFAIL";
3894 case D3DRS_STENCILPASS : return "D3DRS_STENCILPASS";
3895 case D3DRS_STENCILFUNC : return "D3DRS_STENCILFUNC";
3896 case D3DRS_STENCILREF : return "D3DRS_STENCILREF";
3897 case D3DRS_STENCILMASK : return "D3DRS_STENCILMASK";
3898 case D3DRS_STENCILWRITEMASK : return "D3DRS_STENCILWRITEMASK";
3899 case D3DRS_TEXTUREFACTOR : return "D3DRS_TEXTUREFACTOR";
3900 case D3DRS_WRAP0 : return "D3DRS_WRAP0";
3901 case D3DRS_WRAP1 : return "D3DRS_WRAP1";
3902 case D3DRS_WRAP2 : return "D3DRS_WRAP2";
3903 case D3DRS_WRAP3 : return "D3DRS_WRAP3";
3904 case D3DRS_WRAP4 : return "D3DRS_WRAP4";
3905 case D3DRS_WRAP5 : return "D3DRS_WRAP5";
3906 case D3DRS_WRAP6 : return "D3DRS_WRAP6";
3907 case D3DRS_WRAP7 : return "D3DRS_WRAP7";
3908 case D3DRS_CLIPPING : return "D3DRS_CLIPPING";
3909 case D3DRS_LIGHTING : return "D3DRS_LIGHTING";
3910 case D3DRS_AMBIENT : return "D3DRS_AMBIENT";
3911 case D3DRS_FOGVERTEXMODE : return "D3DRS_FOGVERTEXMODE";
3912 case D3DRS_COLORVERTEX : return "D3DRS_COLORVERTEX";
3913 case D3DRS_LOCALVIEWER : return "D3DRS_LOCALVIEWER";
3914 case D3DRS_NORMALIZENORMALS : return "D3DRS_NORMALIZENORMALS";
3915 case D3DRS_DIFFUSEMATERIALSOURCE : return "D3DRS_DIFFUSEMATERIALSOURCE";
3916 case D3DRS_SPECULARMATERIALSOURCE : return "D3DRS_SPECULARMATERIALSOURCE";
3917 case D3DRS_AMBIENTMATERIALSOURCE : return "D3DRS_AMBIENTMATERIALSOURCE";
3918 case D3DRS_EMISSIVEMATERIALSOURCE : return "D3DRS_EMISSIVEMATERIALSOURCE";
3919 case D3DRS_VERTEXBLEND : return "D3DRS_VERTEXBLEND";
3920 case D3DRS_CLIPPLANEENABLE : return "D3DRS_CLIPPLANEENABLE";
3921 case D3DRS_SOFTWAREVERTEXPROCESSING : return "D3DRS_SOFTWAREVERTEXPROCESSING";
3922 case D3DRS_POINTSIZE : return "D3DRS_POINTSIZE";
3923 case D3DRS_POINTSIZE_MIN : return "D3DRS_POINTSIZE_MIN";
3924 case D3DRS_POINTSPRITEENABLE : return "D3DRS_POINTSPRITEENABLE";
3925 case D3DRS_POINTSCALEENABLE : return "D3DRS_POINTSCALEENABLE";
3926 case D3DRS_POINTSCALE_A : return "D3DRS_POINTSCALE_A";
3927 case D3DRS_POINTSCALE_B : return "D3DRS_POINTSCALE_B";
3928 case D3DRS_POINTSCALE_C : return "D3DRS_POINTSCALE_C";
3929 case D3DRS_MULTISAMPLEANTIALIAS : return "D3DRS_MULTISAMPLEANTIALIAS";
3930 case D3DRS_MULTISAMPLEMASK : return "D3DRS_MULTISAMPLEMASK";
3931 case D3DRS_PATCHEDGESTYLE : return "D3DRS_PATCHEDGESTYLE";
3932 case D3DRS_PATCHSEGMENTS : return "D3DRS_PATCHSEGMENTS";
3933 case D3DRS_DEBUGMONITORTOKEN : return "D3DRS_DEBUGMONITORTOKEN";
3934 case D3DRS_POINTSIZE_MAX : return "D3DRS_POINTSIZE_MAX";
3935 case D3DRS_INDEXEDVERTEXBLENDENABLE : return "D3DRS_INDEXEDVERTEXBLENDENABLE";
3936 case D3DRS_COLORWRITEENABLE : return "D3DRS_COLORWRITEENABLE";
3937 case D3DRS_TWEENFACTOR : return "D3DRS_TWEENFACTOR";
3938 case D3DRS_BLENDOP : return "D3DRS_BLENDOP";
3939// case D3DRS_POSITIONORDER : return "D3DRS_POSITIONORDER";
3940// case D3DRS_NORMALORDER : return "D3DRS_NORMALORDER";
3941 default : return "UNKNOWN";
3942 }
3943}
3944
3945const char* DX8Wrapper::Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state)
3946{
3947 switch (state) {
3948 case D3DTSS_COLOROP : return "D3DTSS_COLOROP";
3949 case D3DTSS_COLORARG1 : return "D3DTSS_COLORARG1";
3950 case D3DTSS_COLORARG2 : return "D3DTSS_COLORARG2";
3951 case D3DTSS_ALPHAOP : return "D3DTSS_ALPHAOP";
3952 case D3DTSS_ALPHAARG1 : return "D3DTSS_ALPHAARG1";
3953 case D3DTSS_ALPHAARG2 : return "D3DTSS_ALPHAARG2";
3954 case D3DTSS_BUMPENVMAT00 : return "D3DTSS_BUMPENVMAT00";
3955 case D3DTSS_BUMPENVMAT01 : return "D3DTSS_BUMPENVMAT01";
3956 case D3DTSS_BUMPENVMAT10 : return "D3DTSS_BUMPENVMAT10";
3957 case D3DTSS_BUMPENVMAT11 : return "D3DTSS_BUMPENVMAT11";
3958 case D3DTSS_TEXCOORDINDEX : return "D3DTSS_TEXCOORDINDEX";
3959 case D3DTSS_ADDRESSU : return "D3DTSS_ADDRESSU";
3960 case D3DTSS_ADDRESSV : return "D3DTSS_ADDRESSV";
3961 case D3DTSS_BORDERCOLOR : return "D3DTSS_BORDERCOLOR";
3962 case D3DTSS_MAGFILTER : return "D3DTSS_MAGFILTER";
3963 case D3DTSS_MINFILTER : return "D3DTSS_MINFILTER";
3964 case D3DTSS_MIPFILTER : return "D3DTSS_MIPFILTER";
3965 case D3DTSS_MIPMAPLODBIAS : return "D3DTSS_MIPMAPLODBIAS";
3966 case D3DTSS_MAXMIPLEVEL : return "D3DTSS_MAXMIPLEVEL";
3967 case D3DTSS_MAXANISOTROPY : return "D3DTSS_MAXANISOTROPY";
3968 case D3DTSS_BUMPENVLSCALE : return "D3DTSS_BUMPENVLSCALE";
3969 case D3DTSS_BUMPENVLOFFSET : return "D3DTSS_BUMPENVLOFFSET";
3970 case D3DTSS_TEXTURETRANSFORMFLAGS : return "D3DTSS_TEXTURETRANSFORMFLAGS";
3971 case D3DTSS_ADDRESSW : return "D3DTSS_ADDRESSW";
3972 case D3DTSS_COLORARG0 : return "D3DTSS_COLORARG0";
3973 case D3DTSS_ALPHAARG0 : return "D3DTSS_ALPHAARG0";
3974 case D3DTSS_RESULTARG : return "D3DTSS_RESULTARG";
3975 default : return "UNKNOWN";
3976 }
3977}
3978
3979void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTATETYPE state, unsigned value)
3980{
3981 switch (state) {
3982 case D3DRS_ZENABLE:
3984 break;
3985
3986 case D3DRS_FILLMODE:
3988 break;
3989
3990 case D3DRS_SHADEMODE:
3992 break;
3993
3994 case D3DRS_LINEPATTERN:
3995 case D3DRS_FOGCOLOR:
3996 case D3DRS_ALPHAREF:
3997 case D3DRS_STENCILMASK:
3998 case D3DRS_STENCILWRITEMASK:
3999 case D3DRS_TEXTUREFACTOR:
4000 case D3DRS_AMBIENT:
4001 case D3DRS_CLIPPLANEENABLE:
4002 case D3DRS_MULTISAMPLEMASK:
4003 name.Format("0x%x",value);
4004 break;
4005
4006 case D3DRS_ZWRITEENABLE:
4007 case D3DRS_ALPHATESTENABLE:
4008 case D3DRS_LASTPIXEL:
4009 case D3DRS_DITHERENABLE:
4010 case D3DRS_ALPHABLENDENABLE:
4011 case D3DRS_FOGENABLE:
4012 case D3DRS_SPECULARENABLE:
4013 case D3DRS_STENCILENABLE:
4014 case D3DRS_RANGEFOGENABLE:
4015 case D3DRS_EDGEANTIALIAS:
4016 case D3DRS_CLIPPING:
4017 case D3DRS_LIGHTING:
4018 case D3DRS_COLORVERTEX:
4019 case D3DRS_LOCALVIEWER:
4020 case D3DRS_NORMALIZENORMALS:
4021 case D3DRS_SOFTWAREVERTEXPROCESSING:
4022 case D3DRS_POINTSPRITEENABLE:
4023 case D3DRS_POINTSCALEENABLE:
4024 case D3DRS_MULTISAMPLEANTIALIAS:
4025 case D3DRS_INDEXEDVERTEXBLENDENABLE:
4026 name=value ? "TRUE" : "FALSE";
4027 break;
4028
4029 case D3DRS_SRCBLEND:
4030 case D3DRS_DESTBLEND:
4032 break;
4033
4034 case D3DRS_CULLMODE:
4036 break;
4037
4038 case D3DRS_ZFUNC:
4039 case D3DRS_ALPHAFUNC:
4040 case D3DRS_STENCILFUNC:
4042 break;
4043
4044 case D3DRS_ZVISIBLE:
4045 name="NOTSUPPORTED";
4046 break;
4047
4048 case D3DRS_FOGTABLEMODE:
4049 case D3DRS_FOGVERTEXMODE:
4051 break;
4052
4053 case D3DRS_FOGSTART:
4054 case D3DRS_FOGEND:
4055 case D3DRS_FOGDENSITY:
4056 case D3DRS_POINTSIZE:
4057 case D3DRS_POINTSIZE_MIN:
4058 case D3DRS_POINTSCALE_A:
4059 case D3DRS_POINTSCALE_B:
4060 case D3DRS_POINTSCALE_C:
4061 case D3DRS_PATCHSEGMENTS:
4062 case D3DRS_POINTSIZE_MAX:
4063 case D3DRS_TWEENFACTOR:
4064 name.Format("%f",*(float*)&value);
4065 break;
4066
4067 case D3DRS_ZBIAS:
4068 case D3DRS_STENCILREF:
4069 name.Format("%d",value);
4070 break;
4071
4072 case D3DRS_STENCILFAIL:
4073 case D3DRS_STENCILZFAIL:
4074 case D3DRS_STENCILPASS:
4076 break;
4077
4078 case D3DRS_WRAP0:
4079 case D3DRS_WRAP1:
4080 case D3DRS_WRAP2:
4081 case D3DRS_WRAP3:
4082 case D3DRS_WRAP4:
4083 case D3DRS_WRAP5:
4084 case D3DRS_WRAP6:
4085 case D3DRS_WRAP7:
4086 name="0";
4087 if (value&D3DWRAP_U) name+="|D3DWRAP_U";
4088 if (value&D3DWRAP_V) name+="|D3DWRAP_V";
4089 if (value&D3DWRAP_W) name+="|D3DWRAP_W";
4090 break;
4091
4092 case D3DRS_DIFFUSEMATERIALSOURCE:
4093 case D3DRS_SPECULARMATERIALSOURCE:
4094 case D3DRS_AMBIENTMATERIALSOURCE:
4095 case D3DRS_EMISSIVEMATERIALSOURCE:
4097 break;
4098
4099 case D3DRS_VERTEXBLEND:
4101 break;
4102
4103 case D3DRS_PATCHEDGESTYLE:
4105 break;
4106
4107 case D3DRS_DEBUGMONITORTOKEN:
4109 break;
4110
4111 case D3DRS_COLORWRITEENABLE:
4112 name="0";
4113 if (value&D3DCOLORWRITEENABLE_RED) name+="|D3DCOLORWRITEENABLE_RED";
4114 if (value&D3DCOLORWRITEENABLE_GREEN) name+="|D3DCOLORWRITEENABLE_GREEN";
4115 if (value&D3DCOLORWRITEENABLE_BLUE) name+="|D3DCOLORWRITEENABLE_BLUE";
4116 if (value&D3DCOLORWRITEENABLE_ALPHA) name+="|D3DCOLORWRITEENABLE_ALPHA";
4117 break;
4118 case D3DRS_BLENDOP:
4120 break;
4121 default:
4122 name.Format("UNKNOWN (%d)",value);
4123 break;
4124 }
4125}
4126
4127void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTEXTURESTAGESTATETYPE state, unsigned value)
4128{
4129 switch (state) {
4130 case D3DTSS_COLOROP:
4131 case D3DTSS_ALPHAOP:
4133 break;
4134
4135 case D3DTSS_COLORARG0:
4136 case D3DTSS_COLORARG1:
4137 case D3DTSS_COLORARG2:
4138 case D3DTSS_ALPHAARG0:
4139 case D3DTSS_ALPHAARG1:
4140 case D3DTSS_ALPHAARG2:
4141 case D3DTSS_RESULTARG:
4143 break;
4144
4145 case D3DTSS_ADDRESSU:
4146 case D3DTSS_ADDRESSV:
4147 case D3DTSS_ADDRESSW:
4149 break;
4150
4151 case D3DTSS_MAGFILTER:
4152 case D3DTSS_MINFILTER:
4153 case D3DTSS_MIPFILTER:
4155 break;
4156
4157 case D3DTSS_TEXTURETRANSFORMFLAGS:
4159
4160 // Floating point values
4161 case D3DTSS_MIPMAPLODBIAS:
4162 case D3DTSS_BUMPENVMAT00:
4163 case D3DTSS_BUMPENVMAT01:
4164 case D3DTSS_BUMPENVMAT10:
4165 case D3DTSS_BUMPENVMAT11:
4166 case D3DTSS_BUMPENVLSCALE:
4167 case D3DTSS_BUMPENVLOFFSET:
4168 name.Format("%f",*(float*)&value);
4169 break;
4170
4171 case D3DTSS_TEXCOORDINDEX:
4172 if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACENORMAL) {
4173 name.Format("D3DTSS_TCI_CAMERASPACENORMAL|%d",value&0xffff);
4174 }
4175 else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEPOSITION) {
4176 name.Format("D3DTSS_TCI_CAMERASPACEPOSITION|%d",value&0xffff);
4177 }
4178 else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) {
4179 name.Format("D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR|%d",value&0xffff);
4180 }
4181 else {
4182 name.Format("%d",value);
4183 }
4184 break;
4185
4186 // Integer value
4187 case D3DTSS_MAXMIPLEVEL:
4188 case D3DTSS_MAXANISOTROPY:
4189 name.Format("%d",value);
4190 break;
4191 // Hex values
4192 case D3DTSS_BORDERCOLOR:
4193 name.Format("0x%x",value);
4194 break;
4195
4196 default:
4197 name.Format("UNKNOWN (%d)",value);
4198 break;
4199 }
4200}
4201
4203{
4204 switch (value) {
4205 case D3DTOP_DISABLE : return "D3DTOP_DISABLE";
4206 case D3DTOP_SELECTARG1 : return "D3DTOP_SELECTARG1";
4207 case D3DTOP_SELECTARG2 : return "D3DTOP_SELECTARG2";
4208 case D3DTOP_MODULATE : return "D3DTOP_MODULATE";
4209 case D3DTOP_MODULATE2X : return "D3DTOP_MODULATE2X";
4210 case D3DTOP_MODULATE4X : return "D3DTOP_MODULATE4X";
4211 case D3DTOP_ADD : return "D3DTOP_ADD";
4212 case D3DTOP_ADDSIGNED : return "D3DTOP_ADDSIGNED";
4213 case D3DTOP_ADDSIGNED2X : return "D3DTOP_ADDSIGNED2X";
4214 case D3DTOP_SUBTRACT : return "D3DTOP_SUBTRACT";
4215 case D3DTOP_ADDSMOOTH : return "D3DTOP_ADDSMOOTH";
4216 case D3DTOP_BLENDDIFFUSEALPHA : return "D3DTOP_BLENDDIFFUSEALPHA";
4217 case D3DTOP_BLENDTEXTUREALPHA : return "D3DTOP_BLENDTEXTUREALPHA";
4218 case D3DTOP_BLENDFACTORALPHA : return "D3DTOP_BLENDFACTORALPHA";
4219 case D3DTOP_BLENDTEXTUREALPHAPM : return "D3DTOP_BLENDTEXTUREALPHAPM";
4220 case D3DTOP_BLENDCURRENTALPHA : return "D3DTOP_BLENDCURRENTALPHA";
4221 case D3DTOP_PREMODULATE : return "D3DTOP_PREMODULATE";
4222 case D3DTOP_MODULATEALPHA_ADDCOLOR : return "D3DTOP_MODULATEALPHA_ADDCOLOR";
4223 case D3DTOP_MODULATECOLOR_ADDALPHA : return "D3DTOP_MODULATECOLOR_ADDALPHA";
4224 case D3DTOP_MODULATEINVALPHA_ADDCOLOR : return "D3DTOP_MODULATEINVALPHA_ADDCOLOR";
4225 case D3DTOP_MODULATEINVCOLOR_ADDALPHA : return "D3DTOP_MODULATEINVCOLOR_ADDALPHA";
4226 case D3DTOP_BUMPENVMAP : return "D3DTOP_BUMPENVMAP";
4227 case D3DTOP_BUMPENVMAPLUMINANCE : return "D3DTOP_BUMPENVMAPLUMINANCE";
4228 case D3DTOP_DOTPRODUCT3 : return "D3DTOP_DOTPRODUCT3";
4229 case D3DTOP_MULTIPLYADD : return "D3DTOP_MULTIPLYADD";
4230 case D3DTOP_LERP : return "D3DTOP_LERP";
4231 default : return "UNKNOWN";
4232 }
4233}
4234
4236{
4237 switch (value) {
4238 case D3DTA_CURRENT : return "D3DTA_CURRENT";
4239 case D3DTA_DIFFUSE : return "D3DTA_DIFFUSE";
4240 case D3DTA_SELECTMASK : return "D3DTA_SELECTMASK";
4241 case D3DTA_SPECULAR : return "D3DTA_SPECULAR";
4242 case D3DTA_TEMP : return "D3DTA_TEMP";
4243 case D3DTA_TEXTURE : return "D3DTA_TEXTURE";
4244 case D3DTA_TFACTOR : return "D3DTA_TFACTOR";
4245 case D3DTA_ALPHAREPLICATE : return "D3DTA_ALPHAREPLICATE";
4246 case D3DTA_COMPLEMENT : return "D3DTA_COMPLEMENT";
4247 default : return "UNKNOWN";
4248 }
4249}
4250
4252{
4253 switch (value) {
4254 case D3DTEXF_NONE : return "D3DTEXF_NONE";
4255 case D3DTEXF_POINT : return "D3DTEXF_POINT";
4256 case D3DTEXF_LINEAR : return "D3DTEXF_LINEAR";
4257 case D3DTEXF_ANISOTROPIC : return "D3DTEXF_ANISOTROPIC";
4258 case D3DTEXF_FLATCUBIC : return "D3DTEXF_FLATCUBIC";
4259 case D3DTEXF_GAUSSIANCUBIC : return "D3DTEXF_GAUSSIANCUBIC";
4260 default : return "UNKNOWN";
4261 }
4262}
4263
4265{
4266 switch (value) {
4267 case D3DTADDRESS_WRAP : return "D3DTADDRESS_WRAP";
4268 case D3DTADDRESS_MIRROR : return "D3DTADDRESS_MIRROR";
4269 case D3DTADDRESS_CLAMP : return "D3DTADDRESS_CLAMP";
4270 case D3DTADDRESS_BORDER : return "D3DTADDRESS_BORDER";
4271 case D3DTADDRESS_MIRRORONCE: return "D3DTADDRESS_MIRRORONCE";
4272 default : return "UNKNOWN";
4273 }
4274}
4275
4277{
4278 switch (value) {
4279 case D3DTTFF_DISABLE : return "D3DTTFF_DISABLE";
4280 case D3DTTFF_COUNT1 : return "D3DTTFF_COUNT1";
4281 case D3DTTFF_COUNT2 : return "D3DTTFF_COUNT2";
4282 case D3DTTFF_COUNT3 : return "D3DTTFF_COUNT3";
4283 case D3DTTFF_COUNT4 : return "D3DTTFF_COUNT4";
4284 case D3DTTFF_PROJECTED : return "D3DTTFF_PROJECTED";
4285 default : return "UNKNOWN";
4286 }
4287}
4288
4290{
4291 switch (value) {
4292 case D3DZB_FALSE : return "D3DZB_FALSE";
4293 case D3DZB_TRUE : return "D3DZB_TRUE";
4294 case D3DZB_USEW : return "D3DZB_USEW";
4295 default : return "UNKNOWN";
4296 }
4297}
4298
4300{
4301 switch (value) {
4302 case D3DFILL_POINT : return "D3DFILL_POINT";
4303 case D3DFILL_WIREFRAME : return "D3DFILL_WIREFRAME";
4304 case D3DFILL_SOLID : return "D3DFILL_SOLID";
4305 default : return "UNKNOWN";
4306 }
4307}
4308
4310{
4311 switch (value) {
4312 case D3DSHADE_FLAT : return "D3DSHADE_FLAT";
4313 case D3DSHADE_GOURAUD : return "D3DSHADE_GOURAUD";
4314 case D3DSHADE_PHONG : return "D3DSHADE_PHONG";
4315 default : return "UNKNOWN";
4316 }
4317}
4318
4320{
4321 switch (value) {
4322 case D3DBLEND_ZERO : return "D3DBLEND_ZERO";
4323 case D3DBLEND_ONE : return "D3DBLEND_ONE";
4324 case D3DBLEND_SRCCOLOR : return "D3DBLEND_SRCCOLOR";
4325 case D3DBLEND_INVSRCCOLOR : return "D3DBLEND_INVSRCCOLOR";
4326 case D3DBLEND_SRCALPHA : return "D3DBLEND_SRCALPHA";
4327 case D3DBLEND_INVSRCALPHA : return "D3DBLEND_INVSRCALPHA";
4328 case D3DBLEND_DESTALPHA : return "D3DBLEND_DESTALPHA";
4329 case D3DBLEND_INVDESTALPHA : return "D3DBLEND_INVDESTALPHA";
4330 case D3DBLEND_DESTCOLOR : return "D3DBLEND_DESTCOLOR";
4331 case D3DBLEND_INVDESTCOLOR : return "D3DBLEND_INVDESTCOLOR";
4332 case D3DBLEND_SRCALPHASAT : return "D3DBLEND_SRCALPHASAT";
4333 case D3DBLEND_BOTHSRCALPHA : return "D3DBLEND_BOTHSRCALPHA";
4334 case D3DBLEND_BOTHINVSRCALPHA : return "D3DBLEND_BOTHINVSRCALPHA";
4335 default : return "UNKNOWN";
4336 }
4337}
4338
4340{
4341 switch (value) {
4342 case D3DCULL_NONE : return "D3DCULL_NONE";
4343 case D3DCULL_CW : return "D3DCULL_CW";
4344 case D3DCULL_CCW : return "D3DCULL_CCW";
4345 default : return "UNKNOWN";
4346 }
4347}
4348
4350{
4351 switch (value) {
4352 case D3DCMP_NEVER : return "D3DCMP_NEVER";
4353 case D3DCMP_LESS : return "D3DCMP_LESS";
4354 case D3DCMP_EQUAL : return "D3DCMP_EQUAL";
4355 case D3DCMP_LESSEQUAL : return "D3DCMP_LESSEQUAL";
4356 case D3DCMP_GREATER : return "D3DCMP_GREATER";
4357 case D3DCMP_NOTEQUAL : return "D3DCMP_NOTEQUAL";
4358 case D3DCMP_GREATEREQUAL : return "D3DCMP_GREATEREQUAL";
4359 case D3DCMP_ALWAYS : return "D3DCMP_ALWAYS";
4360 default : return "UNKNOWN";
4361 }
4362}
4363
4365{
4366 switch (value) {
4367 case D3DFOG_NONE : return "D3DFOG_NONE";
4368 case D3DFOG_EXP : return "D3DFOG_EXP";
4369 case D3DFOG_EXP2 : return "D3DFOG_EXP2";
4370 case D3DFOG_LINEAR : return "D3DFOG_LINEAR";
4371 default : return "UNKNOWN";
4372 }
4373}
4374
4376{
4377 switch (value) {
4378 case D3DSTENCILOP_KEEP : return "D3DSTENCILOP_KEEP";
4379 case D3DSTENCILOP_ZERO : return "D3DSTENCILOP_ZERO";
4380 case D3DSTENCILOP_REPLACE : return "D3DSTENCILOP_REPLACE";
4381 case D3DSTENCILOP_INCRSAT : return "D3DSTENCILOP_INCRSAT";
4382 case D3DSTENCILOP_DECRSAT : return "D3DSTENCILOP_DECRSAT";
4383 case D3DSTENCILOP_INVERT : return "D3DSTENCILOP_INVERT";
4384 case D3DSTENCILOP_INCR : return "D3DSTENCILOP_INCR";
4385 case D3DSTENCILOP_DECR : return "D3DSTENCILOP_DECR";
4386 default : return "UNKNOWN";
4387 }
4388}
4389
4391{
4392 switch (value) {
4393 case D3DMCS_MATERIAL : return "D3DMCS_MATERIAL";
4394 case D3DMCS_COLOR1 : return "D3DMCS_COLOR1";
4395 case D3DMCS_COLOR2 : return "D3DMCS_COLOR2";
4396 default : return "UNKNOWN";
4397 }
4398}
4399
4401{
4402 switch (value) {
4403 case D3DVBF_DISABLE : return "D3DVBF_DISABLE";
4404 case D3DVBF_1WEIGHTS : return "D3DVBF_1WEIGHTS";
4405 case D3DVBF_2WEIGHTS : return "D3DVBF_2WEIGHTS";
4406 case D3DVBF_3WEIGHTS : return "D3DVBF_3WEIGHTS";
4407 case D3DVBF_TWEENING : return "D3DVBF_TWEENING";
4408 case D3DVBF_0WEIGHTS : return "D3DVBF_0WEIGHTS";
4409 default : return "UNKNOWN";
4410 }
4411}
4412
4414{
4415 switch (value) {
4416 case D3DPATCHEDGE_DISCRETE : return "D3DPATCHEDGE_DISCRETE";
4417 case D3DPATCHEDGE_CONTINUOUS:return "D3DPATCHEDGE_CONTINUOUS";
4418 default : return "UNKNOWN";
4419 }
4420}
4421
4423{
4424 switch (value) {
4425 case D3DDMT_ENABLE : return "D3DDMT_ENABLE";
4426 case D3DDMT_DISABLE : return "D3DDMT_DISABLE";
4427 default : return "UNKNOWN";
4428 }
4429}
4430
4432{
4433 switch (value) {
4434 case D3DBLENDOP_ADD : return "D3DBLENDOP_ADD";
4435 case D3DBLENDOP_SUBTRACT : return "D3DBLENDOP_SUBTRACT";
4436 case D3DBLENDOP_REVSUBTRACT: return "D3DBLENDOP_REVSUBTRACT";
4437 case D3DBLENDOP_MIN : return "D3DBLENDOP_MIN";
4438 case D3DBLENDOP_MAX : return "D3DBLENDOP_MAX";
4439 default : return "UNKNOWN";
4440 }
4441}
4442
4443
4444//============================================================================
4445// DX8Wrapper::getBackBufferFormat
4446//============================================================================
4447
4449{
4450 return D3DFormat_To_WW3DFormat( _PresentParameters.BackBufferFormat );
4451}
#define NULL
Definition BaseType.h:92
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
#define max(x, y)
Definition BaseType.h:105
Int DX8Wrapper_PreserveFPU
void const char * value
bool DX8Wrapper_IsWindowed
#define DX8_RECORD_RENDER(polys, verts, shader)
Definition statistics.h:76
#define WWASSERT
#define W3DNEW
Definition always.h:109
unsigned short WORD
Definition bittype.h:58
unsigned int UINT
Definition bittype.h:63
unsigned long DWORD
Definition bittype.h:57
int Find_POT(int val)
Definition pot.cpp:53
char dir[_MAX_DIR]
Definition autorun.cpp:215
T Bound(T original, T minval, T maxval)
Definition bound.h:44
static void Init(void)
Definition boxrobj.cpp:347
static void Shutdown(void)
Definition boxrobj.cpp:384
D3DCAPS8 const & Get_DX8_Caps() const
Definition dx8caps.h:251
bool Is_Valid_Display_Format(int width, int height, WW3DFormat format)
Definition dx8caps.cpp:990
static void Shutdown(void)
Definition dx8caps.cpp:502
static void Recreate_Textures()
static void Release_Textures()
static void Render(int backbufferindex)
static void Update(void)
static int Get_Swap_Interval(void)
static const char * Get_DX8_Fill_Mode_Name(unsigned value)
static unsigned Get_Last_Frame_Texture_Stage_State_Changes()
static void Set_Vertex_Buffer(const VertexBufferClass *vb, unsigned stream=0)
static void Begin_Scene(void)
static const char * Get_DX8_Stencil_Op_Name(unsigned value)
static IDirect3DDevice8 * _Get_D3D_Device8()
Definition dx8wrapper.h:530
static bool Test_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT zmode)
static void Begin_Statistics()
static unsigned TextureStageStates[MAX_TEXTURE_STAGES][32]
Definition dx8wrapper.h:670
static unsigned Get_Last_Frame_Material_Changes()
static bool IsRenderToTexture
Definition dx8wrapper.h:705
static LightEnvironmentClass * Light_Environment
Definition dx8wrapper.h:658
static const char * Get_DX8_Vertex_Blend_Flag_Name(unsigned value)
static void Set_Vertex_Shader_Constant(int reg, const void *data, int count)
Definition dx8wrapper.h:739
static int CurRenderDevice
Definition dx8wrapper.h:639
static void Set_Texture(unsigned stage, TextureBaseClass *texture)
static DWORD Vertex_Processing_Behavior
Definition dx8wrapper.h:661
static bool Set_Next_Render_Device(void)
static void _Update_Texture(TextureClass *system, TextureClass *video)
static void Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float dest_alpha=0.0f, float z=1.0f, unsigned int stencil=0)
Clear current render device.
static const char * Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state)
static IDirect3DTexture8 * _Create_DX8_Texture(unsigned int width, unsigned int height, WW3DFormat format, MipCountType mip_level_count, D3DPOOL pool=D3DPOOL_MANAGED, bool rendertarget=false)
static unsigned long FrameCount
Definition dx8wrapper.h:689
static void Do_Onetime_Device_Dependent_Inits(void)
static RenderStateStruct render_state
Definition dx8wrapper.h:628
static const char * Get_DX8_Fog_Mode_Name(unsigned value)
static void Get_Format_Name(unsigned int format, StringClass *tex_format)
static unsigned Get_Last_Frame_Vertex_Buffer_Changes()
static IDirect3DSurface8 * _Get_DX8_Front_Buffer()
static bool Validate_Device(void)
static bool IsInitted
Definition dx8wrapper.h:632
static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode)
static IDirect3DSurface8 * CurrentDepthBuffer
Definition dx8wrapper.h:699
static bool IsWindowed
Definition dx8wrapper.h:644
friend class DX8IndexBufferClass
Definition dx8wrapper.h:714
static const char * Get_DX8_ZBuffer_Type_Name(unsigned value)
static unsigned light_changes
Definition dx8wrapper.h:682
static void Set_Default_Global_Render_States(void)
static D3DMATRIX old_world
Definition dx8wrapper.h:647
static IDirect3D8 * _Get_D3D8()
Definition dx8wrapper.h:531
static int Get_Render_Device(void)
static const DX8Caps * Get_Current_Caps()
Definition dx8wrapper.h:536
static ZTextureClass * Shadow_Map[MAX_SHADOW_MAPS]
Definition dx8wrapper.h:663
static void Shutdown(void)
static IDirect3DCubeTexture8 * _Create_DX8_Cube_Texture(unsigned int width, unsigned int height, WW3DFormat format, MipCountType mip_level_count, D3DPOOL pool=D3DPOOL_MANAGED, bool rendertarget=false)
static SurfaceClass * _Get_DX8_Back_Buffer(unsigned int num=0)
static unsigned RenderStates[256]
Definition dx8wrapper.h:669
static D3DADAPTER_IDENTIFIER8 CurrentAdapterIdentifier
Definition dx8wrapper.h:693
static bool world_identity
Definition dx8wrapper.h:668
static D3DCOLOR FogColor
Definition dx8wrapper.h:676
static DWORD Pixel_Shader
Definition dx8wrapper.h:653
static void Set_Light(unsigned index, const D3DLIGHT8 *light)
static const char * Get_DX8_Shade_Mode_Name(unsigned value)
static void Get_Device_Resolution(int &set_w, int &set_h, int &set_bits, bool &set_windowed)
static unsigned _MainThreadID
Definition dx8wrapper.h:635
static IDirect3DSwapChain8 * Create_Additional_Swap_Chain(HWND render_window)
static Vector4 Pixel_Shader_Constants[MAX_PIXEL_SHADER_CONSTANTS]
Definition dx8wrapper.h:656
static DX8_CleanupHook * m_pCleanupHook
Definition dx8wrapper.h:626
static const char * Get_DX8_Texture_Filter_Name(unsigned value)
static bool Set_Any_Render_Device(void)
static void Invalidate_Cached_Render_States(void)
static bool Init(void *hwnd, bool lite=false)
static void Set_Light_Environment(LightEnvironmentClass *light_env)
Set the light environment. This is a lighting model which used up to four directional lights to produ...
static int ResolutionWidth
Definition dx8wrapper.h:640
static void Flip_To_Primary(void)
static unsigned texture_changes
Definition dx8wrapper.h:683
static unsigned DrawPolygonLowBoundLimit
Definition dx8wrapper.h:703
static void End_Scene(bool flip_frame=true)
static const char * Get_DX8_Texture_Op_Name(unsigned value)
static unsigned vertex_buffer_changes
Definition dx8wrapper.h:680
static unsigned int Get_Free_Texture_RAM()
static bool FogEnable
Definition dx8wrapper.h:675
static bool Toggle_Windowed(void)
static float ZFar
Definition dx8wrapper.h:709
static void Set_Pixel_Shader_Constant(int reg, const void *data, int count)
Definition dx8wrapper.h:750
static bool Create_Device(void)
static void Get_DX8_Texture_Stage_State_Value_Name(StringClass &name, D3DTEXTURESTAGESTATETYPE state, unsigned value)
static IDirect3DSurface8 * CurrentRenderTarget
Definition dx8wrapper.h:698
static const char * Get_DX8_Material_Source_Name(unsigned value)
static bool Set_Render_Device(const char *dev_name, int width=-1, int height=-1, int bits=-1, int windowed=-1, bool resize_window=false)
static D3DFORMAT DisplayFormat
Definition dx8wrapper.h:645
static void Enumerate_Devices()
static bool _Is_Triangle_Draw_Enabled()
Definition dx8wrapper.h:462
static IDirect3DSurface8 * DefaultRenderTarget
Definition dx8wrapper.h:700
static void Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value)
Definition dx8wrapper.h:899
static unsigned texture_stage_state_changes
Definition dx8wrapper.h:685
static void Apply_Default_State()
Resets render device to default state.
static int TextureBitDepth
Definition dx8wrapper.h:643
static int BitDepth
Definition dx8wrapper.h:642
static const char * Get_DX8_Texture_Arg_Name(unsigned value)
static WW3DFormat getBackBufferFormat(void)
Returns the display format - added by TR for video playback - not part of W3D.
static unsigned long Get_FrameCount(void)
static const char * Get_DX8_Texture_Address_Name(unsigned value)
static void Compute_Caps(WW3DFormat display_format)
friend void DX8_Assert()
static void _Set_DX8_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4 &m)
Definition dx8wrapper.h:763
static DX8Caps * CurrentCaps
Definition dx8wrapper.h:691
static void Set_Index_Buffer(const IndexBufferClass *ib, unsigned short index_base_offset)
static RenderInfoClass * Render_Info
Definition dx8wrapper.h:659
static bool IsDeviceLost
Definition dx8wrapper.h:633
static int ZBias
Definition dx8wrapper.h:707
static void Set_Gamma(float gamma, float bright, float contrast, bool calibrate=true, bool uselimit=true)
static const char * Get_DX8_Cmp_Func_Name(unsigned value)
static IDirect3DSurface8 * _Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format)
static unsigned Get_Last_Frame_Light_Changes()
static unsigned Get_Last_Frame_Texture_Changes()
static bool Reset_Device(bool reload_assets=true)
static void Set_Vertex_Shader(DWORD vertex_shader)
Definition dx8wrapper.h:719
static void Set_Pixel_Shader(DWORD pixel_shader)
Definition dx8wrapper.h:730
static Vector4 Convert_Color(unsigned color)
Definition dx8wrapper.h:958
static unsigned matrix_changes
Definition dx8wrapper.h:678
static const char * Get_DX8_Patch_Edge_Style_Name(unsigned value)
static void Draw_Strip(unsigned short start_index, unsigned short index_count, unsigned short min_vertex_index, unsigned short vertex_count)
static Vector4 Vertex_Shader_Constants[MAX_VERTEX_SHADER_CONSTANTS]
Definition dx8wrapper.h:655
static const char * Get_DX8_Debug_Monitor_Token_Name(unsigned value)
static const char * Get_DX8_Cull_Mode_Name(unsigned value)
static unsigned render_state_changes
Definition dx8wrapper.h:684
static void End_Statistics()
static IDirect3DBaseTexture8 * Textures[MAX_TEXTURE_STAGES]
Definition dx8wrapper.h:671
static unsigned Get_Last_Frame_Draw_Calls()
static int Get_Render_Device_Count(void)
static void Do_Onetime_Device_Dependent_Shutdowns(void)
static bool Set_Device_Resolution(int width=-1, int height=-1, int bits=-1, int windowed=-1, bool resize_window=false)
static const char * Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state)
static void Set_Render_Target_With_Z(TextureClass *texture, ZTextureClass *ztexture=NULL)
static const char * Get_DX8_Blend_Name(unsigned value)
static IDirect3DDevice8 * D3DDevice
Definition dx8wrapper.h:696
static void Get_Render_Target_Resolution(int &set_w, int &set_h, int &set_bits, bool &set_windowed)
static void Draw_Triangles(unsigned buffer_type, unsigned short start_index, unsigned short polygon_count, unsigned short min_vertex_index, unsigned short vertex_count)
static unsigned render_state_changed
Definition dx8wrapper.h:629
static void Set_Viewport(CONST D3DVIEWPORT8 *pViewport)
static const char * Get_Render_Device_Name(int device_index)
static bool Has_Stencil(void)
static void Set_Material(const VertexMaterialClass *material)
static unsigned index_buffer_changes
Definition dx8wrapper.h:681
static void Get_DX8_Render_State_Value_Name(StringClass &name, D3DRENDERSTATETYPE state, unsigned value)
static void Set_DX8_Light(int index, D3DLIGHT8 *light)
Definition dx8wrapper.h:857
static unsigned Get_Last_Frame_Matrix_Changes()
static TextureClass * Create_Render_Target(int width, int height, WW3DFormat format=WW3D_FORMAT_UNKNOWN)
static IDirect3DTexture8 * _Create_DX8_ZTexture(unsigned int width, unsigned int height, WW3DZFormat zformat, MipCountType mip_level_count, D3DPOOL pool=D3DPOOL_MANAGED)
static void Set_Swap_Interval(int swap)
static const RenderDeviceDescClass & Get_Render_Device_Desc(int deviceidx)
friend class DX8VertexBufferClass
Definition dx8wrapper.h:715
static bool CurrentDX8LightEnables[4]
Definition dx8wrapper.h:687
static const D3DADAPTER_IDENTIFIER8 & Get_Current_Adapter_Identifier()
Definition dx8wrapper.h:428
static bool Registry_Save_Render_Device(const char *sub_key)
static const char * Get_DX8_Blend_Op_Name(unsigned value)
static Matrix4x4 ProjectionMatrix
Definition dx8wrapper.h:710
static void Apply_Render_State_Changes()
static void Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value)
Definition dx8wrapper.h:874
static void Release_Render_State()
static IDirect3DSurface8 * DefaultDepthBuffer
Definition dx8wrapper.h:701
static void Reset_Statistics()
static D3DMATRIX old_view
Definition dx8wrapper.h:648
static Vector3 Ambient_Color
Definition dx8wrapper.h:665
static bool Registry_Load_Render_Device(const char *sub_key, bool resize_window)
static DWORD Vertex_Shader
Definition dx8wrapper.h:652
static unsigned Get_Last_Frame_Render_State_Changes()
static void Flush_DX8_Resource_Manager(unsigned int bytes=0)
static bool Find_Z_Mode(D3DFORMAT colorbuffer, D3DFORMAT backbuffer, D3DFORMAT *zmode)
static IDirect3D8 * D3DInterface
Definition dx8wrapper.h:695
static IDirect3DVolumeTexture8 * _Create_DX8_Volume_Texture(unsigned int width, unsigned int height, unsigned int depth, WW3DFormat format, MipCountType mip_level_count, D3DPOOL pool=D3DPOOL_MANAGED)
static void Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default_depth_buffer=false)
static D3DMATRIX old_prj
Definition dx8wrapper.h:649
static const char * Get_DX8_Texture_Transform_Flag_Name(unsigned value)
static unsigned material_changes
Definition dx8wrapper.h:679
static unsigned draw_calls
Definition dx8wrapper.h:686
static Matrix4x4 DX8Transforms[D3DTS_WORLD+1]
Definition dx8wrapper.h:630
static bool _EnableTriangleDraw
Definition dx8wrapper.h:637
static bool Find_Color_And_Z_Mode(int resx, int resy, int bitdepth, D3DFORMAT *set_colorbuffer, D3DFORMAT *set_backbuffer, D3DFORMAT *set_zmode)
static int ResolutionHeight
Definition dx8wrapper.h:641
static unsigned Get_Last_Frame_DX8_Calls()
static void Release_Device(void)
static unsigned Get_Last_Frame_Index_Buffer_Changes()
static float ZNear
Definition dx8wrapper.h:708
unsigned Get_Type() const
unsigned Get_Type() const
unsigned short Get_Vertex_Count() const
int Count(void) const
Definition Vector.H:507
virtual bool Is_Available(int forced=false)=0
unsigned Type() const
void Add_Engine_Ref() const
float Get_Intensity(void) const
Definition light.h:108
void Get_Far_Attenuation_Range(double &fStart, double &fEnd) const
Definition light.h:120
float Get_Spot_Exponent(void) const
Definition light.h:144
void Get_Spot_Direction(Vector3 &dir) const
Definition light.h:142
float Get_Spot_Angle(void) const
Definition light.h:139
void Get_Ambient(Vector3 *set_c) const
Definition light.h:111
@ POINT
Definition light.h:63
@ DIRECTIONAL
Definition light.h:64
LightType Get_Type()
Definition light.h:105
void Get_Diffuse(Vector3 *set_c) const
Definition light.h:114
void Get_Specular(Vector3 *set_c) const
Definition light.h:117
float Get_Attenuation_Range(void) const
Definition light.h:124
int Get_Light_Count(void) const
bool isPointLight(int i) const
const Vector3 & getPointDiffuse(int i) const
const Vector3 & getPointAmbient(int i) const
const Vector3 & Get_Light_Direction(int i) const
float getPointOrad(int i) const
const Vector3 & Get_Equivalent_Ambient(void) const
float getPointIrad(int i) const
const Vector3 & getPointCenter(int i) const
const Vector3 & Get_Light_Diffuse(int i) const
static void _Deinit()
static void _Init()
static IDirect3DSurface8 * _Create_Missing_Surface()
static IDirect3DTexture8 * _Get_Missing_Texture()
static void _Shutdown(void)
Definition pointgr.cpp:1602
static void _Init(void)
Definition pointgr.cpp:1438
void Set_Int(const char *name, int value)
Definition registry.cpp:107
char * Get_String(const char *name, char *value, int value_size, const char *default_string=NULL)
Definition registry.cpp:212
void Set_String(const char *name, const char *value)
Definition registry.cpp:232
bool Is_Valid(void)
Definition registry.h:64
int Get_Int(const char *name, int def_value=0)
Definition registry.cpp:95
static void Set_Screen_Resolution(const RectClass &screen)
Definition render2d.cpp:92
const DynamicVectorClass< ResolutionDescClass > & Enumerate_Resolutions(void) const
Definition rddesc.h:112
Vector3 Get_Position(void) const
Definition rendobj.cpp:508
static void Invalidate()
Definition shader.h:346
static void Shutdown(void)
static void Init(void)
static void Insert_Triangles(const SphereClass &bounding_sphere, unsigned short start_index, unsigned short polygon_count, unsigned short min_vertex_index, unsigned short vertex_count)
int _cdecl Format(const TCHAR *format,...)
Definition wwstring.cpp:273
static void Apply_Null(unsigned int stage)
Apply NULL texture state.
Definition texture.cpp:400
IDirect3DBaseTexture8 * Peek_D3D_Base_Texture() const
Returns a pointer to the d3d texture.
Definition texture.cpp:258
static void Invalidate_Old_Unused_Textures(unsigned inactive_time_override)
Invalidate old unused textures.
Definition texture.cpp:142
PoolType Get_Pool() const
Definition texture.h:168
IDirect3DSurface8 * Get_D3D_Surface_Level(unsigned int level=0)
Get D3D surface from mip level.
Definition texture.cpp:1019
static void _Init_Filters(TextureFilterMode texture_filter)
Init filters (legacy)
static void Init(void)
static void Deinit(void)
static IDirect3DSurface8 * Load_Surface_Immediate(const StringClass &filename, WW3DFormat surface_format, bool allow_compression)
static void Sleep_Ms(unsigned ms=0)
Definition thread.cpp:121
static unsigned _Get_Current_Thread_ID()
Definition thread.cpp:142
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
unsigned Type() const
void Add_Engine_Ref() const
static bool Is_Snapshot_Activated()
Definition ww3d.h:298
static int Get_Texture_Filter()
Definition ww3d.h:143
static void _Invalidate_Textures()
Definition ww3d.cpp:754
static void _Invalidate_Mesh_Cache()
Definition ww3d.cpp:749
IDirect3DSurface8 * Get_D3D_Surface_Level(unsigned int level=0)
Get D3D surface from mip level.
Definition texture.cpp:1311
@ DX8_FVF_XYZNDUV2
Definition dx8fvf.h:64
int IndexBufferExceptionFunc(void)
DX8MeshRendererClass TheDX8MeshRenderer
const unsigned dynamic_fvf_type
IDirect3D8 *(WINAPI * Direct3DCreate8Type)(UINT SDKVersion)
const int DEFAULT_RESOLUTION_HEIGHT
const int DEFAULT_RESOLUTION_WIDTH
const int DEFAULT_BIT_DEPTH
void Log_DX8_ErrorCode(unsigned res)
#define WW3D_DEVTYPE
void DX8_Assert()
void Non_Fatal_Log_DX8_ErrorCode(unsigned res, const char *file, int line)
DWORD F2DW(float f)
const int DEFAULT_TEXTURE_BIT_DEPTH
HINSTANCE D3D8Lib
Direct3DCreate8Type Direct3DCreate8Ptr
unsigned number_of_DX8_calls
bool _DX8SingleThreaded
const unsigned MAX_SHADOW_MAPS
Definition dx8wrapper.h:80
#define DX8_RECORD_VERTEX_BUFFER_CHANGE()
Definition dx8wrapper.h:111
@ BUFFER_TYPE_DYNAMIC_DX8
Definition dx8wrapper.h:90
@ BUFFER_TYPE_INVALID
Definition dx8wrapper.h:92
@ BUFFER_TYPE_DX8
Definition dx8wrapper.h:88
@ BUFFER_TYPE_SORTING
Definition dx8wrapper.h:89
@ BUFFER_TYPE_DYNAMIC_SORTING
Definition dx8wrapper.h:91
const unsigned MAX_PIXEL_SHADER_CONSTANTS
Definition dx8wrapper.h:79
#define VALUE_NAME_RENDER_DEVICE_HEIGHT
Definition dx8wrapper.h:71
const unsigned MAX_TEXTURE_STAGES
Definition dx8wrapper.h:76
#define DX8CALL(x)
Definition dx8wrapper.h:138
#define VALUE_NAME_RENDER_DEVICE_DEPTH
Definition dx8wrapper.h:72
#define VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH
Definition dx8wrapper.h:74
#define DX8CALL_HRES(x, res)
Definition dx8wrapper.h:137
#define DX8_RECORD_INDEX_BUFFER_CHANGE()
Definition dx8wrapper.h:112
#define VALUE_NAME_RENDER_DEVICE_NAME
Definition dx8wrapper.h:69
#define VALUE_NAME_RENDER_DEVICE_WINDOWED
Definition dx8wrapper.h:73
#define DX8_RECORD_DRAW_CALLS()
Definition dx8wrapper.h:117
unsigned number_of_DX8_calls
const unsigned MAX_VERTEX_STREAMS
Definition dx8wrapper.h:77
#define DX8_THREAD_ASSERT()
Definition dx8wrapper.h:140
WWINLINE void DX8_ErrorCode(unsigned res)
Definition dx8wrapper.h:125
#define VALUE_NAME_RENDER_DEVICE_WIDTH
Definition dx8wrapper.h:70
const unsigned MAX_VERTEX_SHADER_CONSTANTS
Definition dx8wrapper.h:78
bool _DX8SingleThreaded
FileFactoryClass * _TheFileFactory
Definition ffactory.cpp:51
D3DFORMAT WW3DFormat_To_D3DFormat(WW3DFormat ww3d_format)
Definition formconv.cpp:142
D3DFORMAT WW3DZFormat_To_D3DFormat(WW3DZFormat ww3d_zformat)
Depth Stencil W3D to D3D format conversion.
Definition formconv.cpp:173
WW3DFormat D3DFormat_To_WW3DFormat(D3DFORMAT d3d_format)
Definition formconv.cpp:150
else return(RetVal)
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define REF_PTR_SET(dst, src)
Definition refcount.h:79
#define NEW_REF(C, P)
Definition refcount.h:62
#define SHD_SHUTDOWN
Definition shdlib.h:61
#define SHD_INIT
Definition shdlib.h:60
#define SHD_INIT_SHADERS
Definition shdlib.h:62
#define SHD_SHUTDOWN_SHADERS
Definition shdlib.h:63
void swap(T &a, T &b)
unsigned vertex_buffer_types[MAX_VERTEX_STREAMS]
Definition dx8wrapper.h:190
unsigned short index_base_offset
Definition dx8wrapper.h:197
unsigned short vba_offset
Definition dx8wrapper.h:192
unsigned index_buffer_type
Definition dx8wrapper.h:191
VertexBufferClass * vertex_buffers[MAX_VERTEX_STREAMS]
Definition dx8wrapper.h:195
MipCountType
@ MIP_LEVELS_1
unsigned char flag
Definition vchannel.cpp:273
#define SNAPSHOT_SAY(x)
Definition ww3d.h:68
void Get_WW3D_Format_Name(WW3DFormat format, StringClass &name)
WW3DFormat
Definition ww3dformat.h:75
@ WW3D_FORMAT_UNKNOWN
Definition ww3dformat.h:76
WW3DZFormat
Definition ww3dformat.h:106
#define WWASSERT_PRINT(expr, string)
Definition wwdebug.h:135
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114
#define WWPROFILE(name)
Definition wwprofile.h:270