| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8wrapper.cpp $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 3/12/02 4:27p $*
- * *
- * $Revision:: 170 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- //#define CREATE_DX8_MULTI_THREADED
- //#define CREATE_DX8_FPU_PRESERVE
- #define WW3D_DEVTYPE D3DDEVTYPE_HAL
- #include "dx8wrapper.h"
- #include "dx8fvf.h"
- #include "dx8vertexbuffer.h"
- #include "dx8indexbuffer.h"
- #include "dx8renderer.h"
- #include "ww3d.h"
- #include "camera.h"
- #include "wwstring.h"
- #include "matrix4.h"
- #include "vertmaterial.h"
- #include "rddesc.h"
- #include "lightenvironment.h"
- #include "statistics.h"
- #include "registry.h"
- #include "boxrobj.h"
- #include "pointgr.h"
- #include "render2d.h"
- #include "sortingrenderer.h"
- #include "shattersystem.h"
- #include "light.h"
- #include "assetmgr.h"
- #include "textureloader.h"
- #include "missingtexture.h"
- #include "thread.h"
- #include <stdio.h>
- #include <D3dx8core.h>
- #include "pot.h"
- #include "wwprofile.h"
- #include "ffactory.h"
- #include "dx8caps.h"
- #include "formconv.h"
- #include "dx8texman.h"
- #include "bound.h"
- const int DEFAULT_RESOLUTION_WIDTH = 800;
- const int DEFAULT_RESOLUTION_HEIGHT = 600;
- const int DEFAULT_BIT_DEPTH = 32;
- const int DEFAULT_TEXTURE_BIT_DEPTH = 16;
- /***********************************************************************************
- **
- ** DX8Wrapper Static Variables
- **
- ***********************************************************************************/
- static HWND _Hwnd = NULL;
- bool DX8Wrapper::IsInitted = false;
- bool DX8Wrapper::_EnableTriangleDraw = true;
- int DX8Wrapper::CurRenderDevice = -1;
- int DX8Wrapper::ResolutionWidth = DEFAULT_RESOLUTION_WIDTH;
- int DX8Wrapper::ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT;
- int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH;
- int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH;
- bool DX8Wrapper::IsWindowed = false;
- D3DMATRIX DX8Wrapper::old_world;
- D3DMATRIX DX8Wrapper::old_view;
- D3DMATRIX DX8Wrapper::old_prj;
- bool DX8Wrapper::world_identity;
- unsigned DX8Wrapper::RenderStates[256];
- unsigned DX8Wrapper::TextureStageStates[MAX_TEXTURE_STAGES][32];
- IDirect3DBaseTexture8 * DX8Wrapper::Textures[MAX_TEXTURE_STAGES];
- RenderStateStruct DX8Wrapper::render_state;
- unsigned DX8Wrapper::render_state_changed;
- bool DX8Wrapper::FogEnable = false;
- D3DCOLOR DX8Wrapper::FogColor = 0;
- IDirect3D8 * DX8Wrapper::D3DInterface = NULL;
- IDirect3DDevice8 * DX8Wrapper::D3DDevice = NULL;
- IDirect3DSurface8 * DX8Wrapper::CurrentRenderTarget = NULL;
- IDirect3DSurface8 * DX8Wrapper::DefaultRenderTarget = NULL;
- IDirect3DSurface8 * DX8Wrapper::DefaultDepthBuffer = NULL;
- bool DX8Wrapper::IsRenderToTexture = false;
- unsigned DX8Wrapper::matrix_changes = 0;
- unsigned DX8Wrapper::material_changes = 0;
- unsigned DX8Wrapper::vertex_buffer_changes = 0;
- unsigned DX8Wrapper::index_buffer_changes = 0;
- unsigned DX8Wrapper::light_changes = 0;
- unsigned DX8Wrapper::texture_changes = 0;
- unsigned DX8Wrapper::render_state_changes = 0;
- unsigned DX8Wrapper::texture_stage_state_changes = 0;
- unsigned DX8Wrapper::_MainThreadID = 0;
- bool DX8Wrapper::CurrentDX8LightEnables[4];
- bool DX8Wrapper::IsDeviceLost;
- int DX8Wrapper::ZBias;
- float DX8Wrapper::ZNear;
- float DX8Wrapper::ZFar;
- Matrix4 DX8Wrapper::ProjectionMatrix;
- DX8Caps* DX8Wrapper::CurrentCaps;
- D3DADAPTER_IDENTIFIER8 DX8Wrapper::CurrentAdapterIdentifier;
- unsigned long DX8Wrapper::FrameCount = 0;
- bool _DX8SingleThreaded = false;
- unsigned number_of_DX8_calls = 0;
- static unsigned last_frame_matrix_changes = 0;
- static unsigned last_frame_material_changes = 0;
- static unsigned last_frame_vertex_buffer_changes = 0;
- static unsigned last_frame_index_buffer_changes = 0;
- static unsigned last_frame_light_changes = 0;
- static unsigned last_frame_texture_changes = 0;
- static unsigned last_frame_render_state_changes = 0;
- static unsigned last_frame_texture_stage_state_changes = 0;
- static unsigned last_frame_number_of_DX8_calls = 0;
- static D3DDISPLAYMODE DesktopMode;
- static D3DPRESENT_PARAMETERS _PresentParameters;
- static DynamicVectorClass<StringClass> _RenderDeviceNameTable;
- static DynamicVectorClass<StringClass> _RenderDeviceShortNameTable;
- static DynamicVectorClass<RenderDeviceDescClass> _RenderDeviceDescriptionTable;
- typedef IDirect3D8* (WINAPI *Direct3DCreate8Type) (UINT SDKVersion);
- Direct3DCreate8Type Direct3DCreate8Ptr = NULL;
- HINSTANCE D3D8Lib = NULL;
- /***********************************************************************************
- **
- ** DX8Wrapper Implementation
- **
- ***********************************************************************************/
- void Log_DX8_ErrorCode(unsigned res)
- {
- char tmp[256]="";
- HRESULT new_res=D3DXGetErrorStringA(
- res,
- tmp,
- sizeof(tmp));
- if (new_res==D3D_OK) {
- WWDEBUG_SAY((tmp));
- }
- WWASSERT(0);
- }
- void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line)
- {
- char tmp[256]="";
- HRESULT new_res=D3DXGetErrorStringA(
- res,
- tmp,
- sizeof(tmp));
- if (new_res==D3D_OK) {
- WWDEBUG_SAY(("DX8 Error: %s, File: %s, Line: %d\r\n",tmp,file,line));
- }
- }
- bool DX8Wrapper::Init(void * hwnd, bool lite)
- {
- WWASSERT(!IsInitted);
- /*
- ** Initialize all variables!
- */
- _Hwnd = (HWND)hwnd;
- _MainThreadID=ThreadClass::_Get_Current_Thread_ID();
- WWDEBUG_SAY(("DX8Wrapper main thread: 0x%x\n",_MainThreadID));
- CurRenderDevice = -1;
- ResolutionWidth = DEFAULT_RESOLUTION_WIDTH;
- ResolutionHeight = DEFAULT_RESOLUTION_HEIGHT;
- // Initialize Render2DClass Screen Resolution
- Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) );
- BitDepth = DEFAULT_BIT_DEPTH;
- IsWindowed = false;
- for (int light=0;light<4;++light) CurrentDX8LightEnables[light]=false;
- ::ZeroMemory(&old_world, sizeof(D3DMATRIX));
- ::ZeroMemory(&old_view, sizeof(D3DMATRIX));
- ::ZeroMemory(&old_prj, sizeof(D3DMATRIX));
- //old_vertex_shader; TODO
- //old_sr_shader;
- //current_shader;
- //world_identity;
- //CurrentFogColor;
- D3DInterface = NULL;
- D3DDevice = NULL;
- WWDEBUG_SAY(("Reset DX8Wrapper statistics\n"));
- Reset_Statistics();
- Invalidate_Cached_Render_States();
- if (!lite) {
- D3D8Lib = LoadLibrary("D3D8.DLL");
- if (D3D8Lib == NULL) return false;
- Direct3DCreate8Ptr = (Direct3DCreate8Type) GetProcAddress(D3D8Lib, "Direct3DCreate8");
- if (Direct3DCreate8Ptr) {
- /*
- ** Create the D3D interface object
- */
- WWDEBUG_SAY(("Create Direct3D8\n"));
- D3DInterface = Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
- if (D3DInterface == NULL) {
- return(false);
- }
- IsInitted = true;
- /*
- ** Enumerate the available devices
- */
- WWDEBUG_SAY(("Enumerate devices\n"));
- Enumerate_Devices();
- WWDEBUG_SAY(("DX8Wrapper Init completed\n"));
- }
- }
- return(true);
- }
- void DX8Wrapper::Shutdown(void)
- {
- if (D3DDevice) {
- Set_Render_Target ((IDirect3DSurface8 *)NULL);
- // If in full screen, reset device to windowed mode before releasing it. This is an attempt to
- // fix some random bugs and crashes on some devices.
- #if (0)
- if (!IsWindowed) {
- IsWindowed=true;
- ResolutionWidth=DEFAULT_RESOLUTION_WIDTH;
- ResolutionHeight=DEFAULT_RESOLUTION_HEIGHT;
- _PresentParameters.BackBufferWidth = ResolutionWidth;
- _PresentParameters.BackBufferHeight = ResolutionHeight;
- _PresentParameters.BackBufferCount = 1;
- _PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
- _PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
- _PresentParameters.Windowed = IsWindowed;
- _PresentParameters.EnableAutoDepthStencil = FALSE;
- _PresentParameters.Flags=0;
- _PresentParameters.BackBufferFormat = DesktopMode.Format;
- Reset_Device();
- }
- #endif //(0)
- Release_Device();
- }
- if (D3DInterface) {
- D3DInterface->Release();
- D3DInterface=NULL;
- }
- for (int i = 0; i < MAX_TEXTURE_STAGES; i++) {
- if (Textures[i]) {
- Textures[i]->Release();
- Textures[i] = NULL;
- }
- }
- _RenderDeviceNameTable.Delete_All();
- _RenderDeviceShortNameTable.Delete_All();
- _RenderDeviceDescriptionTable.Delete_All();
- if (D3D8Lib) {
- FreeLibrary(D3D8Lib);
- D3D8Lib = NULL;
- }
- IsInitted = false;
- }
- void DX8Wrapper::Do_Onetime_Device_Dependent_Inits(void)
- {
- /*
- ** Set Global render states (some of which depend on caps)
- */
- Compute_Caps(D3DFormat_To_WW3DFormat(_PresentParameters.BackBufferFormat));
- /*
- ** Initalize any other subsystems inside of WW3D
- */
- MissingTexture::_Init();
- TextureClass::_Init_Filters((TextureClass::TextureFilterMode)WW3D::Get_Texture_Filter());
- TheDX8MeshRenderer.Init();
- BoxRenderObjClass::Init();
- VertexMaterialClass::Init();
- PointGroupClass::_Init(); // This needs the VertexMaterialClass to be initted
- ShatterSystem::Init();
- TextureLoader::Init();
- Set_Default_Global_Render_States();
- }
- inline DWORD F2DW(float f) { return *((unsigned*)&f); }
- void DX8Wrapper::Set_Default_Global_Render_States(void)
- {
- DX8_THREAD_ASSERT();
- const D3DCAPS8 &caps = Get_Current_Caps()->Get_DX8_Caps();
- Set_DX8_Render_State(D3DRS_RANGEFOGENABLE, (caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE) ? TRUE : FALSE);
- Set_DX8_Render_State(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
- Set_DX8_Render_State(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
- Set_DX8_Render_State(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
- Set_DX8_Render_State(D3DRS_COLORVERTEX, TRUE);
- Set_DX8_Render_State(D3DRS_ZBIAS,0);
- Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLSCALE, F2DW(1.0f));
- Set_DX8_Texture_Stage_State(1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f));
- Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT00,F2DW(1.0f));
- Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT01,F2DW(0.0f));
- Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT10,F2DW(0.0f));
- Set_DX8_Texture_Stage_State(0, D3DTSS_BUMPENVMAT11,F2DW(1.0f));
- // Set_DX8_Render_State(D3DRS_CULLMODE, D3DCULL_CW);
- // Set dither mode here?
- }
- void DX8Wrapper::Invalidate_Cached_Render_States(void)
- {
- int a;
- for (a=0;a<sizeof(RenderStates)/sizeof(unsigned);++a) {
- RenderStates[a]=0x12345678;
- }
- for (a=0;a<MAX_TEXTURE_STAGES;++a) {
- for (int b=0; b<32;b++) {
- TextureStageStates[a][b]=0x12345678;
- }
- Textures[a]=NULL;
- }
- ShaderClass::Invalidate();
- }
- void DX8Wrapper::Do_Onetime_Device_Dependent_Shutdowns(void)
- {
- /*
- ** Shutdown ww3d systems
- */
- if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref();
- REF_PTR_RELEASE(render_state.vertex_buffer);
- if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
- REF_PTR_RELEASE(render_state.index_buffer);
- REF_PTR_RELEASE(render_state.material);
- for (unsigned i=0;i<MAX_TEXTURE_STAGES;++i) REF_PTR_RELEASE(render_state.Textures[i]);
- TextureLoader::Deinit();
- SortingRendererClass::Deinit();
- DynamicVBAccessClass::_Deinit();
- DynamicIBAccessClass::_Deinit();
- ShatterSystem::Shutdown();
- PointGroupClass::_Shutdown();
- VertexMaterialClass::Shutdown();
- BoxRenderObjClass::Shutdown();
- TheDX8MeshRenderer.Shutdown();
- MissingTexture::_Deinit();
- if (CurrentCaps) {
- delete CurrentCaps;
- CurrentCaps=NULL;
- }
- }
- bool DX8Wrapper::Create_Device(void)
- {
- WWASSERT(D3DDevice == NULL); // for now, once you've created a device, you're stuck with it!
- D3DCAPS8 caps;
- if (FAILED( D3DInterface->GetDeviceCaps(
- CurRenderDevice,
- WW3D_DEVTYPE,
- &caps))) {
- return false;
- }
- ::ZeroMemory(&CurrentAdapterIdentifier, sizeof(D3DADAPTER_IDENTIFIER8));
- if (FAILED( D3DInterface->GetAdapterIdentifier(CurRenderDevice,D3DENUM_NO_WHQL_LEVEL,&CurrentAdapterIdentifier))) {
- return false;
- }
- unsigned vertex_processing_type=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
- vertex_processing_type=D3DCREATE_MIXED_VERTEXPROCESSING;
- }
- #ifdef CREATE_DX8_MULTI_THREADED
- vertex_processing_type|=D3DCREATE_MULTITHREADED;
- _DX8SingleThreaded=false;
- #else
- _DX8SingleThreaded=true;
- #endif
- #ifdef CREATE_DX8_FPU_PRESERVE
- vertex_processing_type|=D3DCREATE_FPU_PRESERVE;
- #endif
- // JANI HACK! Some objects flicker on ATI Radeons. This can be fixed by locking the back buffer before flipping.
- // For this to work the back buffers need to be created as lockable!
- DX8Caps dx8_caps(
- D3DInterface,
- caps,
- D3DFormat_To_WW3DFormat(_PresentParameters.BackBufferFormat),
- CurrentAdapterIdentifier);
- if (dx8_caps.Get_Vendor()==DX8Caps::VENDOR_ATI) {
- _PresentParameters.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
- }
- HRESULT hr = D3DInterface->CreateDevice(
- CurRenderDevice,
- WW3D_DEVTYPE,
- _Hwnd,
- vertex_processing_type,
- &_PresentParameters,
- &D3DDevice );
- if (FAILED(hr)) {
- // The device selection may fail because the device lied that it supports 32 bit zbuffer with 16 bit
- // display. This happens at least on Voodoo2.
- if ((_PresentParameters.BackBufferFormat==D3DFMT_R5G6B5 ||
- _PresentParameters.BackBufferFormat==D3DFMT_X1R5G5B5 ||
- _PresentParameters.BackBufferFormat==D3DFMT_A1R5G5B5) &&
- (_PresentParameters.AutoDepthStencilFormat==D3DFMT_D32 ||
- _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24S8 ||
- _PresentParameters.AutoDepthStencilFormat==D3DFMT_D24X8)) {
- _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16;
- hr = D3DInterface->CreateDevice(
- CurRenderDevice,
- WW3D_DEVTYPE,
- _Hwnd,
- vertex_processing_type,
- &_PresentParameters,
- &D3DDevice );
- if (FAILED(hr)) {
- return false;
- }
- }
- }
- /*
- ** Initialize all subsystems
- */
- Do_Onetime_Device_Dependent_Inits();
- return true;
- }
- bool DX8Wrapper::Reset_Device(void)
- {
- WWDEBUG_SAY(("Resetting device.\n"));
- DX8_THREAD_ASSERT();
- if ((IsInitted) && (D3DDevice != NULL)) {
- // Release all non-MANAGED stuff
- WW3D::_Invalidate_Textures();
- Set_Vertex_Buffer (NULL);
- Set_Index_Buffer (NULL, 0);
- DynamicVBAccessClass::_Deinit();
- DynamicIBAccessClass::_Deinit();
- DX8TextureManagerClass::Release_Textures();
- // Reset frame count to reflect the flipping chain being reset by Reset()
- FrameCount = 0;
- DX8CALL(Reset(&_PresentParameters));
- DX8TextureManagerClass::Recreate_Textures();
- Invalidate_Cached_Render_States();
- Set_Default_Global_Render_States();
- WWDEBUG_SAY(("Device reset completed\n"));
- return true;
- }
- WWDEBUG_SAY(("Device reset failed\n"));
- return false;
- }
- void DX8Wrapper::Release_Device(void)
- {
- if (D3DDevice) {
- /*
- ** Release the current vertex and index buffers
- */
- if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref();
- REF_PTR_RELEASE(render_state.vertex_buffer);
- if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
- REF_PTR_RELEASE(render_state.index_buffer);
- /*
- ** Shutdown all subsystems
- */
- Do_Onetime_Device_Dependent_Shutdowns();
- /*
- ** Release the device
- */
- D3DDevice->Release();
- D3DDevice=NULL;
- }
- }
- void DX8Wrapper::Enumerate_Devices()
- {
- DX8_Assert();
- int adapter_count = D3DInterface->GetAdapterCount();
- for (int adapter_index=0; adapter_index<adapter_count; adapter_index++) {
- D3DADAPTER_IDENTIFIER8 id;
- ::ZeroMemory(&id, sizeof(D3DADAPTER_IDENTIFIER8));
- HRESULT res = D3DInterface->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&id);
- if (res == D3D_OK) {
- /*
- ** Set up the render device description
- ** TODO: Fill in more fields of the render device description? (need some lookup tables)
- */
- RenderDeviceDescClass desc;
- desc.set_device_name(id.Description);
- desc.set_driver_name(id.Driver);
- char buf[64];
- sprintf(buf,"%d.%d.%d.%d", //"%04x.%04x.%04x.%04x",
- HIWORD(id.DriverVersion.HighPart),
- LOWORD(id.DriverVersion.HighPart),
- HIWORD(id.DriverVersion.LowPart),
- LOWORD(id.DriverVersion.LowPart));
- desc.set_driver_version(buf);
- D3DInterface->GetDeviceCaps(adapter_index,WW3D_DEVTYPE,&desc.Caps);
- D3DInterface->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&desc.AdapterIdentifier);
- DX8Caps dx8caps(D3DInterface,desc.Caps,WW3D_FORMAT_UNKNOWN,desc.AdapterIdentifier);
- /*
- ** Enumerate the resolutions
- */
- desc.reset_resolution_list();
- int mode_count = D3DInterface->GetAdapterModeCount(adapter_index);
- for (int mode_index=0; mode_index<mode_count; mode_index++) {
- D3DDISPLAYMODE d3dmode;
- ::ZeroMemory(&d3dmode, sizeof(D3DDISPLAYMODE));
- HRESULT res = D3DInterface->EnumAdapterModes(adapter_index,mode_index,&d3dmode);
- if (res == D3D_OK) {
- int bits = 0;
- switch (d3dmode.Format)
- {
- case D3DFMT_R8G8B8:
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8: bits = 32; break;
- case D3DFMT_R5G6B5:
- case D3DFMT_X1R5G5B5: bits = 16; break;
- }
- // Some cards fail in certain modes, DX8Caps keeps list of those.
- if (!dx8caps.Is_Valid_Display_Format(d3dmode.Width,d3dmode.Height,D3DFormat_To_WW3DFormat(d3dmode.Format))) {
- bits=0;
- }
- /*
- ** If we recognize the format, add it to the list
- ** TODO: should we handle more formats? will any cards report more than 24 or 16 bit?
- */
- if (bits != 0) {
- desc.add_resolution(d3dmode.Width,d3dmode.Height,bits);
- }
- }
- }
- // IML: If the device has one or more valid resolutions add it to the device list.
- // NOTE: Testing has shown that there are drivers with zero resolutions.
- if (desc.Enumerate_Resolutions().Count() > 0) {
- /*
- ** Set up the device name
- */
- StringClass device_name(id.Description,true);
- _RenderDeviceNameTable.Add(device_name);
- _RenderDeviceShortNameTable.Add(device_name); // for now, just add the same name to the "pretty name table"
- /*
- ** Add the render device to our table
- */
- _RenderDeviceDescriptionTable.Add(desc);
- }
- }
- }
- }
- bool DX8Wrapper::Set_Any_Render_Device(void)
- {
- // Then fullscreen
- for (int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
- if (Set_Render_Device(dev_number,-1,-1,-1,0,false)) {
- return true;
- }
- }
- // Try windowed first
- for (dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
- if (Set_Render_Device(dev_number,-1,-1,-1,1,false)) {
- return true;
- }
- }
- return false;
- }
- bool DX8Wrapper::Set_Render_Device
- (
- const char * dev_name,
- int width,
- int height,
- int bits,
- int windowed,
- bool resize_window
- )
- {
- for ( int dev_number = 0; dev_number < _RenderDeviceNameTable.Count(); dev_number++) {
- if ( strcmp( dev_name, _RenderDeviceNameTable[dev_number]) == 0) {
- return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window );
- }
- if ( strcmp( dev_name, _RenderDeviceShortNameTable[dev_number]) == 0) {
- return Set_Render_Device( dev_number, width, height, bits, windowed, resize_window );
- }
- }
- return false;
- }
- bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed, bool resize_window)
- {
- WWASSERT(IsInitted);
- WWASSERT(dev >= -1);
- WWASSERT(dev < _RenderDeviceNameTable.Count());
- /*
- ** If user has never selected a render device, start out with device 0
- */
- if ((CurRenderDevice == -1) && (dev == -1)) {
- CurRenderDevice = 0;
- } else if (dev != -1) {
- CurRenderDevice = dev;
- }
- /*
- ** If user doesn't want to change res, set the res variables to match the
- ** current resolution
- */
- if (width != -1) ResolutionWidth = width;
- if (height != -1) ResolutionHeight = height;
- // Initialize Render2DClass Screen Resolution
- Render2DClass::Set_Screen_Resolution( RectClass( 0, 0, ResolutionWidth, ResolutionHeight ) );
- if (bits != -1) BitDepth = bits;
- if (windowed != -1) IsWindowed = (windowed != 0);
- WWDEBUG_SAY(("Attempting Set_Render_Device: name: %s, width: %d, height: %d, windowed: %d\r\n",
- _RenderDeviceNameTable[CurRenderDevice],ResolutionWidth,ResolutionHeight,(IsWindowed ? 1 : 0)));
- WWASSERT(D3DDevice == NULL);
- /*
- ** Initialize values for D3DPRESENT_PARAMETERS members.
- */
- ::ZeroMemory(&_PresentParameters, sizeof(D3DPRESENT_PARAMETERS));
- _PresentParameters.BackBufferWidth = ResolutionWidth;
- _PresentParameters.BackBufferHeight = ResolutionHeight;
- _PresentParameters.BackBufferCount = IsWindowed ? 1 : 2;
- _PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
- _PresentParameters.SwapEffect = IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP?
- _PresentParameters.hDeviceWindow = _Hwnd;
- _PresentParameters.Windowed = IsWindowed;
- _PresentParameters.EnableAutoDepthStencil = TRUE; // Driver will attempt to match Z-buffer depth
- _PresentParameters.Flags=0; // We're not going to lock the backbuffer
- _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- _PresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
- /*
- ** Set up the buffer formats. Several issues here:
- ** - if in windowed mode, the backbuffer must use the current display format.
- ** - the depth buffer must use
- */
- ::ZeroMemory(&DesktopMode, sizeof(D3DDISPLAYMODE));
- D3DInterface->GetAdapterDisplayMode( CurRenderDevice, &DesktopMode );
- _PresentParameters.BackBufferFormat = DesktopMode.Format;
- if (IsWindowed) {
- WWDEBUG_SAY(("Initializing windowed mode\r\n"));
- // 10/23/01 - Denzil - DX window initialization
- /*
- ** Enforce a required set of window styles and size if the main window
- ** IS NOT A CHILD WINDOW. :)
- */
- if ((::GetWindowLong(_Hwnd, GWL_STYLE) & WS_CHILD) == 0) {
- ::SetWindowLong(_Hwnd, GWL_STYLE, WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX|WS_CLIPCHILDREN);
- // Always resize the window to the desired resolution in windowed mode.
- resize_window = true;
- }
- // End Denzil - DX window initialzaion
- // In windowed mode, define the bitdepth from desktop mode (as it can't be changed)
- switch (_PresentParameters.BackBufferFormat) {
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- case D3DFMT_R8G8B8: BitDepth=32; break;
- case D3DFMT_A4R4G4B4:
- case D3DFMT_A1R5G5B5:
- case D3DFMT_R5G6B5: BitDepth=16; break;
- case D3DFMT_L8:
- case D3DFMT_A8:
- case D3DFMT_P8: BitDepth=8; break;
- default:
- // Unknown backbuffer format probably means the device can't do windowed
- return false;
- }
- WWDEBUG_SAY(("Using buffer format: %d\r\n",_PresentParameters.BackBufferFormat));
- /*
- ** Find an appropriate Z buffer
- */
- if (!Find_Z_Mode(_PresentParameters.BackBufferFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat))
- {
- // If opening 32 bit mode failed, try 16 bit, even if the desktop happens to be 32 bit
- if (BitDepth==32) {
- WWDEBUG_SAY(("Failed to find a 32 bit mode, trying 16 bit\r\n"));
- BitDepth=16;
- _PresentParameters.BackBufferFormat=D3DFMT_R5G6B5;
- if (!Find_Z_Mode(_PresentParameters.BackBufferFormat,_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat)) {
- _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN;
- }
- }
- else {
- _PresentParameters.AutoDepthStencilFormat=D3DFMT_UNKNOWN;
- }
- }
- } else {
- // 10/23/01 - Denzil - DX Window initialization
- // For fullscreen set the window style to WS_POPUP (Recommended in DX docs)
- SetWindowLong(_Hwnd, GWL_STYLE, WS_POPUP);
- // Set fullscreen window position to top left and resize to cover entire display.
- // Recommended in DX docs to prevent other windows on the desktop from attempting
- // to repaint. This also prevents the OS from spending time calculating invalid
- // rects for windows that will never been seen.
- SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0,
- GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
- SWP_SHOWWINDOW|SWP_NOCOPYBITS);
- // We already resized the window
- resize_window = false;
- // End Denzil - DX window initialization
- WWDEBUG_SAY(("Initializing full-screen mode\r\n"));
- /*
- ** Try to find a mode that matches the user's desired bit-depth.
- */
- Find_Color_And_Z_Mode(ResolutionWidth,ResolutionHeight,BitDepth,
- &_PresentParameters.BackBufferFormat,&_PresentParameters.AutoDepthStencilFormat);
- }
- #ifdef _WINDOWS
- // PWG 4/13/2000 - changed so that if you say to resize the window it resizes
- // regardless of whether its windowed or not as OpenGL resizes its self around
- // the caption and edges of the window type you provide, so its important to
- // push the client area to be the size you really want.
- // if ( resize_window && windowed ) {
- if (resize_window) {
- // Get the current dimensions of the 'render area' of the window
- RECT rect = { 0 };
- ::GetClientRect (_Hwnd, &rect);
- #if(0) // Denzil - DX Window initialization
- // Is the window the correct size for this resolution?
- if ((rect.right-rect.left) != ResolutionWidth ||
- (rect.bottom-rect.top) != ResolutionHeight) {
- // Calculate what the main window's bounding rectangle should be to
- // accomodate this resolution
- rect.left = 0;
- rect.top = 0;
- rect.right = ResolutionWidth;
- rect.bottom = ResolutionHeight;
- DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE);
- AdjustWindowRect (&rect, dwstyle, FALSE);
- // Resize the window to fit this resolution
- ::SetWindowPos (_Hwnd,
- NULL,
- 0,
- 0,
- rect.right-rect.left,
- rect.bottom-rect.top,
- SWP_NOZORDER | SWP_NOMOVE);
- }
- #else
- // Adjust the main window's client area to accomodate the resolution
- DWORD dwstyle = ::GetWindowLong(_Hwnd, GWL_STYLE);
- DWORD dwexstyle = ::GetWindowLong(_Hwnd, GWL_EXSTYLE);
- rect.right = ResolutionWidth;
- rect.bottom = ResolutionHeight;
- ::AdjustWindowRectEx(&rect, dwstyle, (::GetMenu(_Hwnd) != NULL), dwexstyle);
- ::SetWindowPos(_Hwnd, HWND_TOP, 0, 0,
- (rect.right - rect.left), (rect.bottom - rect.top),
- SWP_SHOWWINDOW|SWP_NOCOPYBITS);
- #endif
- }
- #endif
- /*
- ** Time to actually create the device.
- */
- if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) {
- if (BitDepth==32) {
- _PresentParameters.AutoDepthStencilFormat=D3DFMT_D32;
- }
- else {
- _PresentParameters.AutoDepthStencilFormat=D3DFMT_D16;
- }
- }
- return Create_Device();
- }
- bool DX8Wrapper::Set_Next_Render_Device(void)
- {
- int new_dev = (CurRenderDevice + 1) % _RenderDeviceNameTable.Count();
- return Set_Render_Device(new_dev);
- }
- bool DX8Wrapper::Toggle_Windowed(void)
- {
- #ifdef WW3D_DX8
- // State OK?
- assert (IsInitted);
- if (IsInitted) {
- // Get information about the current render device's resolutions
- const RenderDeviceDescClass &render_device = Get_Render_Device_Desc ();
- const DynamicVectorClass<ResolutionDescClass> &resolutions = render_device.Enumerate_Resolutions ();
- // Loop through all the resolutions supported by the current device.
- // If we aren't currently running under one of these resolutions,
- // then we should probably to the closest resolution before
- // toggling the windowed state.
- int curr_res = -1;
- for (int res = 0;
- (res < resolutions.Count ()) && (curr_res == -1);
- res ++) {
- // Is this the resolution we are looking for?
- if ((resolutions[res].Width == ResolutionWidth) &&
- (resolutions[res].Height == ResolutionHeight) &&
- (resolutions[res].BitDepth == BitDepth)) {
- curr_res = res;
- }
- }
- if (curr_res == -1) {
- // We don't match any of the standard resolutions,
- // so set the first resolution and toggle the windowed state.
- return Set_Device_Resolution (resolutions[0].Width,
- resolutions[0].Height,
- resolutions[0].BitDepth,
- !IsWindowed, true);
- } else {
- // Toggle the windowed state
- return Set_Device_Resolution (-1, -1, -1, !IsWindowed, true);
- }
- }
- #endif //WW3D_DX8
- return false;
- }
- void DX8Wrapper::Set_Swap_Interval(int swap)
- {
- switch (swap) {
- case 0: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break;
- case 1: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break;
- case 2: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_TWO; break;
- case 3: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_THREE; break;
- default: _PresentParameters.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE ; break;
- }
- Reset_Device();
- }
- int DX8Wrapper::Get_Swap_Interval(void)
- {
- return _PresentParameters.FullScreen_PresentationInterval;
- }
- int DX8Wrapper::Get_Render_Device_Count(void)
- {
- return _RenderDeviceNameTable.Count();
- }
- int DX8Wrapper::Get_Render_Device(void)
- {
- assert(IsInitted);
- return CurRenderDevice;
- }
- const RenderDeviceDescClass & DX8Wrapper::Get_Render_Device_Desc(int deviceidx)
- {
- WWASSERT(IsInitted);
- if ((deviceidx == -1) && (CurRenderDevice == -1)) {
- CurRenderDevice = 0;
- }
- // if the device index is -1 then we want the current device
- if (deviceidx == -1) {
- WWASSERT(CurRenderDevice >= 0);
- WWASSERT(CurRenderDevice < _RenderDeviceNameTable.Count());
- return _RenderDeviceDescriptionTable[CurRenderDevice];
- }
- // We can only ask for multiple device information if the devices
- // have been detected.
- WWASSERT(deviceidx >= 0);
- WWASSERT(deviceidx < _RenderDeviceNameTable.Count());
- return _RenderDeviceDescriptionTable[deviceidx];
- }
- const char * DX8Wrapper::Get_Render_Device_Name(int device_index)
- {
- device_index = device_index % _RenderDeviceShortNameTable.Count();
- return _RenderDeviceShortNameTable[device_index];
- }
- bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window)
- {
- if (D3DDevice != NULL) {
- if (width != -1) {
- _PresentParameters.BackBufferWidth = ResolutionWidth = width;
- }
- if (height != -1) {
- _PresentParameters.BackBufferHeight = ResolutionHeight = height;
- }
- #pragma message("TODO: support changing windowed status and changing the bit depth")
- return Reset_Device();
- } else {
- return false;
- }
- }
- void DX8Wrapper::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
- {
- WWASSERT(IsInitted);
- set_w = ResolutionWidth;
- set_h = ResolutionHeight;
- set_bits = BitDepth;
- set_windowed = IsWindowed;
- return ;
- }
- void DX8Wrapper::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
- {
- WWASSERT(IsInitted);
- if (CurrentRenderTarget != NULL) {
- D3DSURFACE_DESC info;
- CurrentRenderTarget->GetDesc (&info);
- set_w = info.Width;
- set_h = info.Height;
- set_bits = BitDepth; // should we get the actual bit depth of the target?
- set_windowed = IsWindowed; // this doesn't really make sense for render targets (shouldn't matter)...
- } else {
- Get_Device_Resolution (set_w, set_h, set_bits, set_windowed);
- }
- return ;
- }
- bool DX8Wrapper::Registry_Save_Render_Device( const char * sub_key )
- {
- int width, height, depth;
- bool windowed;
- Get_Device_Resolution(width, height, depth, windowed);
- return Registry_Save_Render_Device(sub_key, CurRenderDevice, ResolutionWidth, ResolutionHeight, BitDepth, IsWindowed, TextureBitDepth);
- }
- bool DX8Wrapper::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth)
- {
- RegistryClass * registry = new RegistryClass( sub_key );
- WWASSERT( registry );
- if ( !registry->Is_Valid() ) {
- delete registry;
- WWDEBUG_SAY(( "Error getting Registry\n" ));
- return false;
- }
- registry->Set_String( VALUE_NAME_RENDER_DEVICE_NAME,
- _RenderDeviceShortNameTable[device] );
- registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, width );
- registry->Set_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, height );
- registry->Set_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, depth );
- registry->Set_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, windowed );
- registry->Set_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, texture_depth );
- delete registry;
- return true;
- }
- bool DX8Wrapper::Registry_Load_Render_Device( const char * sub_key, bool resize_window )
- {
- char name[ 200 ];
- int width,height,depth,windowed;
- if ( Registry_Load_Render_Device( sub_key,
- name,
- sizeof(name),
- width,
- height,
- depth,
- windowed,
- TextureBitDepth) &&
- (*name != 0))
- {
- WWDEBUG_SAY(( "Device %s (%d X %d) %d bit windowed:%d\n", name,width,height,depth,windowed));
- if (TextureBitDepth==16 || TextureBitDepth==32) {
- // WWDEBUG_SAY(( "Texture depth %d\n", TextureBitDepth));
- } else {
- WWDEBUG_SAY(( "Invalid texture depth %d, switching to 16 bits\n", TextureBitDepth));
- TextureBitDepth=16;
- }
- // _RenderDeviceDescriptionTable.
- if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) != true) {
- if (depth==16) depth=32;
- else depth=16;
- if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) {
- return true;
- }
- if (depth==16) depth=32;
- else depth=16;
- // we'll test resolutions down, so if start is 640, increase to begin with...
- if (width==640) {
- width=1024;
- height=768;
- }
- while (true) {
- if (width>2048) {
- width=2048;
- height=1536;
- }
- else if (width>1920) {
- width=1920;
- height=1440;
- }
- else if (width>1600) {
- width=1600;
- height=1200;
- }
- else if (width>1280) {
- width=1280;
- height=1024;
- }
- else if (width>1024) {
- width=1024;
- height=768;
- }
- else if (width>800) {
- width=800;
- height=600;
- }
- else if (width!=640) {
- width=640;
- height=480;
- }
- else {
- return Set_Any_Render_Device();
- }
- for (int i=0;i<2;++i) {
- if ( Set_Render_Device( name, width,height,depth,windowed, resize_window ) == true) {
- return true;
- }
- if (depth==16) depth=32;
- else depth=16;
- }
- }
- }
- return true;
- }
- WWDEBUG_SAY(( "Error getting Registry\n" ));
- return Set_Any_Render_Device();
- }
- bool 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)
- {
- RegistryClass registry( sub_key );
- if ( registry.Is_Valid() ) {
- registry.Get_String( VALUE_NAME_RENDER_DEVICE_NAME,
- device, device_len);
- width = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WIDTH, -1 );
- height = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_HEIGHT, -1 );
- depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_DEPTH, -1 );
- windowed = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_WINDOWED, -1 );
- texture_depth = registry.Get_Int( VALUE_NAME_RENDER_DEVICE_TEXTURE_DEPTH, -1 );
- return true;
- }
- *device=0;
- width=-1;
- height=-1;
- depth=-1;
- windowed=-1;
- texture_depth=-1;
- return false;
- }
- bool DX8Wrapper::Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_zmode)
- {
- static D3DFORMAT _formats16[] =
- {
- D3DFMT_R5G6B5,
- D3DFMT_X1R5G5B5,
- D3DFMT_A1R5G5B5
- };
- static D3DFORMAT _formats32[] =
- {
- D3DFMT_A8R8G8B8,
- D3DFMT_X8R8G8B8,
- D3DFMT_R8G8B8,
- };
- /*
- ** Select the table that we're going to use to search for a valid backbuffer format
- */
- D3DFORMAT * format_table = NULL;
- int format_count = 0;
- if (BitDepth == 16) {
- format_table = _formats16;
- format_count = sizeof(_formats16) / sizeof(D3DFORMAT);
- } else {
- format_table = _formats32;
- format_count = sizeof(_formats32) / sizeof(D3DFORMAT);
- }
- /*
- ** now search for a valid format
- */
- bool found = false;
- unsigned int mode = 0;
- for (int format_index=0; format_index < format_count; format_index++) {
- found |= Find_Color_Mode(format_table[format_index],resx,resy,&mode);
- if (found) break;
- }
- if (!found) {
- return false;
- } else {
- *set_colorbuffer = format_table[format_index];
- }
- /*
- ** We found a backbuffer format, now find a zbuffer format
- */
- return Find_Z_Mode(*set_colorbuffer,*set_colorbuffer, set_zmode);
- };
- // find the resolution mode with at least resx,resy with the highest supported
- // refresh rate
- bool DX8Wrapper::Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode)
- {
- UINT i,j,modemax;
- UINT rx,ry;
- D3DDISPLAYMODE dmode;
- ::ZeroMemory(&dmode, sizeof(D3DDISPLAYMODE));
- rx=(unsigned int) resx;
- ry=(unsigned int) resy;
- bool found=false;
- modemax=D3DInterface->GetAdapterModeCount(D3DADAPTER_DEFAULT);
- i=0;
- while (i<modemax && !found)
- {
- D3DInterface->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &dmode);
- if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer) {
- WWDEBUG_SAY(("Found valid color mode. Width = %d Height = %d Format = %d\r\n",dmode.Width,dmode.Height,dmode.Format));
- found=true;
- }
- i++;
- }
- i--; // this is the first valid mode
- // no match
- if (!found) {
- WWDEBUG_SAY(("Failed to find a valid color mode\r\n"));
- return false;
- }
- // go to the highest refresh rate in this mode
- bool stillok=true;
- j=i;
- while (j<modemax && stillok)
- {
- D3DInterface->EnumAdapterModes(D3DADAPTER_DEFAULT, j, &dmode);
- if (dmode.Width==rx && dmode.Height==ry && dmode.Format==colorbuffer)
- stillok=true; else stillok=false;
- j++;
- }
- if (stillok==false) *mode=j-2;
- else *mode=i;
- return true;
- }
- // Helper function to find a Z buffer mode for the colorbuffer
- // Will look for greatest Z precision
- bool DX8Wrapper::Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode)
- {
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D32))
- {
- *zmode=D3DFMT_D32;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D32\r\n"));
- return true;
- }
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24S8))
- {
- *zmode=D3DFMT_D24S8;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24S8\r\n"));
- return true;
- }
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X8))
- {
- *zmode=D3DFMT_D24X8;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X8\r\n"));
- return true;
- }
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D24X4S4))
- {
- *zmode=D3DFMT_D24X4S4;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D24X4S4\r\n"));
- return true;
- }
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D16))
- {
- *zmode=D3DFMT_D16;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D16\r\n"));
- return true;
- }
- if (Test_Z_Mode(colorbuffer,backbuffer,D3DFMT_D15S1))
- {
- *zmode=D3DFMT_D15S1;
- WWDEBUG_SAY(("Found zbuffer mode D3DFMT_D15S1\r\n"));
- return true;
- }
- // can't find a match
- WWDEBUG_SAY(("Failed to find a valid zbuffer mode\r\n"));
- return false;
- }
- bool DX8Wrapper::Test_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT zmode)
- {
- // See if we have this mode first
- if (FAILED(D3DInterface->CheckDeviceFormat(D3DADAPTER_DEFAULT,WW3D_DEVTYPE,
- colorbuffer,D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,zmode)))
- {
- WWDEBUG_SAY(("CheckDeviceFormat failed. Colorbuffer format = %d Zbufferformat = %d\r\n",colorbuffer,zmode));
- return false;
- }
- // Then see if it matches the color buffer
- if(FAILED(D3DInterface->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, WW3D_DEVTYPE,
- colorbuffer,backbuffer,zmode)))
- {
- WWDEBUG_SAY(("CheckDepthStencilMatch failed. Colorbuffer format = %d Backbuffer format = %d Zbufferformat = %d\r\n",colorbuffer,backbuffer,zmode));
- return false;
- }
- return true;
- }
- void DX8Wrapper::Reset_Statistics()
- {
- matrix_changes = 0;
- material_changes = 0;
- vertex_buffer_changes = 0;
- index_buffer_changes = 0;
- light_changes = 0;
- texture_changes = 0;
- render_state_changes =0;
- texture_stage_state_changes =0;
- number_of_DX8_calls = 0;
- last_frame_matrix_changes = 0;
- last_frame_material_changes = 0;
- last_frame_vertex_buffer_changes = 0;
- last_frame_index_buffer_changes = 0;
- last_frame_light_changes = 0;
- last_frame_texture_changes = 0;
- last_frame_render_state_changes = 0;
- last_frame_texture_stage_state_changes = 0;
- last_frame_number_of_DX8_calls = 0;
- }
- void DX8Wrapper::Begin_Statistics()
- {
- matrix_changes=0;
- material_changes=0;
- vertex_buffer_changes=0;
- index_buffer_changes=0;
- light_changes=0;
- texture_changes = 0;
- render_state_changes =0;
- texture_stage_state_changes =0;
- number_of_DX8_calls=0;
- }
- void DX8Wrapper::End_Statistics()
- {
- last_frame_matrix_changes=matrix_changes;
- last_frame_material_changes=material_changes;
- last_frame_vertex_buffer_changes=vertex_buffer_changes;
- last_frame_index_buffer_changes=index_buffer_changes;
- last_frame_light_changes=light_changes;
- last_frame_texture_changes = texture_changes;
- last_frame_render_state_changes = render_state_changes;
- last_frame_texture_stage_state_changes = texture_stage_state_changes;
- last_frame_number_of_DX8_calls=number_of_DX8_calls;
- }
- unsigned DX8Wrapper::Get_Last_Frame_Matrix_Changes() { return last_frame_matrix_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Material_Changes() { return last_frame_material_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Vertex_Buffer_Changes() { return last_frame_vertex_buffer_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Index_Buffer_Changes() { return last_frame_index_buffer_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Light_Changes() { return last_frame_light_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Texture_Changes() { return last_frame_texture_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Render_State_Changes() { return last_frame_render_state_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_Texture_Stage_State_Changes() { return last_frame_texture_stage_state_changes; }
- unsigned DX8Wrapper::Get_Last_Frame_DX8_Calls() { return last_frame_number_of_DX8_calls; }
- unsigned long DX8Wrapper::Get_FrameCount(void) {return FrameCount;}
- void DX8_Assert()
- {
- WWASSERT(DX8Wrapper::_Get_D3D8());
- DX8_THREAD_ASSERT();
- }
- void DX8Wrapper::Begin_Scene(void)
- {
- DX8_THREAD_ASSERT();
- DX8CALL(BeginScene());
- }
- void DX8Wrapper::End_Scene(bool flip_frames)
- {
- DX8_THREAD_ASSERT();
- DX8CALL(EndScene());
- if (flip_frames) {
- // JANI HACK! Some objects flicker on ATI Radeons. This can be fixed by locking the back buffer before flipping.
- // Remember that for this to work the back buffers need to have been create as lockable!
- if (Get_Current_Caps()->Get_Vendor()==DX8Caps::VENDOR_ATI) {
- IDirect3DSurface8 * bb;
- DX8CALL(GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&bb));
- D3DLOCKED_RECT rect;
- HRESULT res=bb->LockRect(
- &rect,
- NULL,
- D3DLOCK_READONLY);
- if (res==D3D_OK) {
- bb->UnlockRect();
- bb->Release();
- }
- }
- DX8_Assert();
- HRESULT hr;
- {
- WWPROFILE("DX8Device::Present()");
- hr=_Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL);
- }
- number_of_DX8_calls++;
- if (SUCCEEDED(hr)) {
- IsDeviceLost=false;
- FrameCount++;
- }
- else {
- IsDeviceLost=true;
- }
- // If the device was lost we need to check for cooperative level and possibly reset the device
- if (hr==D3DERR_DEVICELOST) {
- hr=_Get_D3D_Device8()->TestCooperativeLevel();
- if (hr==D3DERR_DEVICENOTRESET) {
- Reset_Device();
- }
- else {
- // Sleep it not active
- ThreadClass::Sleep_Ms(200);
- }
- }
- else {
- DX8_ErrorCode(hr);
- }
- }
- // Each frame, release all of the buffers and textures.
- Set_Vertex_Buffer(NULL);
- Set_Index_Buffer(NULL,0);
- for (unsigned i=0;i<MAX_TEXTURE_STAGES;++i) Set_Texture(i,NULL);
- Set_Material(NULL);
- }
- void DX8Wrapper::Flip_To_Primary(void)
- {
- // If we are fullscreen and the current frame is odd then we need
- // to force a page flip to ensure that the first buffer in the flipping
- // chain is the one visible.
- if (!IsWindowed) {
- DX8_Assert();
- int numBuffers = (_PresentParameters.BackBufferCount + 1);
- int visibleBuffer = (FrameCount % numBuffers);
- int flipCount = ((numBuffers - visibleBuffer) % numBuffers);
- int resetAttempts = 0;
- while ((flipCount > 0) && (resetAttempts < 3)) {
- HRESULT hr = _Get_D3D_Device8()->TestCooperativeLevel();
- if (FAILED(hr)) {
- WWDEBUG_SAY(("TestCooperativeLevel Failed!\n"));
- if (D3DERR_DEVICELOST == hr) {
- IsDeviceLost=true;
- WWDEBUG_SAY(("DEVICELOST: Cannot flip to primary.\n"));
- return;
- }
- IsDeviceLost=false;
- if (D3DERR_DEVICENOTRESET == hr) {
- WWDEBUG_SAY(("DEVICENOTRESET\n"));
- Reset_Device();
- resetAttempts++;
- }
- } else {
- WWDEBUG_SAY(("Flipping: %ld\n", FrameCount));
- hr = _Get_D3D_Device8()->Present(NULL, NULL, NULL, NULL);
- if (SUCCEEDED(hr)) {
- IsDeviceLost=false;
- FrameCount++;
- WWDEBUG_SAY(("Flip to primary succeeded %ld\n", FrameCount));
- }
- else {
- IsDeviceLost=true;
- }
- }
- --flipCount;
- }
- }
- }
- void DX8Wrapper::Clear(bool clear_color, bool clear_z_stencil, const Vector3 &color, float z, unsigned int stencil)
- {
- DX8_THREAD_ASSERT();
- // If we try to clear a stencil buffer which is not there, the entire call will fail
- bool has_stencil = ( _PresentParameters.AutoDepthStencilFormat == D3DFMT_D15S1 ||
- _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24S8 ||
- _PresentParameters.AutoDepthStencilFormat == D3DFMT_D24X4S4);
- DWORD flags = 0;
- if (clear_color) flags |= D3DCLEAR_TARGET;
- if (clear_z_stencil) flags |= D3DCLEAR_ZBUFFER;
- if (clear_z_stencil && has_stencil) flags |= D3DCLEAR_STENCIL;
- if (flags)
- {
- DX8CALL(Clear(0, NULL, flags, Convert_Color(color,0.0f), z, stencil));
- }
- }
- void DX8Wrapper::Set_Viewport(CONST D3DVIEWPORT8* pViewport)
- {
- DX8_THREAD_ASSERT();
- DX8CALL(SetViewport(pViewport));
- }
- // ----------------------------------------------------------------------------
- //
- // Set vertex buffer. A reference to previous vertex buffer is released and
- // this one is assigned the current vertex buffer. The DX8 vertex buffer will
- // actually be set in Apply() which is called by Draw_Indexed_Triangles().
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Set_Vertex_Buffer(const VertexBufferClass* vb)
- {
- render_state.vba_offset=0;
- render_state.vba_count=0;
- if (render_state.vertex_buffer) {
- render_state.vertex_buffer->Release_Engine_Ref();
- }
- REF_PTR_SET(render_state.vertex_buffer,const_cast<VertexBufferClass*>(vb));
- if (vb) {
- vb->Add_Engine_Ref();
- render_state.vertex_buffer_type=vb->Type();
- }
- else {
- render_state.index_buffer_type=BUFFER_TYPE_INVALID;
- }
- render_state_changed|=VERTEX_BUFFER_CHANGED;
- }
- // ----------------------------------------------------------------------------
- //
- // Set index buffer. A reference to previous index buffer is released and
- // this one is assigned the current index buffer. The DX8 index buffer will
- // actually be set in Apply() which is called by Draw_Indexed_Triangles().
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Set_Index_Buffer(const IndexBufferClass* ib,unsigned short index_base_offset)
- {
- render_state.iba_offset=0;
- if (render_state.index_buffer) {
- render_state.index_buffer->Release_Engine_Ref();
- }
- REF_PTR_SET(render_state.index_buffer,const_cast<IndexBufferClass*>(ib));
- render_state.index_base_offset=index_base_offset;
- if (ib) {
- ib->Add_Engine_Ref();
- render_state.index_buffer_type=ib->Type();
- }
- else {
- render_state.index_buffer_type=BUFFER_TYPE_INVALID;
- }
- render_state_changed|=INDEX_BUFFER_CHANGED;
- }
- // ----------------------------------------------------------------------------
- //
- // Set vertex buffer using dynamic access object.
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Set_Vertex_Buffer(const DynamicVBAccessClass& vba_)
- {
- if (render_state.vertex_buffer) render_state.vertex_buffer->Release_Engine_Ref();
- DynamicVBAccessClass& vba=const_cast<DynamicVBAccessClass&>(vba_);
- render_state.vertex_buffer_type=vba.Get_Type();
- render_state.vba_offset=vba.VertexBufferOffset;
- render_state.vba_count=vba.Get_Vertex_Count();
- REF_PTR_SET(render_state.vertex_buffer,vba.VertexBuffer);
- render_state.vertex_buffer->Add_Engine_Ref();
- render_state_changed|=VERTEX_BUFFER_CHANGED;
- render_state_changed|=INDEX_BUFFER_CHANGED; // vba_offset changes so index buffer needs to be reset as well.
- }
- // ----------------------------------------------------------------------------
- //
- // Set index buffer using dynamic access object.
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Set_Index_Buffer(const DynamicIBAccessClass& iba_,unsigned short index_base_offset)
- {
- if (render_state.index_buffer) render_state.index_buffer->Release_Engine_Ref();
- DynamicIBAccessClass& iba=const_cast<DynamicIBAccessClass&>(iba_);
- render_state.index_base_offset=index_base_offset;
- render_state.index_buffer_type=iba.Get_Type();
- render_state.iba_offset=iba.IndexBufferOffset;
- REF_PTR_SET(render_state.index_buffer,iba.IndexBuffer);
- render_state.index_buffer->Add_Engine_Ref();
- render_state_changed|=INDEX_BUFFER_CHANGED;
- }
- // ----------------------------------------------------------------------------
- //
- // Private function for the special case of rendering polygons from sorting
- // index and vertex buffers.
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Draw_Sorting_IB_VB(
- unsigned primitive_type,
- unsigned short start_index,
- unsigned short polygon_count,
- unsigned short min_vertex_index,
- unsigned short vertex_count)
- {
- WWASSERT(render_state.vertex_buffer_type==BUFFER_TYPE_SORTING || render_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING);
- WWASSERT(render_state.index_buffer_type==BUFFER_TYPE_SORTING || render_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING);
- // Fill dynamic vertex buffer with sorting vertex buffer vertices
- DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertex_count);
- {
- DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access);
- VertexFormatXYZNDUV2* src = static_cast<SortingVertexBufferClass*>(render_state.vertex_buffer)->VertexBuffer;
- VertexFormatXYZNDUV2* dest= lock.Get_Formatted_Vertex_Array();
- src += render_state.vba_offset + render_state.index_base_offset + min_vertex_index;
- unsigned size = dyn_vb_access.FVF_Info().Get_FVF_Size()*vertex_count/sizeof(unsigned);
- unsigned *dest_u =(unsigned*) dest;
- unsigned *src_u = (unsigned*) src;
- for (unsigned i=0;i<size;++i) {
- *dest_u++=*src_u++;
- }
- }
- DX8CALL(SetStreamSource(
- 0,
- static_cast<DX8VertexBufferClass*>(dyn_vb_access.VertexBuffer)->Get_DX8_Vertex_Buffer(),
- dyn_vb_access.FVF_Info().Get_FVF_Size()));
- DX8CALL(SetVertexShader(dyn_vb_access.FVF_Info().Get_FVF()));
- DX8_RECORD_VERTEX_BUFFER_CHANGE();
- unsigned index_count=0;
- switch (primitive_type) {
- case D3DPT_TRIANGLELIST: index_count=polygon_count*3; break;
- case D3DPT_TRIANGLESTRIP: index_count=polygon_count+2; break;
- case D3DPT_TRIANGLEFAN: index_count=polygon_count+2; break;
- default: WWASSERT(0); break; // Unsupported primitive type
- }
- // Fill dynamic index buffer with sorting index buffer vertices
- DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,index_count);
- {
- DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access);
- unsigned short* dest=lock.Get_Index_Array();
- unsigned short* src=NULL;
- src=static_cast<SortingIndexBufferClass*>(render_state.index_buffer)->index_buffer;
- src+=render_state.iba_offset+start_index;
- for (unsigned short i=0;i<index_count;++i) {
- unsigned short index=*src++;
- index-=min_vertex_index;
- WWASSERT(index<vertex_count);
- *dest++=index;
- }
- }
- DX8CALL(SetIndices(
- static_cast<DX8IndexBufferClass*>(dyn_ib_access.IndexBuffer)->Get_DX8_Index_Buffer(),
- dyn_vb_access.VertexBufferOffset));
- DX8_RECORD_INDEX_BUFFER_CHANGE();
- DX8CALL(DrawIndexedPrimitive(
- D3DPT_TRIANGLELIST,
- 0, // start vertex
- vertex_count,
- dyn_ib_access.IndexBufferOffset,
- polygon_count));
- DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader);
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Draw(
- unsigned primitive_type,
- unsigned short start_index,
- unsigned short polygon_count,
- unsigned short min_vertex_index,
- unsigned short vertex_count)
- {
- DX8_THREAD_ASSERT();
- SNAPSHOT_SAY(("DX8 - draw\n"));
- Apply_Render_State_Changes();
- // Debug feature to disable triangle drawing...
- if (!_Is_Triangle_Draw_Enabled()) return;
- #ifdef MESH_RENDER_SNAPSHOT_ENABLED
- if (WW3D::Is_Snapshot_Activated()) {
- unsigned long passes=0;
- SNAPSHOT_SAY(("ValidateDevice: "));
- HRESULT res=D3DDevice->ValidateDevice(&passes);
- switch (res) {
- case D3D_OK:
- SNAPSHOT_SAY(("OK\n"));
- break;
- case D3DERR_CONFLICTINGTEXTUREFILTER:
- SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREFILTER\n"));
- break;
- case D3DERR_CONFLICTINGTEXTUREPALETTE:
- SNAPSHOT_SAY(("D3DERR_CONFLICTINGTEXTUREPALETTE\n"));
- break;
- case D3DERR_DEVICELOST:
- SNAPSHOT_SAY(("D3DERR_DEVICELOST\n"));
- break;
- case D3DERR_TOOMANYOPERATIONS:
- SNAPSHOT_SAY(("D3DERR_TOOMANYOPERATIONS\n"));
- break;
- case D3DERR_UNSUPPORTEDALPHAARG:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAARG\n"));
- break;
- case D3DERR_UNSUPPORTEDALPHAOPERATION:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDALPHAOPERATION\n"));
- break;
- case D3DERR_UNSUPPORTEDCOLORARG:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLORARG\n"));
- break;
- case D3DERR_UNSUPPORTEDCOLOROPERATION:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDCOLOROPERATION\n"));
- break;
- case D3DERR_UNSUPPORTEDFACTORVALUE:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDFACTORVALUE\n"));
- break;
- case D3DERR_UNSUPPORTEDTEXTUREFILTER:
- SNAPSHOT_SAY(("D3DERR_UNSUPPORTEDTEXTUREFILTER\n"));
- break;
- case D3DERR_WRONGTEXTUREFORMAT:
- SNAPSHOT_SAY(("D3DERR_WRONGTEXTUREFORMAT\n"));
- break;
- default:
- SNAPSHOT_SAY(("UNKNOWN Error\n"));
- break;
- }
- }
- #endif // MESH_RENDER_SHAPSHOT_ENABLED
- SNAPSHOT_SAY(("DX8 - draw %d polygons (%d vertices)\n",polygon_count,vertex_count));
- if (vertex_count<3) {
- min_vertex_index=0;
- switch (render_state.vertex_buffer_type) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_SORTING:
- vertex_count=render_state.vertex_buffer->Get_Vertex_Count()-render_state.index_base_offset-render_state.vba_offset-min_vertex_index;
- break;
- case BUFFER_TYPE_DYNAMIC_DX8:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- vertex_count=render_state.vba_count;
- break;
- }
- }
- switch (render_state.vertex_buffer_type) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_DYNAMIC_DX8:
- switch (render_state.index_buffer_type) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_DYNAMIC_DX8:
- {
- DX8_RECORD_RENDER(polygon_count,vertex_count,render_state.shader);
- DX8CALL(DrawIndexedPrimitive(
- (D3DPRIMITIVETYPE)primitive_type,
- min_vertex_index,
- vertex_count,
- start_index+render_state.iba_offset,
- polygon_count));
- }
- break;
- case BUFFER_TYPE_SORTING:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)");
- break;
- case BUFFER_TYPE_INVALID:
- WWASSERT(0);
- break;
- }
- break;
- case BUFFER_TYPE_SORTING:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- switch (render_state.index_buffer_type) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_DYNAMIC_DX8:
- WWASSERT_PRINT(0,"VB and IB must of same type (sorting or dx8)");
- break;
- case BUFFER_TYPE_SORTING:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- Draw_Sorting_IB_VB(primitive_type,start_index,polygon_count,min_vertex_index,vertex_count);
- break;
- case BUFFER_TYPE_INVALID:
- WWASSERT(0);
- break;
- }
- break;
- case BUFFER_TYPE_INVALID:
- WWASSERT(0);
- break;
- }
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Draw_Triangles(
- unsigned buffer_type,
- unsigned short start_index,
- unsigned short polygon_count,
- unsigned short min_vertex_index,
- unsigned short vertex_count)
- {
- if (buffer_type==BUFFER_TYPE_SORTING || buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) {
- SortingRendererClass::Insert_Triangles(start_index,polygon_count,min_vertex_index,vertex_count);
- }
- else {
- Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count);
- }
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Draw_Triangles(
- unsigned short start_index,
- unsigned short polygon_count,
- unsigned short min_vertex_index,
- unsigned short vertex_count)
- {
- Draw(D3DPT_TRIANGLELIST,start_index,polygon_count,min_vertex_index,vertex_count);
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Draw_Strip(
- unsigned short start_index,
- unsigned short polygon_count,
- unsigned short min_vertex_index,
- unsigned short vertex_count)
- {
- Draw(D3DPT_TRIANGLESTRIP,start_index,polygon_count,min_vertex_index,vertex_count);
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Apply_Render_State_Changes()
- {
- if (!render_state_changed) return;
- if (render_state_changed&SHADER_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply shader\n"));
- render_state.shader.Apply();
- }
- unsigned mask=TEXTURE0_CHANGED;
- for (unsigned i=0;i<MAX_TEXTURE_STAGES;++i,mask<<=1) {
- if (render_state_changed&mask) {
- SNAPSHOT_SAY(("DX8 - apply texture %d (%s)\n",i,render_state.Textures[i] ? render_state.Textures[i]->Get_Full_Path() : "NULL"));
- if (render_state.Textures[i]) render_state.Textures[i]->Apply(i);
- else TextureClass::Apply_Null(i);
- }
- else {
- SNAPSHOT_SAY(("DX8 - texture %d not changed (%s)\n",i,render_state.Textures[i] ? render_state.Textures[i]->Get_Full_Path() : "NULL"));
- }
- }
- if (render_state_changed&MATERIAL_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply material\n"));
- VertexMaterialClass* material=const_cast<VertexMaterialClass*>(render_state.material);
- if (material) {
- material->Apply();
- }
- else VertexMaterialClass::Apply_Null();
- }
- if (render_state_changed&LIGHTS_CHANGED)
- {
- unsigned mask=LIGHT0_CHANGED;
- for (unsigned index=0;index<4;++index,mask<<=1) {
- if (render_state_changed&mask) {
- SNAPSHOT_SAY(("DX8 - apply light %d\n",index));
- if (render_state.LightEnable[index]) {
- Set_DX8_Light(index,&render_state.Lights[index]);
- }
- else {
- Set_DX8_Light(index,NULL);
- }
- }
- }
- }
- if (render_state_changed&WORLD_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply world matrix\n"));
- _Set_DX8_Transform(D3DTS_WORLD,render_state.world);
- }
- if (render_state_changed&VIEW_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply view matrix\n"));
- _Set_DX8_Transform(D3DTS_VIEW,render_state.view);
- }
- if (render_state_changed&VERTEX_BUFFER_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply vb change\n"));
- if (render_state.vertex_buffer) {
- switch (render_state.vertex_buffer_type) {//->Type()) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_DYNAMIC_DX8:
- DX8CALL(SetStreamSource(
- 0,
- static_cast<DX8VertexBufferClass*>(render_state.vertex_buffer)->Get_DX8_Vertex_Buffer(),
- render_state.vertex_buffer->FVF_Info().Get_FVF_Size()));
- DX8_RECORD_VERTEX_BUFFER_CHANGE();
- DX8CALL(SetVertexShader(render_state.vertex_buffer->FVF_Info().Get_FVF()));
- break;
- case BUFFER_TYPE_SORTING:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- break;
- default:
- WWASSERT(0);
- }
- } else {
- DX8CALL(SetStreamSource(0,NULL,0));
- DX8_RECORD_VERTEX_BUFFER_CHANGE();
- }
- }
- if (render_state_changed&INDEX_BUFFER_CHANGED) {
- SNAPSHOT_SAY(("DX8 - apply ib change\n"));
- if (render_state.index_buffer) {
- switch (render_state.index_buffer_type) {//->Type()) {
- case BUFFER_TYPE_DX8:
- case BUFFER_TYPE_DYNAMIC_DX8:
- DX8CALL(SetIndices(
- static_cast<DX8IndexBufferClass*>(render_state.index_buffer)->Get_DX8_Index_Buffer(),
- render_state.index_base_offset+render_state.vba_offset));
- DX8_RECORD_INDEX_BUFFER_CHANGE();
- break;
- case BUFFER_TYPE_SORTING:
- case BUFFER_TYPE_DYNAMIC_SORTING:
- break;
- default:
- WWASSERT(0);
- }
- }
- else {
- DX8CALL(SetIndices(
- NULL,
- 0));
- DX8_RECORD_INDEX_BUFFER_CHANGE();
- }
- }
- render_state_changed&=((unsigned)WORLD_IDENTITY|(unsigned)VIEW_IDENTITY);
- }
- IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture(
- unsigned int width,
- unsigned int height,
- WW3DFormat format,
- TextureClass::MipCountType mip_level_count,
- D3DPOOL pool,
- bool rendertarget)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- IDirect3DTexture8 *texture = NULL;
- // Paletted textures not supported!
- WWASSERT(format!=D3DFMT_P8);
- // NOTE: If 'format' is not supported as a texture format, this function will find the closest
- // format that is supported and use that instead.
- // Render target may return NOTAVAILABLE, in
- // which case we return NULL.
- if (rendertarget) {
- unsigned ret=D3DXCreateTexture(
- DX8Wrapper::_Get_D3D_Device8(),
- width,
- height,
- mip_level_count,
- D3DUSAGE_RENDERTARGET,
- WW3DFormat_To_D3DFormat(format),
- pool,
- &texture);
- if (ret==D3DERR_NOTAVAILABLE) {
- Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
- return NULL;
- }
- // If ran out of texture ram, try invalidating some textures and mesh cache.
- if (ret==D3DERR_OUTOFVIDEOMEMORY) {
- WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets...\n"));
- // Free all textures that haven't been used in the last 5 seconds
- TextureClass::Invalidate_Old_Unused_Textures(5000);
- // Invalidate the mesh cache
- WW3D::_Invalidate_Mesh_Cache();
- ret=D3DXCreateTexture(
- DX8Wrapper::_Get_D3D_Device8(),
- width,
- height,
- mip_level_count,
- D3DUSAGE_RENDERTARGET,
- WW3DFormat_To_D3DFormat(format),
- pool,
- &texture);
- if (SUCCEEDED(ret)) {
- WWDEBUG_SAY(("...Render target creation succesful.\n"));
- }
- else {
- WWDEBUG_SAY(("...Render target creation failed.\n"));
- }
- if (ret==D3DERR_OUTOFVIDEOMEMORY) {
- Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
- return NULL;
- }
- }
- DX8_ErrorCode(ret);
- // Just return the texture, no reduction
- // allowed for render targets.
- return texture;
- }
- // We should never run out of video memory when allocating a non-rendertarget texture.
- // However, it seems to happen sometimes when there are a lot of textures in memory and so
- // if it happens we'll release assets and try again (anything is better than crashing).
- unsigned ret=D3DXCreateTexture(
- DX8Wrapper::_Get_D3D_Device8(),
- width,
- height,
- mip_level_count,
- 0,
- WW3DFormat_To_D3DFormat(format),
- pool,
- &texture);
- // If ran out of texture ram, try invalidating some textures and mesh cache.
- if (ret==D3DERR_OUTOFVIDEOMEMORY) {
- WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets...\n"));
- // Free all textures that haven't been used in the last 5 seconds
- TextureClass::Invalidate_Old_Unused_Textures(5000);
- // Invalidate the mesh cache
- WW3D::_Invalidate_Mesh_Cache();
- ret=D3DXCreateTexture(
- DX8Wrapper::_Get_D3D_Device8(),
- width,
- height,
- mip_level_count,
- 0,
- WW3DFormat_To_D3DFormat(format),
- pool,
- &texture);
- if (SUCCEEDED(ret)) {
- WWDEBUG_SAY(("...Texture creation succesful.\n"));
- }
- else {
- StringClass format_name(0,true);
- Get_WW3D_Format_Name(format, format_name);
- WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d\n",width,height,format_name,mip_level_count));
- }
- }
- DX8_ErrorCode(ret);
- return texture;
- }
- IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture(
- const char *filename,
- TextureClass::MipCountType mip_level_count)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- IDirect3DTexture8 *texture = NULL;
- // NOTE: If the original image format is not supported as a texture format, it will
- // automatically be converted to an appropriate format.
- // NOTE: It is possible to get the size and format of the original image file from this
- // function as well, so if we later want to second-guess D3DX's format conversion decisions
- // we can do so after this function is called..
- unsigned result = D3DXCreateTextureFromFileExA(
- _Get_D3D_Device8(),
- filename,
- D3DX_DEFAULT,
- D3DX_DEFAULT,
- mip_level_count,//create_mipmaps ? 0 : 1,
- 0,
- D3DFMT_UNKNOWN,
- D3DPOOL_MANAGED,
- D3DX_FILTER_BOX,
- D3DX_FILTER_BOX,
- 0,
- NULL,
- NULL,
- &texture);
- if (result != D3D_OK) {
- return MissingTexture::_Get_Missing_Texture();
- }
- // Make sure texture wasn't paletted!
- D3DSURFACE_DESC desc;
- texture->GetLevelDesc(0,&desc);
- if (desc.Format==D3DFMT_P8) {
- texture->Release();
- return MissingTexture::_Get_Missing_Texture();
- }
- return texture;
- }
- IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture(
- IDirect3DSurface8 *surface,
- TextureClass::MipCountType mip_level_count)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- IDirect3DTexture8 *texture = NULL;
- D3DSURFACE_DESC surface_desc;
- ::ZeroMemory(&surface_desc, sizeof(D3DSURFACE_DESC));
- surface->GetDesc(&surface_desc);
- // This function will create a texture with a different (but similar) format if the surface is
- // not in a supported texture format.
- WW3DFormat format=D3DFormat_To_WW3DFormat(surface_desc.Format);
- texture = _Create_DX8_Texture(surface_desc.Width, surface_desc.Height, format, mip_level_count);
- // Copy the surface to the texture
- IDirect3DSurface8 *tex_surface = NULL;
- texture->GetSurfaceLevel(0, &tex_surface);
- DX8_ErrorCode(D3DXLoadSurfaceFromSurface(tex_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_BOX, 0));
- tex_surface->Release();
- // Create mipmaps if needed
- if (mip_level_count!=TextureClass::MIP_LEVELS_1) {
- DX8_ErrorCode(D3DXFilterTexture(texture, NULL, 0, D3DX_FILTER_BOX));
- }
- return texture;
- }
- IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- IDirect3DSurface8 *surface = NULL;
- // Paletted surfaces not supported!
- WWASSERT(format!=D3DFMT_P8);
- DX8CALL(CreateImageSurface(width, height, WW3DFormat_To_D3DFormat(format), &surface));
- return surface;
- }
- IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(const char *filename_)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- // Note: Since there is no "D3DXCreateSurfaceFromFile" and no "GetSurfaceInfoFromFile" (the
- // latter is supposed to be added to D3DX in a future version), we create a texture from the
- // file (w/o mipmaps), check that its surface is equal to the original file data (which it
- // will not be if the file is not in a texture-supported format or size). If so, copy its
- // surface (we might be able to just get its surface and add a ref to it but I'm not sure so
- // I'm not going to risk it) and release the texture. If not, create a surface according to
- // the file data and use D3DXLoadSurfaceFromFile. This is a horrible hack, but it saves us
- // having to write file loaders. Will fix this when D3DX provides us with the right functions.
- // Create a surface the size of the file image data
- IDirect3DSurface8 *surface = NULL;
- {
- file_auto_ptr myfile(_TheFileFactory,filename_);
- // If file not found, create a surface with missing texture in it
- if (!myfile->Is_Available()) {
- return MissingTexture::_Create_Missing_Surface();
- }
- }
- StringClass filename_string(filename_,true);
- surface=TextureLoader::Load_Surface_Immediate(
- filename_string,
- WW3D_FORMAT_UNKNOWN,
- true);
- return surface;
- }
- /***********************************************************************************************
- * DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/26/2001 hy : Created. *
- *=============================================================================================*/
- void DX8Wrapper::_Update_Texture(TextureClass *system, TextureClass *video)
- {
- WWASSERT(system);
- WWASSERT(video);
- WWASSERT(system->Pool==TextureClass::POOL_SYSTEMMEM);
- WWASSERT(video->Pool==TextureClass::POOL_DEFAULT);
- DX8CALL(UpdateTexture(system->D3DTexture,video->D3DTexture));
- }
- void DX8Wrapper::Compute_Caps(WW3DFormat display_format)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- delete CurrentCaps;
- CurrentCaps=new DX8Caps(_Get_D3D8(),D3DDevice,display_format,Get_Current_Adapter_Identifier());
- }
- void DX8Wrapper::Set_Light(unsigned index,const LightClass &light)
- {
- D3DLIGHT8 dlight;
- Vector3 temp;
- memset(&dlight,0,sizeof(D3DLIGHT8));
- switch (light.Get_Type())
- {
- case LightClass::POINT:
- {
- dlight.Type=D3DLIGHT_POINT;
- }
- break;
- case LightClass::DIRECTIONAL:
- {
- dlight.Type=D3DLIGHT_DIRECTIONAL;
- }
- break;
- case LightClass::SPOT:
- {
- dlight.Type=D3DLIGHT_SPOT;
- }
- break;
- }
- light.Get_Diffuse(&temp);
- temp*=light.Get_Intensity();
- dlight.Diffuse.r=temp.X;
- dlight.Diffuse.g=temp.Y;
- dlight.Diffuse.b=temp.Z;
- dlight.Diffuse.a=1.0f;
- light.Get_Specular(&temp);
- temp*=light.Get_Intensity();
- dlight.Specular.r=temp.X;
- dlight.Specular.g=temp.Y;
- dlight.Specular.b=temp.Z;
- dlight.Specular.a=1.0f;
- light.Get_Ambient(&temp);
- temp*=light.Get_Intensity();
- dlight.Ambient.r=temp.X;
- dlight.Ambient.g=temp.Y;
- dlight.Ambient.b=temp.Z;
- dlight.Ambient.a=1.0f;
- temp=light.Get_Position();
- dlight.Position=*(D3DVECTOR*) &temp;
- light.Get_Spot_Direction(temp);
- dlight.Direction=*(D3DVECTOR*) &temp;
- dlight.Range=light.Get_Attenuation_Range();
- dlight.Falloff=light.Get_Spot_Exponent();
- dlight.Theta=light.Get_Spot_Angle();
- dlight.Phi=light.Get_Spot_Angle();
- // Inverse linear light 1/(1+D)
- double a,b;
- light.Get_Far_Attenuation_Range(a,b);
- dlight.Attenuation0=1.0f;
- if (fabs(a-b)<1e-5)
- // if the attenuation range is too small assume uniform with cutoff
- dlight.Attenuation1=0.0f;
- else
- // this will cause the light to drop to half intensity at the first far attenuation
- dlight.Attenuation1=(float) 1.0/a;
- dlight.Attenuation2=0.0f;
- Set_Light(index,&dlight);
- }
- // ----------------------------------------------------------------------------
- //
- // Set the light environment. This is a lighting model which used up to four
- // directional lights to produce the lighting.
- //
- // ----------------------------------------------------------------------------
- void DX8Wrapper::Set_Light_Environment(LightEnvironmentClass* light_env)
- {
- if (light_env) {
- int light_count = light_env->Get_Light_Count();
- Set_DX8_Render_State(D3DRS_AMBIENT,Convert_Color(light_env->Get_Equivalent_Ambient(),0.0f));
- D3DLIGHT8 light;
- ::ZeroMemory(&light, sizeof(D3DLIGHT8));
- light.Type=D3DLIGHT_DIRECTIONAL;
- for (int l=0;l<light_count;++l) {
- (Vector3&)light.Diffuse=light_env->Get_Light_Diffuse(l);
- Vector3 dir=-light_env->Get_Light_Direction(l);
- light.Direction=(const D3DVECTOR&)(dir);
- Set_Light(l,&light);
- }
- for (;l<4;++l) {
- Set_Light(l,NULL);
- }
- }
- /* else {
- for (int l=0;l<4;++l) {
- Set_Light(l,NULL);
- }
- }
- */
- }
- IDirect3DSurface8 * DX8Wrapper::_Get_DX8_Front_Buffer()
- {
- DX8_THREAD_ASSERT();
- D3DDISPLAYMODE mode;
- DX8CALL(GetDisplayMode(&mode));
- IDirect3DSurface8 * fb=NULL;
- DX8CALL(CreateImageSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,&fb));
- DX8CALL(GetFrontBuffer(fb));
- return fb;
- }
- SurfaceClass * DX8Wrapper::_Get_DX8_Back_Buffer(unsigned int num)
- {
- DX8_THREAD_ASSERT();
- IDirect3DSurface8 * bb;
- SurfaceClass *surf=NULL;
- DX8CALL(GetBackBuffer(num,D3DBACKBUFFER_TYPE_MONO,&bb));
- if (bb)
- {
- surf=NEW_REF(SurfaceClass,(bb));
- bb->Release();
- }
- return surf;
- }
- TextureClass *
- DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- number_of_DX8_calls++;
- // Use the current display format if format isn't specified
- if (format==WW3D_FORMAT_UNKNOWN) {
- D3DDISPLAYMODE mode;
- DX8CALL(GetDisplayMode(&mode));
- format=D3DFormat_To_WW3DFormat(mode.Format);
- }
- // If render target format isn't supported return NULL
- if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format)) {
- WWDEBUG_SAY(("DX8Wrapper - Render target format is not supported\r\n"));
- return NULL;
- }
- //
- // Note: We're going to force the width and height to be powers of two and equal
- //
- const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps();
- float poweroftwosize = width;
- if (height > 0 && height < width) {
- poweroftwosize = height;
- }
- poweroftwosize = ::Find_POT (poweroftwosize);
- if (poweroftwosize>dx8caps.MaxTextureWidth) {
- poweroftwosize=dx8caps.MaxTextureWidth;
- }
- if (poweroftwosize>dx8caps.MaxTextureHeight) {
- poweroftwosize=dx8caps.MaxTextureHeight;
- }
- width = height = poweroftwosize;
- //
- // Attempt to create the render target
- //
- TextureClass * tex = NEW_REF(TextureClass,(width,height,format,TextureClass::MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true));
- // 3dfx drivers are lying in the CheckDeviceFormat call and claiming
- // that they support render targets!
- if (tex->Peek_DX8_Texture() == NULL) {
- WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!\r\n"));
- REF_PTR_RELEASE(tex);
- }
- return tex;
- }
- void
- DX8Wrapper::Set_Render_Target (TextureClass * texture)
- {
- WWASSERT(texture != NULL);
- IDirect3DSurface8 * d3d_surf = texture->Get_D3D_Surface_Level();
- WWASSERT(d3d_surf != NULL);
- Set_Render_Target(d3d_surf);
- d3d_surf->Release();
- IsRenderToTexture = true;
- }
- void
- DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain)
- {
- DX8_THREAD_ASSERT();
- WWASSERT (swap_chain != NULL);
- //
- // Get the back buffer for the swap chain
- //
- LPDIRECT3DSURFACE8 render_target = NULL;
- swap_chain->GetBackBuffer (0, D3DBACKBUFFER_TYPE_MONO, &render_target);
- //
- // Set this back buffer as the render targer
- //
- Set_Render_Target (render_target, true);
- //
- // Release our hold on the back buffer
- //
- if (render_target != NULL) {
- render_target->Release ();
- render_target = NULL;
- }
- IsRenderToTexture = false;
- return ;
- }
- void
- DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default_depth_buffer)
- {
- DX8_THREAD_ASSERT();
- DX8_Assert();
- //
- // Should we restore the default render target set a new one?
- //
- if (render_target == NULL || render_target == DefaultRenderTarget) {
- // If there is currently a custom render target, default must NOT be NULL.
- if (CurrentRenderTarget) {
- WWASSERT(DefaultRenderTarget!=NULL);
- }
- //
- // Restore the default render target
- //
- if (DefaultRenderTarget != NULL) {
- DX8CALL(SetRenderTarget (DefaultRenderTarget, DefaultDepthBuffer));
- DefaultRenderTarget->Release ();
- DefaultRenderTarget = NULL;
- if (DefaultDepthBuffer) {
- DefaultDepthBuffer->Release ();
- DefaultDepthBuffer = NULL;
- }
- }
- //
- // Release our hold on the "current" render target
- //
- if (CurrentRenderTarget != NULL) {
- CurrentRenderTarget->Release ();
- CurrentRenderTarget = NULL;
- }
- } else if (render_target != CurrentRenderTarget) {
- WWASSERT(DefaultRenderTarget==NULL);
- //
- // We'll need the depth buffer later...
- //
- if (DefaultDepthBuffer == NULL) {
- // IDirect3DSurface8 *depth_buffer = NULL;
- DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer));
- }
- //
- // Get a pointer to the default render target (if necessary)
- //
- if (DefaultRenderTarget == NULL) {
- DX8CALL(GetRenderTarget (&DefaultRenderTarget));
- }
- //
- // Release our hold on the old "current" render target
- //
- if (CurrentRenderTarget != NULL) {
- CurrentRenderTarget->Release ();
- CurrentRenderTarget = NULL;
- }
- //
- // Keep a copy of the current render target (for housekeeping)
- //
- CurrentRenderTarget = render_target;
- WWASSERT (CurrentRenderTarget != NULL);
- if (CurrentRenderTarget != NULL) {
- CurrentRenderTarget->AddRef ();
- //
- // Switch render targets
- //
- if (use_default_depth_buffer) {
- DX8CALL(SetRenderTarget (CurrentRenderTarget, DefaultDepthBuffer));
- } else {
- DX8CALL(SetRenderTarget (CurrentRenderTarget, NULL));
- }
- }
- }
- //
- // Free our hold on the depth buffer
- //
- // if (depth_buffer != NULL) {
- // depth_buffer->Release ();
- // depth_buffer = NULL;
- // }
- IsRenderToTexture = false;
- return ;
- }
- IDirect3DSwapChain8 *
- DX8Wrapper::Create_Additional_Swap_Chain (HWND render_window)
- {
- DX8_Assert();
- //
- // Configure the presentation parameters for a windowed render target
- //
- D3DPRESENT_PARAMETERS params = { 0 };
- params.BackBufferFormat = _PresentParameters.BackBufferFormat;
- params.BackBufferCount = 1;
- params.MultiSampleType = D3DMULTISAMPLE_NONE;
- params.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
- params.hDeviceWindow = render_window;
- params.Windowed = TRUE;
- params.EnableAutoDepthStencil = TRUE;
- params.AutoDepthStencilFormat = _PresentParameters.AutoDepthStencilFormat;
- params.Flags = 0;
- params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
- params.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- //
- // Create the swap chain
- //
- IDirect3DSwapChain8 *swap_chain = NULL;
- DX8CALL(CreateAdditionalSwapChain(¶ms, &swap_chain));
- return swap_chain;
- }
- void DX8Wrapper::Flush_DX8_Resource_Manager(unsigned int bytes)
- {
- DX8_Assert();
- DX8CALL(ResourceManagerDiscardBytes(bytes));
- }
- unsigned int DX8Wrapper::Get_Free_Texture_RAM()
- {
- DX8_Assert();
- number_of_DX8_calls++;
- return DX8Wrapper::_Get_D3D_Device8()->GetAvailableTextureMem();
- }
- // Converts a linear gamma ramp to one that is controlled by:
- // Gamma - controls the curvature of the middle of the curve
- // Bright - controls the minimum value of the curve
- // Contrast - controls the difference between the maximum and the minimum of the curve
- void DX8Wrapper::Set_Gamma(float gamma,float bright,float contrast,bool calibrate,bool uselimit)
- {
- gamma=Bound(gamma,0.6f,6.0f);
- bright=Bound(bright,-0.5f,0.5f);
- contrast=Bound(contrast,0.5f,2.0f);
- float oo_gamma=1.0f/gamma;
- DX8_Assert();
- number_of_DX8_calls++;
- DWORD flag=(calibrate?D3DSGR_CALIBRATE:D3DSGR_NO_CALIBRATION);
- D3DGAMMARAMP ramp;
- float limit;
- // IML: I'm not really sure what the intent of the 'limit' variable is. It does not produce useful results for my purposes.
- if (uselimit) {
- limit=(contrast-1)/2*contrast;
- } else {
- limit = 0.0f;
- }
- // HY - arrived at this equation after much trial and error.
- for (int i=0; i<256; i++) {
- float in,out;
- in=i/256.0f;
- float x=in-limit;
- x=Bound(x,0.0f,1.0f);
- x=powf(x,oo_gamma);
- out=contrast*x+bright;
- out=Bound(out,0.0f,1.0f);
- ramp.red[i]=(WORD) (out*65535);
- ramp.green[i]=(WORD) (out*65535);
- ramp.blue[i]=(WORD) (out*65535);
- }
- if (Get_Current_Caps()->Support_Gamma()) {
- DX8Wrapper::_Get_D3D_Device8()->SetGammaRamp(flag,&ramp);
- } else {
- HWND hwnd = GetDesktopWindow();
- HDC hdc = GetDC(hwnd);
- if (hdc)
- {
- SetDeviceGammaRamp (hdc, &ramp);
- ReleaseDC (hwnd, hdc);
- }
- }
- }
- const char* DX8Wrapper::Get_DX8_Render_State_Name(D3DRENDERSTATETYPE state)
- {
- switch (state) {
- case D3DRS_ZENABLE : return "D3DRS_ZENABLE";
- case D3DRS_FILLMODE : return "D3DRS_FILLMODE";
- case D3DRS_SHADEMODE : return "D3DRS_SHADEMODE";
- case D3DRS_LINEPATTERN : return "D3DRS_LINEPATTERN";
- case D3DRS_ZWRITEENABLE : return "D3DRS_ZWRITEENABLE";
- case D3DRS_ALPHATESTENABLE : return "D3DRS_ALPHATESTENABLE";
- case D3DRS_LASTPIXEL : return "D3DRS_LASTPIXEL";
- case D3DRS_SRCBLEND : return "D3DRS_SRCBLEND";
- case D3DRS_DESTBLEND : return "D3DRS_DESTBLEND";
- case D3DRS_CULLMODE : return "D3DRS_CULLMODE";
- case D3DRS_ZFUNC : return "D3DRS_ZFUNC";
- case D3DRS_ALPHAREF : return "D3DRS_ALPHAREF";
- case D3DRS_ALPHAFUNC : return "D3DRS_ALPHAFUNC";
- case D3DRS_DITHERENABLE : return "D3DRS_DITHERENABLE";
- case D3DRS_ALPHABLENDENABLE : return "D3DRS_ALPHABLENDENABLE";
- case D3DRS_FOGENABLE : return "D3DRS_FOGENABLE";
- case D3DRS_SPECULARENABLE : return "D3DRS_SPECULARENABLE";
- case D3DRS_ZVISIBLE : return "D3DRS_ZVISIBLE";
- case D3DRS_FOGCOLOR : return "D3DRS_FOGCOLOR";
- case D3DRS_FOGTABLEMODE : return "D3DRS_FOGTABLEMODE";
- case D3DRS_FOGSTART : return "D3DRS_FOGSTART";
- case D3DRS_FOGEND : return "D3DRS_FOGEND";
- case D3DRS_FOGDENSITY : return "D3DRS_FOGDENSITY";
- case D3DRS_EDGEANTIALIAS : return "D3DRS_EDGEANTIALIAS";
- case D3DRS_ZBIAS : return "D3DRS_ZBIAS";
- case D3DRS_RANGEFOGENABLE : return "D3DRS_RANGEFOGENABLE";
- case D3DRS_STENCILENABLE : return "D3DRS_STENCILENABLE";
- case D3DRS_STENCILFAIL : return "D3DRS_STENCILFAIL";
- case D3DRS_STENCILZFAIL : return "D3DRS_STENCILZFAIL";
- case D3DRS_STENCILPASS : return "D3DRS_STENCILPASS";
- case D3DRS_STENCILFUNC : return "D3DRS_STENCILFUNC";
- case D3DRS_STENCILREF : return "D3DRS_STENCILREF";
- case D3DRS_STENCILMASK : return "D3DRS_STENCILMASK";
- case D3DRS_STENCILWRITEMASK : return "D3DRS_STENCILWRITEMASK";
- case D3DRS_TEXTUREFACTOR : return "D3DRS_TEXTUREFACTOR";
- case D3DRS_WRAP0 : return "D3DRS_WRAP0";
- case D3DRS_WRAP1 : return "D3DRS_WRAP1";
- case D3DRS_WRAP2 : return "D3DRS_WRAP2";
- case D3DRS_WRAP3 : return "D3DRS_WRAP3";
- case D3DRS_WRAP4 : return "D3DRS_WRAP4";
- case D3DRS_WRAP5 : return "D3DRS_WRAP5";
- case D3DRS_WRAP6 : return "D3DRS_WRAP6";
- case D3DRS_WRAP7 : return "D3DRS_WRAP7";
- case D3DRS_CLIPPING : return "D3DRS_CLIPPING";
- case D3DRS_LIGHTING : return "D3DRS_LIGHTING";
- case D3DRS_AMBIENT : return "D3DRS_AMBIENT";
- case D3DRS_FOGVERTEXMODE : return "D3DRS_FOGVERTEXMODE";
- case D3DRS_COLORVERTEX : return "D3DRS_COLORVERTEX";
- case D3DRS_LOCALVIEWER : return "D3DRS_LOCALVIEWER";
- case D3DRS_NORMALIZENORMALS : return "D3DRS_NORMALIZENORMALS";
- case D3DRS_DIFFUSEMATERIALSOURCE : return "D3DRS_DIFFUSEMATERIALSOURCE";
- case D3DRS_SPECULARMATERIALSOURCE : return "D3DRS_SPECULARMATERIALSOURCE";
- case D3DRS_AMBIENTMATERIALSOURCE : return "D3DRS_AMBIENTMATERIALSOURCE";
- case D3DRS_EMISSIVEMATERIALSOURCE : return "D3DRS_EMISSIVEMATERIALSOURCE";
- case D3DRS_VERTEXBLEND : return "D3DRS_VERTEXBLEND";
- case D3DRS_CLIPPLANEENABLE : return "D3DRS_CLIPPLANEENABLE";
- case D3DRS_SOFTWAREVERTEXPROCESSING : return "D3DRS_SOFTWAREVERTEXPROCESSING";
- case D3DRS_POINTSIZE : return "D3DRS_POINTSIZE";
- case D3DRS_POINTSIZE_MIN : return "D3DRS_POINTSIZE_MIN";
- case D3DRS_POINTSPRITEENABLE : return "D3DRS_POINTSPRITEENABLE";
- case D3DRS_POINTSCALEENABLE : return "D3DRS_POINTSCALEENABLE";
- case D3DRS_POINTSCALE_A : return "D3DRS_POINTSCALE_A";
- case D3DRS_POINTSCALE_B : return "D3DRS_POINTSCALE_B";
- case D3DRS_POINTSCALE_C : return "D3DRS_POINTSCALE_C";
- case D3DRS_MULTISAMPLEANTIALIAS : return "D3DRS_MULTISAMPLEANTIALIAS";
- case D3DRS_MULTISAMPLEMASK : return "D3DRS_MULTISAMPLEMASK";
- case D3DRS_PATCHEDGESTYLE : return "D3DRS_PATCHEDGESTYLE";
- case D3DRS_PATCHSEGMENTS : return "D3DRS_PATCHSEGMENTS";
- case D3DRS_DEBUGMONITORTOKEN : return "D3DRS_DEBUGMONITORTOKEN";
- case D3DRS_POINTSIZE_MAX : return "D3DRS_POINTSIZE_MAX";
- case D3DRS_INDEXEDVERTEXBLENDENABLE : return "D3DRS_INDEXEDVERTEXBLENDENABLE";
- case D3DRS_COLORWRITEENABLE : return "D3DRS_COLORWRITEENABLE";
- case D3DRS_TWEENFACTOR : return "D3DRS_TWEENFACTOR";
- case D3DRS_BLENDOP : return "D3DRS_BLENDOP";
- // case D3DRS_POSITIONORDER : return "D3DRS_POSITIONORDER";
- // case D3DRS_NORMALORDER : return "D3DRS_NORMALORDER";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Stage_State_Name(D3DTEXTURESTAGESTATETYPE state)
- {
- switch (state) {
- case D3DTSS_COLOROP : return "D3DTSS_COLOROP";
- case D3DTSS_COLORARG1 : return "D3DTSS_COLORARG1";
- case D3DTSS_COLORARG2 : return "D3DTSS_COLORARG2";
- case D3DTSS_ALPHAOP : return "D3DTSS_ALPHAOP";
- case D3DTSS_ALPHAARG1 : return "D3DTSS_ALPHAARG1";
- case D3DTSS_ALPHAARG2 : return "D3DTSS_ALPHAARG2";
- case D3DTSS_BUMPENVMAT00 : return "D3DTSS_BUMPENVMAT00";
- case D3DTSS_BUMPENVMAT01 : return "D3DTSS_BUMPENVMAT01";
- case D3DTSS_BUMPENVMAT10 : return "D3DTSS_BUMPENVMAT10";
- case D3DTSS_BUMPENVMAT11 : return "D3DTSS_BUMPENVMAT11";
- case D3DTSS_TEXCOORDINDEX : return "D3DTSS_TEXCOORDINDEX";
- case D3DTSS_ADDRESSU : return "D3DTSS_ADDRESSU";
- case D3DTSS_ADDRESSV : return "D3DTSS_ADDRESSV";
- case D3DTSS_BORDERCOLOR : return "D3DTSS_BORDERCOLOR";
- case D3DTSS_MAGFILTER : return "D3DTSS_MAGFILTER";
- case D3DTSS_MINFILTER : return "D3DTSS_MINFILTER";
- case D3DTSS_MIPFILTER : return "D3DTSS_MIPFILTER";
- case D3DTSS_MIPMAPLODBIAS : return "D3DTSS_MIPMAPLODBIAS";
- case D3DTSS_MAXMIPLEVEL : return "D3DTSS_MAXMIPLEVEL";
- case D3DTSS_MAXANISOTROPY : return "D3DTSS_MAXANISOTROPY";
- case D3DTSS_BUMPENVLSCALE : return "D3DTSS_BUMPENVLSCALE";
- case D3DTSS_BUMPENVLOFFSET : return "D3DTSS_BUMPENVLOFFSET";
- case D3DTSS_TEXTURETRANSFORMFLAGS : return "D3DTSS_TEXTURETRANSFORMFLAGS";
- case D3DTSS_ADDRESSW : return "D3DTSS_ADDRESSW";
- case D3DTSS_COLORARG0 : return "D3DTSS_COLORARG0";
- case D3DTSS_ALPHAARG0 : return "D3DTSS_ALPHAARG0";
- case D3DTSS_RESULTARG : return "D3DTSS_RESULTARG";
- default : return "UNKNOWN";
- }
- }
- void DX8Wrapper::Get_DX8_Render_State_Value_Name(StringClass& name, D3DRENDERSTATETYPE state, unsigned value)
- {
- switch (state) {
- case D3DRS_ZENABLE:
- name=Get_DX8_ZBuffer_Type_Name(value);
- break;
- case D3DRS_FILLMODE:
- name=Get_DX8_Fill_Mode_Name(value);
- break;
- case D3DRS_SHADEMODE:
- name=Get_DX8_Shade_Mode_Name(value);
- break;
- case D3DRS_LINEPATTERN:
- case D3DRS_FOGCOLOR:
- case D3DRS_ALPHAREF:
- case D3DRS_STENCILMASK:
- case D3DRS_STENCILWRITEMASK:
- case D3DRS_TEXTUREFACTOR:
- case D3DRS_AMBIENT:
- case D3DRS_CLIPPLANEENABLE:
- case D3DRS_MULTISAMPLEMASK:
- name.Format("0x%x",value);
- break;
- case D3DRS_ZWRITEENABLE:
- case D3DRS_ALPHATESTENABLE:
- case D3DRS_LASTPIXEL:
- case D3DRS_DITHERENABLE:
- case D3DRS_ALPHABLENDENABLE:
- case D3DRS_FOGENABLE:
- case D3DRS_SPECULARENABLE:
- case D3DRS_STENCILENABLE:
- case D3DRS_RANGEFOGENABLE:
- case D3DRS_EDGEANTIALIAS:
- case D3DRS_CLIPPING:
- case D3DRS_LIGHTING:
- case D3DRS_COLORVERTEX:
- case D3DRS_LOCALVIEWER:
- case D3DRS_NORMALIZENORMALS:
- case D3DRS_SOFTWAREVERTEXPROCESSING:
- case D3DRS_POINTSPRITEENABLE:
- case D3DRS_POINTSCALEENABLE:
- case D3DRS_MULTISAMPLEANTIALIAS:
- case D3DRS_INDEXEDVERTEXBLENDENABLE:
- name=value ? "TRUE" : "FALSE";
- break;
- case D3DRS_SRCBLEND:
- case D3DRS_DESTBLEND:
- name=Get_DX8_Blend_Name(value);
- break;
- case D3DRS_CULLMODE:
- name=Get_DX8_Cull_Mode_Name(value);
- break;
- case D3DRS_ZFUNC:
- case D3DRS_ALPHAFUNC:
- case D3DRS_STENCILFUNC:
- name=Get_DX8_Cmp_Func_Name(value);
- break;
- case D3DRS_ZVISIBLE:
- name="NOTSUPPORTED";
- break;
- case D3DRS_FOGTABLEMODE:
- case D3DRS_FOGVERTEXMODE:
- name=Get_DX8_Fog_Mode_Name(value);
- break;
- case D3DRS_FOGSTART:
- case D3DRS_FOGEND:
- case D3DRS_FOGDENSITY:
- case D3DRS_POINTSIZE:
- case D3DRS_POINTSIZE_MIN:
- case D3DRS_POINTSCALE_A:
- case D3DRS_POINTSCALE_B:
- case D3DRS_POINTSCALE_C:
- case D3DRS_PATCHSEGMENTS:
- case D3DRS_POINTSIZE_MAX:
- case D3DRS_TWEENFACTOR:
- name.Format("%f",*(float*)&value);
- break;
- case D3DRS_ZBIAS:
- case D3DRS_STENCILREF:
- name.Format("%d",value);
- break;
- case D3DRS_STENCILFAIL:
- case D3DRS_STENCILZFAIL:
- case D3DRS_STENCILPASS:
- name=Get_DX8_Stencil_Op_Name(value);
- break;
- case D3DRS_WRAP0:
- case D3DRS_WRAP1:
- case D3DRS_WRAP2:
- case D3DRS_WRAP3:
- case D3DRS_WRAP4:
- case D3DRS_WRAP5:
- case D3DRS_WRAP6:
- case D3DRS_WRAP7:
- name="0";
- if (value&D3DWRAP_U) name+="|D3DWRAP_U";
- if (value&D3DWRAP_V) name+="|D3DWRAP_V";
- if (value&D3DWRAP_W) name+="|D3DWRAP_W";
- break;
- case D3DRS_DIFFUSEMATERIALSOURCE:
- case D3DRS_SPECULARMATERIALSOURCE:
- case D3DRS_AMBIENTMATERIALSOURCE:
- case D3DRS_EMISSIVEMATERIALSOURCE:
- name=Get_DX8_Material_Source_Name(value);
- break;
- case D3DRS_VERTEXBLEND:
- name=Get_DX8_Vertex_Blend_Flag_Name(value);
- break;
- case D3DRS_PATCHEDGESTYLE:
- name=Get_DX8_Patch_Edge_Style_Name(value);
- break;
- case D3DRS_DEBUGMONITORTOKEN:
- name=Get_DX8_Debug_Monitor_Token_Name(value);
- break;
- case D3DRS_COLORWRITEENABLE:
- name="0";
- if (value&D3DCOLORWRITEENABLE_RED) name+="|D3DCOLORWRITEENABLE_RED";
- if (value&D3DCOLORWRITEENABLE_GREEN) name+="|D3DCOLORWRITEENABLE_GREEN";
- if (value&D3DCOLORWRITEENABLE_BLUE) name+="|D3DCOLORWRITEENABLE_BLUE";
- if (value&D3DCOLORWRITEENABLE_ALPHA) name+="|D3DCOLORWRITEENABLE_ALPHA";
- break;
- case D3DRS_BLENDOP:
- name=Get_DX8_Blend_Op_Name(value);
- break;
- default:
- name.Format("UNKNOWN (%d)",value);
- break;
- }
- }
- void DX8Wrapper::Get_DX8_Texture_Stage_State_Value_Name(StringClass& name, D3DTEXTURESTAGESTATETYPE state, unsigned value)
- {
- switch (state) {
- case D3DTSS_COLOROP:
- case D3DTSS_ALPHAOP:
- name=Get_DX8_Texture_Op_Name(value);
- break;
- case D3DTSS_COLORARG0:
- case D3DTSS_COLORARG1:
- case D3DTSS_COLORARG2:
- case D3DTSS_ALPHAARG0:
- case D3DTSS_ALPHAARG1:
- case D3DTSS_ALPHAARG2:
- case D3DTSS_RESULTARG:
- name=Get_DX8_Texture_Arg_Name(value);
- break;
- case D3DTSS_ADDRESSU:
- case D3DTSS_ADDRESSV:
- case D3DTSS_ADDRESSW:
- name=Get_DX8_Texture_Address_Name(value);
- break;
- case D3DTSS_MAGFILTER:
- case D3DTSS_MINFILTER:
- case D3DTSS_MIPFILTER:
- name=Get_DX8_Texture_Filter_Name(value);
- break;
- case D3DTSS_TEXTURETRANSFORMFLAGS:
- name=Get_DX8_Texture_Transform_Flag_Name(value);
- // Floating point values
- case D3DTSS_MIPMAPLODBIAS:
- case D3DTSS_BUMPENVMAT00:
- case D3DTSS_BUMPENVMAT01:
- case D3DTSS_BUMPENVMAT10:
- case D3DTSS_BUMPENVMAT11:
- case D3DTSS_BUMPENVLSCALE:
- case D3DTSS_BUMPENVLOFFSET:
- name.Format("%f",*(float*)&value);
- break;
- case D3DTSS_TEXCOORDINDEX:
- if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACENORMAL) {
- name.Format("D3DTSS_TCI_CAMERASPACENORMAL|%d",value&0xffff);
- }
- else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEPOSITION) {
- name.Format("D3DTSS_TCI_CAMERASPACEPOSITION|%d",value&0xffff);
- }
- else if ((value&0xffff0000)==D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) {
- name.Format("D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR|%d",value&0xffff);
- }
- else {
- name.Format("%d",value);
- }
- break;
- // Integer value
- case D3DTSS_MAXMIPLEVEL:
- case D3DTSS_MAXANISOTROPY:
- name.Format("%d",value);
- break;
- // Hex values
- case D3DTSS_BORDERCOLOR:
- name.Format("0x%x",value);
- break;
- default:
- name.Format("UNKNOWN (%d)",value);
- break;
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Op_Name(unsigned value)
- {
- switch (value) {
- case D3DTOP_DISABLE : return "D3DTOP_DISABLE";
- case D3DTOP_SELECTARG1 : return "D3DTOP_SELECTARG1";
- case D3DTOP_SELECTARG2 : return "D3DTOP_SELECTARG2";
- case D3DTOP_MODULATE : return "D3DTOP_MODULATE";
- case D3DTOP_MODULATE2X : return "D3DTOP_MODULATE2X";
- case D3DTOP_MODULATE4X : return "D3DTOP_MODULATE4X";
- case D3DTOP_ADD : return "D3DTOP_ADD";
- case D3DTOP_ADDSIGNED : return "D3DTOP_ADDSIGNED";
- case D3DTOP_ADDSIGNED2X : return "D3DTOP_ADDSIGNED2X";
- case D3DTOP_SUBTRACT : return "D3DTOP_SUBTRACT";
- case D3DTOP_ADDSMOOTH : return "D3DTOP_ADDSMOOTH";
- case D3DTOP_BLENDDIFFUSEALPHA : return "D3DTOP_BLENDDIFFUSEALPHA";
- case D3DTOP_BLENDTEXTUREALPHA : return "D3DTOP_BLENDTEXTUREALPHA";
- case D3DTOP_BLENDFACTORALPHA : return "D3DTOP_BLENDFACTORALPHA";
- case D3DTOP_BLENDTEXTUREALPHAPM : return "D3DTOP_BLENDTEXTUREALPHAPM";
- case D3DTOP_BLENDCURRENTALPHA : return "D3DTOP_BLENDCURRENTALPHA";
- case D3DTOP_PREMODULATE : return "D3DTOP_PREMODULATE";
- case D3DTOP_MODULATEALPHA_ADDCOLOR : return "D3DTOP_MODULATEALPHA_ADDCOLOR";
- case D3DTOP_MODULATECOLOR_ADDALPHA : return "D3DTOP_MODULATECOLOR_ADDALPHA";
- case D3DTOP_MODULATEINVALPHA_ADDCOLOR : return "D3DTOP_MODULATEINVALPHA_ADDCOLOR";
- case D3DTOP_MODULATEINVCOLOR_ADDALPHA : return "D3DTOP_MODULATEINVCOLOR_ADDALPHA";
- case D3DTOP_BUMPENVMAP : return "D3DTOP_BUMPENVMAP";
- case D3DTOP_BUMPENVMAPLUMINANCE : return "D3DTOP_BUMPENVMAPLUMINANCE";
- case D3DTOP_DOTPRODUCT3 : return "D3DTOP_DOTPRODUCT3";
- case D3DTOP_MULTIPLYADD : return "D3DTOP_MULTIPLYADD";
- case D3DTOP_LERP : return "D3DTOP_LERP";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Arg_Name(unsigned value)
- {
- switch (value) {
- case D3DTA_CURRENT : return "D3DTA_CURRENT";
- case D3DTA_DIFFUSE : return "D3DTA_DIFFUSE";
- case D3DTA_SELECTMASK : return "D3DTA_SELECTMASK";
- case D3DTA_SPECULAR : return "D3DTA_SPECULAR";
- case D3DTA_TEMP : return "D3DTA_TEMP";
- case D3DTA_TEXTURE : return "D3DTA_TEXTURE";
- case D3DTA_TFACTOR : return "D3DTA_TFACTOR";
- case D3DTA_ALPHAREPLICATE : return "D3DTA_ALPHAREPLICATE";
- case D3DTA_COMPLEMENT : return "D3DTA_COMPLEMENT";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Filter_Name(unsigned value)
- {
- switch (value) {
- case D3DTEXF_NONE : return "D3DTEXF_NONE";
- case D3DTEXF_POINT : return "D3DTEXF_POINT";
- case D3DTEXF_LINEAR : return "D3DTEXF_LINEAR";
- case D3DTEXF_ANISOTROPIC : return "D3DTEXF_ANISOTROPIC";
- case D3DTEXF_FLATCUBIC : return "D3DTEXF_FLATCUBIC";
- case D3DTEXF_GAUSSIANCUBIC : return "D3DTEXF_GAUSSIANCUBIC";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Address_Name(unsigned value)
- {
- switch (value) {
- case D3DTADDRESS_WRAP : return "D3DTADDRESS_WRAP";
- case D3DTADDRESS_MIRROR : return "D3DTADDRESS_MIRROR";
- case D3DTADDRESS_CLAMP : return "D3DTADDRESS_CLAMP";
- case D3DTADDRESS_BORDER : return "D3DTADDRESS_BORDER";
- case D3DTADDRESS_MIRRORONCE: return "D3DTADDRESS_MIRRORONCE";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Texture_Transform_Flag_Name(unsigned value)
- {
- switch (value) {
- case D3DTTFF_DISABLE : return "D3DTTFF_DISABLE";
- case D3DTTFF_COUNT1 : return "D3DTTFF_COUNT1";
- case D3DTTFF_COUNT2 : return "D3DTTFF_COUNT2";
- case D3DTTFF_COUNT3 : return "D3DTTFF_COUNT3";
- case D3DTTFF_COUNT4 : return "D3DTTFF_COUNT4";
- case D3DTTFF_PROJECTED : return "D3DTTFF_PROJECTED";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_ZBuffer_Type_Name(unsigned value)
- {
- switch (value) {
- case D3DZB_FALSE : return "D3DZB_FALSE";
- case D3DZB_TRUE : return "D3DZB_TRUE";
- case D3DZB_USEW : return "D3DZB_USEW";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Fill_Mode_Name(unsigned value)
- {
- switch (value) {
- case D3DFILL_POINT : return "D3DFILL_POINT";
- case D3DFILL_WIREFRAME : return "D3DFILL_WIREFRAME";
- case D3DFILL_SOLID : return "D3DFILL_SOLID";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Shade_Mode_Name(unsigned value)
- {
- switch (value) {
- case D3DSHADE_FLAT : return "D3DSHADE_FLAT";
- case D3DSHADE_GOURAUD : return "D3DSHADE_GOURAUD";
- case D3DSHADE_PHONG : return "D3DSHADE_PHONG";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Blend_Name(unsigned value)
- {
- switch (value) {
- case D3DBLEND_ZERO : return "D3DBLEND_ZERO";
- case D3DBLEND_ONE : return "D3DBLEND_ONE";
- case D3DBLEND_SRCCOLOR : return "D3DBLEND_SRCCOLOR";
- case D3DBLEND_INVSRCCOLOR : return "D3DBLEND_INVSRCCOLOR";
- case D3DBLEND_SRCALPHA : return "D3DBLEND_SRCALPHA";
- case D3DBLEND_INVSRCALPHA : return "D3DBLEND_INVSRCALPHA";
- case D3DBLEND_DESTALPHA : return "D3DBLEND_DESTALPHA";
- case D3DBLEND_INVDESTALPHA : return "D3DBLEND_INVDESTALPHA";
- case D3DBLEND_DESTCOLOR : return "D3DBLEND_DESTCOLOR";
- case D3DBLEND_INVDESTCOLOR : return "D3DBLEND_INVDESTCOLOR";
- case D3DBLEND_SRCALPHASAT : return "D3DBLEND_SRCALPHASAT";
- case D3DBLEND_BOTHSRCALPHA : return "D3DBLEND_BOTHSRCALPHA";
- case D3DBLEND_BOTHINVSRCALPHA : return "D3DBLEND_BOTHINVSRCALPHA";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Cull_Mode_Name(unsigned value)
- {
- switch (value) {
- case D3DCULL_NONE : return "D3DCULL_NONE";
- case D3DCULL_CW : return "D3DCULL_CW";
- case D3DCULL_CCW : return "D3DCULL_CCW";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Cmp_Func_Name(unsigned value)
- {
- switch (value) {
- case D3DCMP_NEVER : return "D3DCMP_NEVER";
- case D3DCMP_LESS : return "D3DCMP_LESS";
- case D3DCMP_EQUAL : return "D3DCMP_EQUAL";
- case D3DCMP_LESSEQUAL : return "D3DCMP_LESSEQUAL";
- case D3DCMP_GREATER : return "D3DCMP_GREATER";
- case D3DCMP_NOTEQUAL : return "D3DCMP_NOTEQUAL";
- case D3DCMP_GREATEREQUAL : return "D3DCMP_GREATEREQUAL";
- case D3DCMP_ALWAYS : return "D3DCMP_ALWAYS";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Fog_Mode_Name(unsigned value)
- {
- switch (value) {
- case D3DFOG_NONE : return "D3DFOG_NONE";
- case D3DFOG_EXP : return "D3DFOG_EXP";
- case D3DFOG_EXP2 : return "D3DFOG_EXP2";
- case D3DFOG_LINEAR : return "D3DFOG_LINEAR";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Stencil_Op_Name(unsigned value)
- {
- switch (value) {
- case D3DSTENCILOP_KEEP : return "D3DSTENCILOP_KEEP";
- case D3DSTENCILOP_ZERO : return "D3DSTENCILOP_ZERO";
- case D3DSTENCILOP_REPLACE : return "D3DSTENCILOP_REPLACE";
- case D3DSTENCILOP_INCRSAT : return "D3DSTENCILOP_INCRSAT";
- case D3DSTENCILOP_DECRSAT : return "D3DSTENCILOP_DECRSAT";
- case D3DSTENCILOP_INVERT : return "D3DSTENCILOP_INVERT";
- case D3DSTENCILOP_INCR : return "D3DSTENCILOP_INCR";
- case D3DSTENCILOP_DECR : return "D3DSTENCILOP_DECR";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Material_Source_Name(unsigned value)
- {
- switch (value) {
- case D3DMCS_MATERIAL : return "D3DMCS_MATERIAL";
- case D3DMCS_COLOR1 : return "D3DMCS_COLOR1";
- case D3DMCS_COLOR2 : return "D3DMCS_COLOR2";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Vertex_Blend_Flag_Name(unsigned value)
- {
- switch (value) {
- case D3DVBF_DISABLE : return "D3DVBF_DISABLE";
- case D3DVBF_1WEIGHTS : return "D3DVBF_1WEIGHTS";
- case D3DVBF_2WEIGHTS : return "D3DVBF_2WEIGHTS";
- case D3DVBF_3WEIGHTS : return "D3DVBF_3WEIGHTS";
- case D3DVBF_TWEENING : return "D3DVBF_TWEENING";
- case D3DVBF_0WEIGHTS : return "D3DVBF_0WEIGHTS";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Patch_Edge_Style_Name(unsigned value)
- {
- switch (value) {
- case D3DPATCHEDGE_DISCRETE : return "D3DPATCHEDGE_DISCRETE";
- case D3DPATCHEDGE_CONTINUOUS:return "D3DPATCHEDGE_CONTINUOUS";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Debug_Monitor_Token_Name(unsigned value)
- {
- switch (value) {
- case D3DDMT_ENABLE : return "D3DDMT_ENABLE";
- case D3DDMT_DISABLE : return "D3DDMT_DISABLE";
- default : return "UNKNOWN";
- }
- }
- const char* DX8Wrapper::Get_DX8_Blend_Op_Name(unsigned value)
- {
- switch (value) {
- case D3DBLENDOP_ADD : return "D3DBLENDOP_ADD";
- case D3DBLENDOP_SUBTRACT : return "D3DBLENDOP_SUBTRACT";
- case D3DBLENDOP_REVSUBTRACT: return "D3DBLENDOP_REVSUBTRACT";
- case D3DBLENDOP_MIN : return "D3DBLENDOP_MIN";
- case D3DBLENDOP_MAX : return "D3DBLENDOP_MAX";
- default : return "UNKNOWN";
- }
- }
|