| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915 |
- /*
- ** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: W3DShaderManager.cpp ////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- //
- // Westwood Studios Pacific.
- //
- // Confidential Information
- // Copyright (C) 2001 - All Rights Reserved
- //
- //-----------------------------------------------------------------------------
- //
- // Project: RTS3
- //
- // File name: W3DShaderManager.cpp
- //
- // Created: Mark Wilczynski, August 2001
- //
- // Desc: Perform tests on currently selected WW3D/D3D device to determine
- // which of our rendering features are supported. The system allows
- // setting up a few custom shaders that are selected based on video
- // card features.
- //
- // To add a new shader to the system:
- // 0) Add your shader to the ShaderTypes enum
- // 1) Create shader using W3DShaderInterface
- // 2) Repeat step 1 for any alternate shaders
- // 3) Create list of alternate shaders sorted by order of preference.
- // The first shader which passes hardware validation will be selected.
- // 4) Add list from step 3) to MasterShaderList[].
- //
- //-----------------------------------------------------------------------------
- #include "dx8wrapper.h"
- #include "assetmgr.h"
- #include "Lib/BaseType.h"
- #include "Common/File.h"
- #include "Common/FileSystem.h"
- #include "W3DDevice/GameClient/W3DShaderManager.h"
- #include "W3DDevice/GameClient/W3DShroud.h"
- #include "W3DDevice/GameClient/HeightMap.h"
- #include "W3DDevice/GameClient/W3DCustomScene.h"
- #include "GameClient/view.h"
- #include "GameClient/CommandXlat.h"
- #include "GameClient/display.h"
- #include "GameClient/Water.h"
- #include "GameLogic/GameLogic.h"
- #include "common/GlobalData.h"
- #include "common/GameLOD.h"
- #include "d3dx8tex.h"
- #include "dx8caps.h"
- #include "common/gamelod.h"
- #include "Benchmark.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- /** Interface definition for custom shaders we define in our app. These shaders can perform more complex
- operations than those allowed in the WW3D2 shader system.
- */
- class W3DShaderInterface
- {
- public:
- Int getNumPasses(void) {return m_numPasses;}; ///<return number of passes needed for this shader
- virtual Int set(Int pass) {return TRUE;}; ///<setup shader for the specified rendering pass.
- ///do any custom resetting necessary to bring W3D in sync.
- virtual void reset(void) {
- ShaderClass::Invalidate();
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);};
- virtual Int init(void) = 0; ///<perform any one time initialization and validation
- virtual Int shutdown(void) { return TRUE;}; ///<release resources used by shader
- protected:
- Int m_numPasses; ///<number of passes to complete shader
- };
- //this table will contain custom versions of each shader tuned for specific video card and user options.
- static W3DFilterInterface *W3DFilters[FT_MAX];
- static W3DShaderInterface *W3DShaders[W3DShaderManager::ST_MAX];
- static Int W3DShadersPassCount[W3DShaderManager::ST_MAX]; //number of passes for each of the above shaders
- TextureClass *W3DShaderManager::m_Textures[8];
- W3DShaderManager::ShaderTypes W3DShaderManager::m_currentShader;
- FilterTypes W3DShaderManager::m_currentFilter=FT_NULL_FILTER; ///< Last filter that was set.
- Int W3DShaderManager::m_currentShaderPass;
- Bool W3DShaderManager::m_renderingToTexture = false;
- IDirect3DSurface8 *W3DShaderManager::m_oldRenderSurface=NULL; ///<previous render target
- IDirect3DTexture8 *W3DShaderManager::m_renderTexture=NULL; ///<texture into which rendering will be redirected.
- IDirect3DSurface8 *W3DShaderManager::m_newRenderSurface=NULL; ///<new render target inside m_renderTexture
- IDirect3DSurface8 *W3DShaderManager::m_oldDepthSurface=NULL; ///<previous depth buffer surface
- /*===========================================================================================*/
- /*========= Screen Shaders =============================================================*/
- /*===========================================================================================*/
- /*========= ScreenBWFilter =============================================================*/
- ///converts viewport to black & white.
- Int ScreenBWFilter::m_fadeFrames;
- Int ScreenBWFilter::m_curFadeFrame;
- Real ScreenBWFilter::m_curFadeValue;
- Int ScreenBWFilter::m_fadeDirection;
- ScreenBWFilter screenBWFilter;
- ScreenBWFilterDOT3 screenBWFilterDOT3; //slower version for older cards without pixel shaders.
- ///List of different BW shader implementations in order of preference
- W3DFilterInterface *ScreenBWFilterList[]=
- {
- &screenBWFilter,
- &screenBWFilterDOT3, //slower version for older cards without pixel shaders.
- NULL
- };
- Int ScreenBWFilter::init(void)
- {
- Int res;
- HRESULT hr;
- m_dwBWPixelShader = NULL;
- m_curFadeFrame = 0;
- if (!W3DShaderManager::canRenderToTexture()) {
- // Have to be able to render to texture.
- return false;
- }
- if ((res=W3DShaderManager::getChipset()) != 0)
- {
- if (res >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- //this shader needs some assets that need to be loaded
- //shader decleration
- DWORD Declaration[]=
- {
- (D3DVSD_STREAM(0)),
- (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position
- (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse
- (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates
- (D3DVSD_END())
- };
- //Monochrome pixel shader.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\monochrome.pso", &Declaration[0], 0, false, &m_dwBWPixelShader);
- if (FAILED(hr))
- return FALSE;
- W3DFilters[FT_VIEW_BW_FILTER]=&screenBWFilter;
- return TRUE;
- }
- }
- return FALSE;
- }
- Bool ScreenBWFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- skipRender = false;
- W3DShaderManager::startRenderToTexture();
- return true;
- }
- Bool ScreenBWFilter::postRender(enum FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender)
- {
- IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture();
- DEBUG_ASSERTCRASH(tex, ("Require rendered texture."));
- if (!tex) return false;
- if (!set(mode)) return false;
- LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
- struct _TRANS_LIT_TEX_VERTEX {
- D3DXVECTOR4 p;
- DWORD color; // diffuse color
- float u;
- float v;
- } v[4];
- Int xpos, ypos, width, height;
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture
- TheTacticalView->getOrigin(&xpos,&ypos);
- width=TheTacticalView->getWidth();
- height=TheTacticalView->getHeight();
- //bottom right
- v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top right
- v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- //bottom left
- v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top left
- v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- v[0].color = 0xffffffff;
- v[1].color = 0xffffffff;
- v[2].color = 0xffffffff;
- v[3].color = 0xffffffff;
- //draw polygons like this is very inefficient but for only 2 triangles, it's
- //not worth bothering with index/vertex buffers.
- pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- reset();
- return true;
- }
- Int ScreenBWFilter::set(enum FilterModes mode)
- {
- HRESULT hr;
- if (mode > FM_NULL_MODE)
- { //rendering a quad with redirected rendering surface tinted by pixel shader
- if (m_fadeDirection > 0)
- { //turning effect on
- m_curFadeFrame++;
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = (Real)fade/(Real)m_fadeFrames;
- }
- else
- {
- m_curFadeFrame = 0;
- m_curFadeValue = 1.0f;
- m_fadeDirection = 0;
- }
- }
- else
- if (m_fadeDirection < 0)
- { //turning effect off
- m_curFadeFrame++;
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = 1.0f - (Real)fade/(Real)m_fadeFrames;
- }
- else
- { m_curFadeValue = 0.0f;
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- m_curFadeFrame = 0;
- m_fadeDirection = 0;
- }
- }
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader);
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- hr=DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBWPixelShader);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(0, D3DXVECTOR4(0.3f, 0.59f, 0.11f, 1.0f), 1);
- D3DXVECTOR4 color(1.0f,1.0f,1.0f,1.0f); //multiply color
- if (mode == FM_VIEW_BW_BLACK_AND_WHITE)
- { //back & white mode
- color.x=1.0f;
- color.y=1.0f;
- color.z=1.0f;
- }
- if (mode == FM_VIEW_BW_RED_AND_WHITE)
- { //red is on
- color.x = 1.0f;
- color.y = 0.0f;
- color.z = 0.0f;
- //inverse red is on
- //red is on
- // color.x = 0.0f;
- // color.y = 1.0f;
- // color.z = 1.0f;
- }
- if (mode == FM_VIEW_BW_GREEN_AND_WHITE)
- {
- color.x = 0.0f;
- color.y = 1.0f;
- color.z = 0.0f;
- }
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(1, color, 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(2, D3DXVECTOR4(m_curFadeValue, m_curFadeValue, m_curFadeValue, 1.0f), 1);
- /* DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(2, D3DXVECTOR4(150.0f/255.0f, 150.0f/255.0f, 150.0f/255.0f, 0.0f), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(3, D3DXVECTOR4((765.0f/450.0f)/3, (765.0f/450.0f)/3, (765.0f/450.0f)/3, 1.0f), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(4, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(5, D3DXVECTOR4((60.0f)/255.0f, (60.0f)/255.0f, (60.0f)/255.0f, 0), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(6, D3DXVECTOR4((157.0f)/255.0f, (157.0f)/255.0f, (157.0f)/255.0f, 0), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(7, D3DXVECTOR4((30.0f)/255.0f, (30.0f)/255.0f, (30.0f)/255.0f, 0), 1);
- */
- return true;
- }
- return false;
- }
- void ScreenBWFilter::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int ScreenBWFilter::shutdown(void)
- {
- if (m_dwBWPixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBWPixelShader);
- m_dwBWPixelShader=NULL;
- return TRUE;
- }
- /**Alternate version of the above filter which does not require pixel shaders - good for older cards*/
- Int ScreenBWFilterDOT3::init(void)
- {
- Int res;
- m_curFadeFrame = 0;
- if (!W3DShaderManager::canRenderToTexture()) {
- // Have to be able to render to texture.
- return false;
- }
- if ((res=W3DShaderManager::getChipset()) != 0)
- {
- W3DFilters[FT_VIEW_BW_FILTER]=&screenBWFilterDOT3;
- return TRUE;
- }
- return FALSE;
- }
- Bool ScreenBWFilterDOT3::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- skipRender = false;
- W3DShaderManager::startRenderToTexture();
- return true;
- }
- Bool ScreenBWFilterDOT3::postRender(enum FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender)
- {
- IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture();
- DEBUG_ASSERTCRASH(tex, ("Require rendered texture."));
- if (!tex) return false;
- if (!set(mode)) return false;
- LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
- struct _TRANS_LIT_TEX_VERTEX {
- D3DXVECTOR4 p;
- DWORD color; // diffuse color
- float u;
- float v;
- } v[4];
- Int xpos, ypos, width, height;
- TheTacticalView->getOrigin(&xpos,&ypos);
- width=TheTacticalView->getWidth();
- height=TheTacticalView->getHeight();
- //bottom right
- v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top right
- v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- //bottom left
- v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top left
- v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
-
- DWORD currentFade=(((Int)((1.0f-m_curFadeValue) * 255.0f))<<24) | 0x00ffffff; //store alpha value
- v[0].color = currentFade;
- v[1].color = currentFade;
- v[2].color = currentFade;
- v[3].color = currentFade;
- //draw polygons like this is very inefficient but for only 2 triangles, it's
- //not worth bothering with index/vertex buffers.
- pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
- //Draw B&W version first
- if (DX8Caps::Support_DOT3())
- { //Override W3D states with customizations for grayscale
- DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0x80A5CA8E);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG0, D3DTA_TFACTOR | D3DTA_ALPHAREPLICATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR | D3DTA_ALPHAREPLICATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
- }
- else
- { //doesn't have DOT3 blend mode so fake it another way.
- DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0x60606060);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- }
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- //Draw normal view blended by current fade level
- ShaderClass::Invalidate(); //reset DOT3 blend from above.
- ShaderClass shader=ShaderClass::_PresetAlphaShader;
- shader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS);
- DX8Wrapper::Set_Shader(shader);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- //replace texture alpha with vertex alpha
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- reset();
- return true;
- }
- Int ScreenBWFilterDOT3::set(enum FilterModes mode)
- {
- if (mode > FM_NULL_MODE)
- { //rendering a quad with redirected rendering surface tinted by pixel shader
- if (m_fadeDirection > 0)
- { //turning effect on
- m_curFadeFrame++;
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = (Real)fade/(Real)m_fadeFrames;
- }
- else
- {
- m_curFadeFrame = 0;
- m_curFadeValue = 1.0f;
- m_fadeDirection = 0;
- }
- }
- else
- if (m_fadeDirection < 0)
- { //turning effect off
- m_curFadeFrame++;
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = 1.0f - (Real)fade/(Real)m_fadeFrames;
- }
- else
- { m_curFadeValue = 0.0f;
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- m_curFadeFrame = 0;
- m_fadeDirection = 0;
- }
- }
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader);
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- return true;
- }
- return false;
- }
- void ScreenBWFilterDOT3::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int ScreenBWFilterDOT3::shutdown(void)
- {
- return TRUE;
- }
- /*========= ScreenCrossFadeFilter =============================================================*/
- ///Fades screen between 2 different views of the scene with both being visible at once.
- Int ScreenCrossFadeFilter::m_fadeFrames;
- Int ScreenCrossFadeFilter::m_curFadeFrame;
- Real ScreenCrossFadeFilter::m_curFadeValue;
- Int ScreenCrossFadeFilter::m_fadeDirection;
- TextureClass *ScreenCrossFadeFilter::m_fadePatternTexture=NULL;
- Bool ScreenCrossFadeFilter::m_skipRender = FALSE;
- ScreenCrossFadeFilter screenCrossFadeFilter;
- ///List of different BW shader implementations in order of preference
- ///@todo: Add a version that doesn't require pixel shader
- W3DFilterInterface *ScreenCrossFadeFilterList[]=
- {
- &screenCrossFadeFilter,
- NULL
- };
- Int ScreenCrossFadeFilter::init(void)
- {
- if (!TheDisplay)
- return FALSE; //effect is useless without a view so no point initializing for the WB, etc.
- m_curFadeFrame = 0;
- if (!W3DShaderManager::canRenderToTexture())
- // Have to be able to render to texture.
- return FALSE;
- //Load an alpha mask texture that will mix foreground/background views.
- m_fadePatternTexture=WW3DAssetManager::Get_Instance()->Get_Texture("exmask_g.tga");
- if (!m_fadePatternTexture)
- return FALSE;
- m_fadePatternTexture->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
- m_fadePatternTexture->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
- m_fadePatternTexture->Set_Mip_Mapping(TextureClass::FILTER_TYPE_NONE);
- W3DFilters[FT_VIEW_CROSSFADE]=&screenCrossFadeFilter;
- return TRUE;
- }
- Bool ScreenCrossFadeFilter::updateFadeLevel(void)
- {
- if (m_fadeDirection > 0)
- { //turning effect on
- m_curFadeFrame++;
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = (Real)fade/(Real)m_fadeFrames;
- }
- else
- {
- m_curFadeFrame = 0;
- m_curFadeValue = 1.0f;
- m_fadeDirection = 0;
- return false;
- }
- }
- else
- if (m_fadeDirection < 0)
- { //turning effect off
- Int fade = m_curFadeFrame;
- if (fade<m_fadeFrames)
- {
- m_curFadeValue = 1.0f - (Real)fade/(Real)m_fadeFrames;
- m_curFadeFrame++;
- }
- else
- { m_curFadeValue = 0.0f;
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- m_curFadeFrame = 0;
- m_fadeDirection = 0;
- return false;
- }
- }
- return true;
- }
- Bool ScreenCrossFadeFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- if (updateFadeLevel())
- { //if fade has not completed
- W3DShaderManager::startRenderToTexture();
- scenePassMode=SCENE_PASS_ALPHA_MASK;
- skipRender = false;
- m_skipRender=true; //tell the postRender function not to draw into framebuffer yet.
- return true;
- }
- //fade must have completed
- return true;
- }
- Bool ScreenCrossFadeFilter::postRender(enum FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender)
- {
- IDirect3DTexture8 * tex;
- if (m_skipRender)
- {
- //don't render anything to frame buffer because we still need to draw the new scene
- //that we're fading into. Okay to render on the next call.
- m_skipRender = false;
- doExtraRender = TRUE;
- tex = W3DShaderManager::endRenderToTexture();
- return true;
- }
- tex=W3DShaderManager::getRenderTexture();
- DEBUG_ASSERTCRASH(tex, ("Require last rendered texture."));
- if (!tex) return false;
- if (!set(mode)) return false;
- LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
- struct _TRANS_LIT_TEX_VERTEX {
- D3DXVECTOR4 p;
- DWORD color; // diffuse color
- float u;
- float v;
- float u1;
- float v1;
- } v[4];
- Int xpos, ypos, width, height;
- Real radius = 0.0f;
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture
- if (mode == FM_VIEW_CROSSFADE_CIRCLE)
- { DX8Wrapper::_Get_D3D_Device8()->SetTexture(1,m_fadePatternTexture->Peek_DX8_Texture());
- //Use the current fade level to scale the mask texture, for other modes the texture
- //comes pre-scaled so doesn't require uv scaling.
- radius = (1.0f-m_curFadeValue)*2.0f;
- if (radius <= 0)
- radius = 0.01f;
- radius = 0.5f/radius;
- }
- TheTacticalView->getOrigin(&xpos,&ypos);
- width=TheTacticalView->getWidth();
- height=TheTacticalView->getHeight();
- /* Real radius = (1.0f-m_curFadeValue);
- if (radius <= 0)
- radius = 0.01f;
- radius = 25.0f-radius*24.75f;
- */
- //bottom right
- v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- v[0].u1 = 0.5f+radius; v[0].v1 = 0.5f+radius;
- //top right
- v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- v[1].u1 = 0.5f+radius; v[1].v1 = 0.5f-radius;
- //bottom left
- v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- v[2].u1 = 0.5f-radius; v[2].v1 = 0.5f+radius;
- //top left
- v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- v[3].u1 = 0.5f-radius; v[3].v1 = 0.5f-radius;
- DWORD diffuse = 0xffffffff;//((Int)((m_curFadeValue) * 255.0f) << 24) | 0x00ffffff; //store alpha value in vertex diffuse
- v[0].color = diffuse;
- v[1].color = diffuse;
- v[2].color = diffuse;
- v[3].color = diffuse;
- //draw polygons like this is very inefficient but for only 2 triangles, it's
- //not worth bothering with index/vertex buffers.
- pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2);
- // m_pDev->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
- // m_pDev->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- reset();
- return true;
- }
- Int ScreenCrossFadeFilter::set(enum FilterModes mode)
- {
- if (mode > FM_NULL_MODE)
- { //rendering a quad with redirected rendering surface
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaShader);
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_Texture(1,NULL);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- if (mode == FM_VIEW_CROSSFADE_CIRCLE)
- { //cross-fading using circle mask stored in stage 1
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE);
- }
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- return true;
- }
- return false;
- }
- void ScreenCrossFadeFilter::reset(void)
- {
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int ScreenCrossFadeFilter::shutdown(void)
- {
- REF_PTR_RELEASE(m_fadePatternTexture);
- return TRUE;
- }
- /*========= ScreenMotionBlurFilter =============================================================*/
- ///applies motion blur to viewport.
- ScreenMotionBlurFilter screenMotionBlurFilter;
- Coord3D ScreenMotionBlurFilter::m_zoomToPos;
- Bool ScreenMotionBlurFilter::m_zoomToValid = false;
- ScreenMotionBlurFilter::ScreenMotionBlurFilter():
- m_decrement(false),
- m_maxCount(0),
- m_lastFrame(0),
- m_skipRender(false)
- {
- }
- ///List of different motion blur implementations in order of preference
- W3DFilterInterface *ScreenMotionBlurFilterList[]=
- {
- &screenMotionBlurFilter,
- NULL
- };
- Int ScreenMotionBlurFilter::init(void)
- {
- if (!W3DShaderManager::canRenderToTexture()) {
- // Have to be able to render to texture.
- return false;
- }
- W3DFilters[FT_VIEW_MOTION_BLUR_FILTER]=this;
- return true;
- }
- Bool ScreenMotionBlurFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- skipRender = m_skipRender;
- W3DShaderManager::startRenderToTexture();
- return true;
- }
- Bool ScreenMotionBlurFilter::postRender(enum FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender)
- {
- IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture();
- DEBUG_ASSERTCRASH(tex, ("Require rendered texture."));
- if (!tex) return false;
- if (!set(mode)) return false;
- LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
- Bool continueEffect = true;
- struct _TRANS_LIT_TEX_VERTEX {
- D3DXVECTOR4 p;
- DWORD color; // diffuse color
- float u;
- float v;
- } v[4];
- Int xpos, ypos, width, height;
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture
- TheTacticalView->getOrigin(&xpos,&ypos);
- width=TheTacticalView->getWidth();
- height=TheTacticalView->getHeight();
- //bottom right
- v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top right
- v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- //bottom left
- v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top left
- v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- v[0].color = 0xffffffff;
- v[1].color = 0xffffffff;
- v[2].color = 0xffffffff;
- v[3].color = 0xffffffff;
- if (m_additive) {
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ONE);
- } else {
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
- }
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false);
- //draw polygons like this is very inefficient but for only 2 triangles, it's
- //not worth bothering with index/vertex buffers.
- DX8Wrapper::Apply_Render_State_Changes();
- pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
- Coord2D center;
- center.x = 0.5f;
- center.y = 0.5f;
- Bool pan = false;
- if (mode>=FM_VIEW_MB_PAN_ALPHA) {
- Real len = sqrt(scrollDelta.x*scrollDelta.x + scrollDelta.y*scrollDelta.y);
- //center.x += 0.5f * (scrollDelta.x/len);
- center.y -= 0.5f; // * (scrollDelta.y/len);
- m_decrement = false;
- m_maxCount = (len*200*m_panFactor/(Real)DEFAULT_PAN_FACTOR);
- if (m_maxCount<m_panFactor/2)
- m_maxCount = m_panFactor/2;
- if (m_maxCount>m_panFactor)
- m_maxCount=m_panFactor;
- pan = true;
- m_priorDelta = scrollDelta;
- } else if (mode == FM_VIEW_MB_END_PAN_ALPHA) {
- Real len = sqrt(m_priorDelta.x*m_priorDelta.x + m_priorDelta.y*m_priorDelta.y);
- center.x += 0.5f * (m_priorDelta.x/len);
- center.y -= 0.5f * (m_priorDelta.y/len);
- m_decrement = false;
- m_maxCount--;
- if (m_maxCount<2) {
- continueEffect = false;
- }
- pan = true;
- }
- m_skipRender = false;
- if (!pan && m_lastFrame != TheGameLogic->getFrame()) {
- if (m_decrement) {
- m_maxCount-=COUNT_STEP;
- if (m_maxCount<1) {
- m_decrement = false;
- continueEffect = false;
- } else {
- m_skipRender = true;
- }
- } else {
- m_maxCount+=COUNT_STEP;
- if (m_maxCount>=MAX_COUNT) {
- m_decrement = true;
- if (m_doZoomTo && m_zoomToValid) {
- TheTacticalView->lookAt(&m_zoomToPos);
- } else {
- continueEffect = false;
- }
- } else {
- m_skipRender = true;
- }
- }
- }
- Int i, j;
- if (!pan) {
- for (i=0; i<4; i++) {
- Real factor = 1.0f - (m_maxCount/(Real)MAX_COUNT)*0.90f;
- factor = sqrt(factor);
- v[i].u = ((v[i].u-center.x)*factor) + center.x;
- v[i].v = ((v[i].v-center.y)*factor) + center.y;
- }
- }
- pDev->SetTextureStageState(0,D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- pDev->SetTextureStageState(0,D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
- pDev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
- DX8Wrapper::Apply_Render_State_Changes();
- {
- Int limit = m_maxCount;
- if (m_maxCount>30) limit = 30;
- for (j=0; j<limit; j++) {
- for (i=0; i<4; i++) {
- Real factor = 0.99f;
- if (m_additive) factor = 0.98f;
- Int alpha = 0x15;
- if (m_additive) {
- alpha = 0x09;
- if (m_maxCount>limit) {
- alpha += (m_maxCount-limit)/5;
- }
- if (m_maxCount==MAX_COUNT) alpha += 60;
- }
- v[i].color = (alpha<<24)|0x00ffffff; //
- if (pan) {
- v[i].u = ((v[i].u-center.x)*(factor+.006)) + center.x;
- v[i].v = ((v[i].v-center.y)*factor) + center.y;
- } else {
- v[i].u = ((v[i].u-center.x)*factor) + center.x;
- v[i].v = ((v[i].v-center.y)*factor) + center.y;
- }
- }
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- }
- }
- m_lastFrame = TheGameLogic->getFrame();
- if (pan){
- m_skipRender = false;
- }
- reset();
- if (!continueEffect) {
- m_zoomToValid = false;
- }
- return continueEffect;
- }
- Bool ScreenMotionBlurFilter::setup(enum FilterModes mode)
- {
- m_additive = false;
- if (mode == FM_VIEW_MB_IN_AND_OUT_SATURATE ||
- mode == FM_VIEW_MB_IN_SATURATE ||
- mode == FM_VIEW_MB_OUT_SATURATE) {
- m_additive = true;
- }
- m_doZoomTo = false;
- if (mode == FM_VIEW_MB_IN_AND_OUT_SATURATE ||
- mode == FM_VIEW_MB_IN_AND_OUT_ALPHA ) {
- m_doZoomTo = true;
- }
- if (mode >= FM_VIEW_MB_PAN_ALPHA) {
- m_panFactor = (int)mode - FM_VIEW_MB_PAN_ALPHA;
- if (m_panFactor<1) m_panFactor = DEFAULT_PAN_FACTOR;
- }
- m_skipRender = false;
- if (mode != FM_VIEW_MB_END_PAN_ALPHA)
- m_maxCount = 0;
- m_decrement = false;
- m_skipRender = false;
- switch (mode) {
- case FM_VIEW_MB_OUT_SATURATE:
- case FM_VIEW_MB_OUT_ALPHA:
- m_maxCount = MAX_COUNT;
- m_decrement = TRUE;
- break;
- }
- return true;
- }
- Int ScreenMotionBlurFilter::set(enum FilterModes mode)
- {
- if (mode > FM_NULL_MODE)
- { //rendering a quad with redirected rendering surface motion blurred
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader);
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_Texture(1,NULL);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- }
- return TRUE;
- }
- void ScreenMotionBlurFilter::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int ScreenMotionBlurFilter::shutdown(void)
- {
- return TRUE;
- }
- /*===========================================================================================*/
- /*========= Shroud Shaders =============================================================*/
- /*===========================================================================================*/
- ///Shroud layer rendering shader
- class ShroudTextureShader : public W3DShaderInterface
- {
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- Int m_stageOfSet;
- } shroudTextureShader;
- ///List of different shroud shader implementations in order of preference
- W3DShaderInterface *ShroudShaderList[]=
- {
- &shroudTextureShader,
- NULL
- };
- //#define SHROUD_STRETCH_FACTOR (1.0f/MAP_XY_FACTOR) //1 texel per heightmap cell width
- Int ShroudTextureShader::init(void)
- {
- W3DShaders[W3DShaderManager::ST_SHROUD_TEXTURE]=&shroudTextureShader;
- W3DShadersPassCount[W3DShaderManager::ST_SHROUD_TEXTURE]=1;
- return TRUE;
- }
- //Setup a texture projection in the given stage that applies our shroud.
- Int ShroudTextureShader::set(Int stage)
- {
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- if (stage < 2)
- DX8Wrapper::Set_Texture(stage, W3DShaderManager::getShaderTexture(0));
- else //stages larger than 1 are not supported by W3D so set them directly
- DX8Wrapper::Set_DX8_Texture(stage, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- if (stage == 0)
- {
- #if defined(_DEBUG) || defined(_INTERNAL)
- if (TheGlobalData && TheGlobalData->m_fogOfWarOn)
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaSpriteShader);
- else
- DX8Wrapper::Set_Shader(ShaderClass::_PresetMultiplicativeSpriteShader);
- #else
- DX8Wrapper::Set_Shader(ShaderClass::_PresetMultiplicativeSpriteShader);
- #endif
- }
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_EQUAL);
- //We need to scale so shroud texel stretches over one full terrain cell. Each texel
- //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture).
- W3DShroud *shroud;
- if ((shroud=TheTerrainRenderObject->getShroud()) != 0)
- { ///@todo: All this code really only need to be done once per camera/view. Find a way to optimize it out.
- D3DXMATRIX inv;
- float det;
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- D3DXMATRIX scale,offset;
- //We need to make all world coordinates be relative to the heightmap data origin since that
- //is where the shroud begins.
- float xoffset = 0;
- float yoffset = 0;
- Real width=shroud->getCellWidth();
- Real height=shroud->getCellHeight();
- if (TheTerrainRenderObject->getMap())
- { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels.
- xoffset = -(float)shroud->getDrawOriginX() + width;
- yoffset = -(float)shroud->getDrawOriginY() + height;
- }
- D3DXMatrixTranslation(&offset, xoffset, yoffset,0);
- width = 1.0f/(width*shroud->getTextureWidth());
- height = 1.0f/(height*shroud->getTextureHeight());
- D3DXMatrixScaling(&scale, width, height, 1);
- *((D3DXMATRIX *)&curView) = (inv * offset) * scale;
- DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4*)&curView));
- }
- m_stageOfSet=stage;
- return TRUE;
- }
- void ShroudTextureShader::reset(void)
- {
- if (m_stageOfSet < MAX_TEXTURE_STAGES)
- DX8Wrapper::Set_Texture(m_stageOfSet,NULL);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
- DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXCOORDINDEX, m_stageOfSet);
- DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- }
- ///Mask layer rendering shader
- class MaskTextureShader : public W3DShaderInterface
- {
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- } maskTextureShader;
- ///List of different shroud shader implementations in order of preference
- W3DShaderInterface *MaskShaderList[]=
- {
- &maskTextureShader,
- NULL
- };
- Int MaskTextureShader::init(void)
- {
- W3DShaders[W3DShaderManager::ST_MASK_TEXTURE]=&maskTextureShader;
- W3DShadersPassCount[W3DShaderManager::ST_MASK_TEXTURE]=1;
- return TRUE;
- }
- Int MaskTextureShader::set(Int pass)
- {
- Real fadeLevel=ScreenCrossFadeFilter::getCurrentFadeValue();
- //Use the current fade level to scale the mask texture
- Real radius = (1.0f-fadeLevel)*2.0f;
- if (radius <= 0)
- radius = 0.01f;
- radius = 0.5f/radius;
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
- //For now we're always going to project the texture coming from the crossfade effect
- DX8Wrapper::Set_Texture(0, ScreenCrossFadeFilter::getCurrentMaskTexture());
- ShaderClass shader=ShaderClass::_PresetOpaqueShader;
- shader.Set_Primary_Gradient(ShaderClass::GRADIENT_DISABLE);
- DX8Wrapper::Set_Shader(shader);
- DX8Wrapper::Apply_Render_State_Changes();
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- D3DXMATRIX inv;
- float det;
- //Get inverse view matrix so we can transform camera space points back to world space
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- D3DXMATRIX scale,offset,offsetTextureCenter;
- Coord3D centerPos;
- //Find center of projection (this should be returned from some other filter, etc. but
- //for now assume terrain location at center of screen.
- if (TheTacticalView)
- { Int xpos,ypos;
- TheTacticalView->getOrigin(&xpos,&ypos);
- ICoord2D screenPos;
- screenPos.x=(Real)TheTacticalView->getWidth()*0.5f;
- screenPos.y=(Real)TheTacticalView->getHeight()*0.5f;
- TheTacticalView->screenToTerrain(&screenPos,¢erPos);
- }
- D3DXMatrixTranslation(&offset, -centerPos.x, -centerPos.y,0);
- D3DXMatrixTranslation(&offsetTextureCenter, 0.5f, 0.5f, 0); //shift coordinates so center of projection falls at uv 0.5,0.5
- Real worldTexelWidth=(1.0f-fadeLevel)*25.0f; //9 worked well for circle but weird shape requires more stretch to cover.
- Real worldTexelHeight=(1.0f-fadeLevel)*25.0f;
- ///@todo: Fix this to work with non 128x128 textures.
- if (worldTexelWidth != 0 && worldTexelHeight != 0)
- { Real widthScale = 1.0f/(worldTexelWidth*128.0f);
- Real heightScale = 1.0f/(worldTexelHeight*128.0f);
- D3DXMatrixScaling(&scale, widthScale, heightScale, 1);
- *((D3DXMATRIX *)&curView) = ((inv * offset) * scale)*offsetTextureCenter;
- }
- else
- { D3DXMatrixScaling(&scale, 0, 0, 1); //scaling by 0 will set uv coordinates to 0,0
- *((D3DXMATRIX *)&curView) = ((inv * offset) * scale);
- }
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4*)&curView));
- return TRUE;
- }
- void MaskTextureShader::reset(void)
- {
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, 0);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- }
- /*===========================================================================================*/
- /*========= Terrain Shaders =========================================================*/
- /*===========================================================================================*/
- ///regular terrain shader that should work on all multi-texture video cards (slowest version)
- class TerrainShader2Stage : public W3DShaderInterface
- {
- public:
- float m_xSlidePerSecond ; ///< How far the clouds move per second.
- float m_ySlidePerSecond ; ///< How far the clouds move per second.
- int m_curTick;
- float m_xOffset;
- float m_yOffset;
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- void updateNoise1 (D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate=true); ///<generate the uv coordinates for Noise1 (i.e clouds)
- void updateNoise2 (D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate=true); ///<generate the uv coordinates for Noise2 (i.e lightmap)
- } terrainShader2Stage;
- ///8 stage terrain shader which only works on certain Nvidia cards.
- class TerrainShader8Stage : public W3DShaderInterface
- {
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- virtual Int init(void); ///<perform any one time initialization and validation
- } terrainShader8Stage;
- //Offsets into constant register pool used by vertex shader
- #define CV_WORLDVIEWPROJ_0 0 //4 vectors for transform of world->clip space.
- ///Pixel shader based terrain shader - fastest method for the newest cards.
- class TerrainShaderPixelShader : public W3DShaderInterface
- {
- DWORD m_dwBasePixelShader; ///<handle to terrain D3D pixel shader
- DWORD m_dwBaseNoise1PixelShader; ///<handle to terrain/single noise D3D pixel shader
- DWORD m_dwBaseNoise2PixelShader; ///<handle to terrain/double noise D3D pixel shader
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual Int shutdown(void); ///<release resources used by shader
- } terrainShaderPixelShader;
- ///List of different terrain shader implementations in order of preference
- W3DShaderInterface *TerrainShaderList[]=
- {
- &terrainShaderPixelShader,
- &terrainShader8Stage,
- &terrainShader2Stage,
- NULL
- };
- Int TerrainShader2Stage::init( void )
- {
- //initialize settings for uv animated clouds
- m_xSlidePerSecond = -0.02f;
- m_ySlidePerSecond = 1.50f * m_xSlidePerSecond;
- m_curTick = 0;
- m_curTick = WW3D::Get_Sync_Time();//::GetTickCount();
- m_xOffset = 0;
- m_yOffset = 0;
- //no special device validation needed - anything in our min spec should handle this.
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE]=&terrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE]=2;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=&terrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=3;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=&terrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=3;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=&terrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=3;
- return TRUE;
- }
- void TerrainShader2Stage::reset(void)
- {
- ShaderClass::Invalidate();
- //Free references to textures
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1);
- }
- void TerrainShader2Stage::updateNoise1(D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate)
- {
- #define STRETCH_FACTOR ((float)(1/(63.0*MAP_XY_FACTOR/2))) /* covers 63/2 tiles */
- D3DXMATRIX scale;
- D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
- *destMatrix = *curViewInverse * scale;
- D3DXMATRIX offset;
- Int delta = m_curTick;
- m_curTick = WW3D::Get_Sync_Time();//::GetTickCount();
- delta = m_curTick-delta;
- m_xOffset += m_xSlidePerSecond*delta/1000;
- m_yOffset += m_ySlidePerSecond*delta/1000;
- //m_xOffset += m_xSlidePerSecond*delta/500;
- //m_yOffset += m_ySlidePerSecond*delta/500;
- //m_yOffset = sinf( (float)m_curTick * 0.0001f );
- //m_xOffset = cosf( (float)m_curTick * 0.0001f );
- if (m_xOffset > 1) m_xOffset -= 1;
- if (m_yOffset > 1) m_yOffset -= 1;
- if (m_xOffset < -1) m_xOffset += 1;
- if (m_yOffset < -1) m_yOffset += 1;
- D3DXMatrixTranslation(&offset, m_xOffset, m_yOffset,0);
- *destMatrix *= offset;
- }
- void TerrainShader2Stage::updateNoise2(D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate)
- {
-
- D3DXMATRIX scale;
- D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
- *destMatrix = *curViewInverse * scale;
- }
- Int TerrainShader2Stage::set(Int pass)
- {
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- DX8Wrapper::Apply_Render_State_Changes();
- if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- }
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- }
- switch (pass)
- {
- case 0:
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- // Modulate the diffuse color with the texture as lighting comes from diffuse.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false);
- break;
- case 1:
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- // Modulate the diffuse color with the texture as lighting comes from diffuse.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 );
- // Blend the result using the alpha. (came from diffuse mod texture)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
- // Disable stage 2.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- break;
- case 2:
- // Noise/cloud pass
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- //these states apply to all noise/cloud combination passes
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- //blend into frame buffer
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO);
-
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE12)
- {
- //setup cloud pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView);
- //clouds always need bilinear filtering
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- //setup noise pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(3)->Peek_DX8_Texture());
- updateNoise2(((D3DXMATRIX*)&curView),&inv);
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView);
- //noise always needs point/linear filtering. Why point!?
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- } //ST_TERRAIN_BASE_NOISE12
- else
- { //only 1 noise or cloud texture
- // Now setup the texture pipeline.
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE1)
- { //setup cloud pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- else
- {
- //setup noise pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(3)->Peek_DX8_Texture());
- updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4*)&curView));
- }
- break;
- }
- return TRUE;
- }
- Int TerrainShader8Stage::init( void )
- {
- ChipsetType res;
- //this shader will also use the 2Stage shader for some of the passes so initialize it too.
- if (terrainShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_TNT && res <= DC_GEFORCE2)
- {
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE]=&terrainShader8Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE]=1;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=&terrainShader8Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=2;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=&terrainShader8Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=2;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=&terrainShader8Stage;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=2;
- return TRUE;
- }
- return FALSE;
- }
- Int TerrainShader8Stage::set(Int pass)
- {
- if (pass == 0)
- {
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- }
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- }
-
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_ADD);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_ADD);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture(2, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, 2);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG2, D3DTA_TEXTURE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture(3, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, 3);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE | 0 | D3DTA_ALPHAREPLICATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture(4, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_TEXCOORDINDEX, 4);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG1, D3DTA_CURRENT);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture(5, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLOROP, D3DTOP_ADD);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_TEXCOORDINDEX, 5);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAOP, D3DTOP_ADD);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture(6, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLOROP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_TEXCOORDINDEX, 6);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture(7, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_TEXCOORDINDEX, 7);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG2, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
- }
- else
- { //setup cloud noise/pass
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- DX8Wrapper::Invalidate_Cached_Render_States();
- terrainShader2Stage.set(2);
- }
- return TRUE;
- }
- void TerrainShader8Stage::reset(void)
- {
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int TerrainShaderPixelShader::shutdown(void)
- {
- if (m_dwBasePixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBasePixelShader);
- if (m_dwBaseNoise1PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise1PixelShader);
- if (m_dwBaseNoise2PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader);
- m_dwBasePixelShader=NULL;
- m_dwBaseNoise1PixelShader=NULL;
- m_dwBaseNoise2PixelShader=NULL;
- return TRUE;
- }
- Int TerrainShaderPixelShader::init( void )
- {
- Int res;
- //this shader will also use the 2Stage shader for some of the passes so initialize it too.
- if (terrainShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- if (res >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- //this shader needs some assets that need to be loaded
- //shader decleration
- DWORD Declaration[]=
- {
- (D3DVSD_STREAM(0)),
- (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position
- (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse
- (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates
- (D3DVSD_REG(3, D3DVSDT_FLOAT2)), // Texture Coordinates
- (D3DVSD_END())
- };
- //base version which doesn't apply any noise textures.
- HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrain.pso", &Declaration[0], 0, false, &m_dwBasePixelShader);
- if (FAILED(hr))
- return FALSE;
- //version which blends 1 noise texture.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrainnoise.pso", &Declaration[0], 0, false, &m_dwBaseNoise1PixelShader);
- if (FAILED(hr))
- return FALSE;
- //version which blends 2 noise textures.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrainnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader);
- if (FAILED(hr))
- return FALSE;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE]=&terrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=&terrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=&terrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=&terrainShaderPixelShader;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE]=1;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=1;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=1;
- W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=1;
- return TRUE;
- }
- }
- return FALSE;
- }
- Int TerrainShaderPixelShader::set(Int pass)
- {
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- DX8Wrapper::Apply_Render_State_Changes();
- //setup base pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- //tell pixel shader which UV set to use for each stage
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 );
- if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- }
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- }
- if (W3DShaderManager::getCurrentShader() >= W3DShaderManager::ST_TERRAIN_BASE_NOISE1)
- {
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
-
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE12)
- { //full shader
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3, W3DShaderManager::getShaderTexture(3)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView);
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE3, curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- }
- else
- { //single noise texture shader
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise1PixelShader);
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE1)
- { //cloud map
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- else
- { //light map
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(3)->Peek_DX8_Texture());
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView);
- }
- }
- else
- { //just base texturing
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBasePixelShader);
- }
- return TRUE;
- }
- void TerrainShaderPixelShader::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3);
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- ///Cloud layer rendering shader - used for objects similar to terrain which only need the cloud layer.
- class CloudTextureShader : public W3DShaderInterface
- {
- virtual Int set(Int stage); ///<setup shader for the specified rendering pass.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- Int m_stageOfSet;
- } cloudTextureShader;
- ///List of different cloud shader implementations in order of preference
- W3DShaderInterface *CloudShaderList[]=
- {
- &cloudTextureShader,
- NULL
- };
- Int CloudTextureShader::init(void)
- {
- W3DShaders[W3DShaderManager::ST_CLOUD_TEXTURE]=&cloudTextureShader;
- W3DShadersPassCount[W3DShaderManager::ST_CLOUD_TEXTURE]=1;
- return TRUE;
- }
- /**Setup a certain texture stage to project our cloud texture*/
- Int CloudTextureShader::set(Int stage)
- {
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- //Get a texture matrix that applies the current cloud position
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv,false); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(stage, W3DShaderManager::getShaderTexture(stage)->Peek_DX8_Texture());
- m_stageOfSet=stage;
- return TRUE;
- }
- void CloudTextureShader::reset(void)
- {
- //Free reference to texture
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(m_stageOfSet, NULL);
- //Turn off texture projection
- DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|m_stageOfSet);
- DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- }
- /*===========================================================================================*/
- /*========= Road Shaders =========================================================*/
- /*===========================================================================================*/
- class RoadShaderPixelShader : public W3DShaderInterface
- {
- DWORD m_dwBaseNoise2PixelShader; ///<handle to road/double noise D3D pixel shader
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual Int shutdown(void); ///<release resources used by shader
- } roadShaderPixelShader;
- class RoadShader2Stage : public W3DShaderInterface
- { friend class RoadShaderPixelShader; //pixel shader version uses some of the same features.
- virtual Int set(Int pass); ///<setup shader for the specified rendering pass.
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual void reset(void);
- } roadShader2Stage;
- ///List of different terrain shader implementations in order of preference
- W3DShaderInterface *RoadShaderList[]=
- {
- &roadShaderPixelShader,
- &roadShader2Stage,
- NULL
- };
- Int RoadShaderPixelShader::shutdown(void)
- {
- if (m_dwBaseNoise2PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader);
- m_dwBaseNoise2PixelShader=NULL;
- return TRUE;
- }
- Int RoadShaderPixelShader::init( void )
- {
- Int res;
- //this shader will also use the 2Stage shader for some of the passes so initialize it too.
- if (roadShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- if (res >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- //this shader needs some assets that need to be loaded
- //shader decleration
- DWORD Declaration[]=
- {
- (D3DVSD_STREAM(0)),
- (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position
- (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse
- (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates
- (D3DVSD_END())
- };
- //version which blends 2 noise textures.
- HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\roadnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader);
- if (FAILED(hr))
- return FALSE;
- //Only set this shader for use in dual noise mode. The 2Stage shader will take care of
- //all the other modes.
- W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE12]=&roadShaderPixelShader;
- W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE12]=1;
- return TRUE;
- }
- }
- return FALSE;
- }
- Int RoadShaderPixelShader::set(Int pass)
- {
- //after we're done with this shader we're going to reset to NULL texture, so set W3D same way.
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_Texture(1,NULL);
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- DX8Wrapper::Apply_Render_State_Changes();
- //Directly set texture without W3D knowing... but we'll restore to NULL later.
- if (W3DShaderManager::getShaderTexture(0))
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- //tell pixel shader which UV set to use for each stage
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_LIGHTING, FALSE);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); //blend roads into terrain
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex)
- { DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- }
- else
- { DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- }
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
-
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView);
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- return TRUE;
- }
- void RoadShaderPixelShader::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3);
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- Int RoadShader2Stage::init( void )
- {
- //no special device validation needed - anything in our min spec should handle this.
- W3DShaders[W3DShaderManager::ST_ROAD_BASE]=&roadShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE]=1;
- W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE1]=&roadShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE1]=1;
- W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE2]=&roadShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE2]=1;
- W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE12]=&roadShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE12]=2;
- return TRUE;
- }
- Int RoadShader2Stage::set(Int pass)
- {
- //after we're done with this shader we're going to reset to NULL texture, so set W3D same way.
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_Texture(1,NULL);
- //Force system to apply world/view transforms.
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_LIGHTING, FALSE);
- //first texture unit will always contain base road texture
- if (W3DShaderManager::getShaderTexture(0))
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_DX8_Texture());
- // Modulate the diffuse color with the texture as lighting comes from diffuse.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); //blend roads into terrain
- if (pass == 0)
- {
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
- if (W3DShaderManager::getCurrentShader() >= W3DShaderManager::ST_ROAD_BASE_NOISE1)
- { //second texture unit will contain a noise pass
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex)
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- else
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE12)
- { //full shader, apply noise 1 in pass 0.
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView);
- }
- else
- { //single noise texture shader
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE1)
- { //cloud map
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_DX8_Texture());
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- else
- { //light map
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- }
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView);
- }
- }
- else
- { //just base texturing
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- }
- } //pass 0
- else
- { //pass 1, apply additional noise pass
- Matrix4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex)
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- else
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(2)->Peek_DX8_Texture());
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- //Copy alpha channel into stage 1 but mask out color channel by replacing with white.
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- //Force color channel to white by copying the alpha into RGB
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE|D3DTA_ALPHAREPLICATE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- //Modulate into existing roads with clouds applied. - only apply where roads are transparent by
- //using road texture as a mask.
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_ZERO);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR);
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView);
- }
- return TRUE;
- }
- void RoadShader2Stage::reset(void)
- {
- ShaderClass::Invalidate();
- //Free references to textures
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1);
- }
- /** List of all custom shader lists - each list in this list contains variations of the same
- shader to allow it to work on different hardware configurations.
- */
- W3DShaderInterface **MasterShaderList[]=
- {
- TerrainShaderList,
- ShroudShaderList,
- RoadShaderList,
- MaskShaderList,
- CloudShaderList,
- NULL
- };
- /** List of all custom filter lists - each list in this list contains variations of the same
- filter to allow it to work on different hardware configurations.
- */
- W3DFilterInterface **MasterFilterList[]=
- {
- ScreenBWFilterList,
- ScreenMotionBlurFilterList,
- ScreenCrossFadeFilterList,
- NULL
- };
- // W3DShaderManager::W3DShaderManager =========================================
- /** Constructor - just clears some variables */
- //=============================================================================
- W3DShaderManager::W3DShaderManager(void)
- {
- m_currentShader = ST_INVALID;
- m_currentFilter = FT_NULL_FILTER;
- m_oldRenderSurface = NULL;
- m_renderTexture = NULL;
- m_newRenderSurface = NULL;
- m_oldDepthSurface = NULL;
- m_renderingToTexture = false;
- Int i;
- for (i=0; i<W3DShaderManager::ST_MAX; i++)
- { W3DShaders[i]=NULL;
- W3DShadersPassCount[i]=0;
- }
- for (i=0; i<FT_MAX; i++)
- { W3DFilters[i]=NULL;
- }
- for (i=0; i<8; i++)
- {
- m_Textures[i]=NULL;
- }
- m_currentShader=(W3DShaderManager::ShaderTypes)-1;
- }
- // W3DShaderManager::init =======================================================
- /** Walk through all shaders and find versions suitable for current hardware */
- //=============================================================================
- void W3DShaderManager::init(void)
- {
- int i,j;
- D3DSURFACE_DESC desc;
- // For now, check & see if we are gf3 or higher on the food chain.
- Int res=0;
- if ((res=W3DShaderManager::getChipset()) != 0)
- {
- //Some of our effects require an offscreen render target, so try creating it here.
- HRESULT hr=DX8Wrapper::_Get_D3D_Device8()->GetRenderTarget(&m_oldRenderSurface);
- m_oldRenderSurface->GetDesc(&desc);
- hr=DX8Wrapper::_Get_D3D_Device8()->CreateTexture(desc.Width,desc.Height,1,D3DUSAGE_RENDERTARGET,desc.Format,D3DPOOL_DEFAULT,&m_renderTexture);
- if (hr != S_OK)
- {
- if (m_oldRenderSurface) m_oldRenderSurface->Release();
- m_oldRenderSurface = NULL;
- m_renderTexture = NULL;
- } else {
- hr = m_renderTexture->GetSurfaceLevel(0, &m_newRenderSurface);
- if (hr != S_OK)
- {
- if (m_renderTexture) m_renderTexture->Release();
- m_renderTexture = NULL;
- m_newRenderSurface = NULL;
- } else {
- hr = DX8Wrapper::_Get_D3D_Device8()->GetDepthStencilSurface(&m_oldDepthSurface);
- if (hr != S_OK)
- {
- if (m_newRenderSurface) m_newRenderSurface->Release();
- if (m_renderTexture) m_renderTexture->Release();
- m_renderTexture = NULL;
- m_newRenderSurface = NULL;
- m_oldDepthSurface = NULL;
- }
- }
- }
- }
- W3DShaderInterface **shaders;
- for (i=0; MasterShaderList[i] != NULL; i++)
- {
- shaders=MasterShaderList[i];
- for (j=0; shaders[j] != NULL; j++)
- {
- if (shaders[j]->init())
- break; //found a working shader
- }
- }
- W3DFilterInterface **filters;
- for (i=0; MasterFilterList[i] != NULL; i++)
- {
- filters=MasterFilterList[i];
- for (j=0; filters[j] != NULL; j++)
- {
- if (filters[j]->init())
- break; //found a working shader
- }
- }
- DEBUG_LOG(("ShaderManager ChipsetID %d\n", res));
- }
- // W3DShaderManager::shutdown =======================================================
- /** Any shaders which allocate resources will be allowed to free them */
- //=============================================================================
- void W3DShaderManager::shutdown(void)
- {
- if (m_newRenderSurface) m_newRenderSurface->Release();
- if (m_renderTexture) m_renderTexture->Release();
- if (m_oldRenderSurface) m_oldRenderSurface->Release();
- if (m_oldDepthSurface) m_oldDepthSurface->Release();
- m_renderTexture = NULL;
- m_newRenderSurface = NULL;
- m_oldDepthSurface = NULL;
- m_oldRenderSurface = NULL;
- m_currentShader = ST_INVALID;
- m_currentFilter = FT_NULL_FILTER;
- //release any assets associated with a shader (vertex/pixel shaders, textures, etc.)
- for (Int i=0; i<W3DShaderManager::ST_MAX; i++) {
- if (W3DShaders[i]) {
- W3DShaders[i]->shutdown();
- }
- }
- for ( i=0; i < FT_MAX; i++)
- {
- if (W3DFilters[i])
- {
- W3DFilters[i]->shutdown();
- }
- }
- }
- // W3DShaderManager::getShaderPasses =======================================================
- /** Return number of renderig passes required in perform the desired shader on current
- hardware. App will need to re-render the polygons this many times to complete the
- effect.
- */
- //=============================================================================
- Int W3DShaderManager::getShaderPasses(ShaderTypes shader)
- {
- return W3DShadersPassCount[shader];
- }
- // W3DShaderManager::setShader =======================================================
- /** Must call this method before each rendering pass in order to perform proper D3D
- setup for each shader.
- */
- //=============================================================================
- Int W3DShaderManager::setShader(ShaderTypes shader, Int pass)
- {
- if (shader == m_currentShader && pass == m_currentShaderPass)
- return TRUE; //shader is already set
- m_currentShader=shader;
- m_currentShaderPass = pass;
- if (W3DShaders[shader])
- return W3DShaders[shader]->set(pass);
- return FALSE;
- }
- // W3DShaderManager::resetShader =======================================================
- /** Must call this method after all polygons and rendering passes have been submitted.
- This method allows D3D to reset itself to a default state that doesn't conflict
- with the WW3D2 Shader system.
- */
- //=============================================================================
- void W3DShaderManager::resetShader(ShaderTypes shader)
- {
- if (m_currentShader == ST_INVALID)
- return; //last shader is already reset.
- if (W3DShaders[shader])
- W3DShaders[shader]->reset();
- m_currentShader = ST_INVALID;
- }
- // W3DShaderManager::filterPreRender =======================================================
- /** Call to view filter shaders before rendering starts.
- */
- //=============================================================================
- Bool W3DShaderManager::filterPreRender(FilterTypes filter, Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- if (W3DFilters[filter])
- { Bool result=W3DFilters[filter]->preRender(skipRender,scenePassMode);
- if (result)
- m_currentFilter = filter;
- return result;
- }
- return FALSE;
- }
- // W3DShaderManager::filterPostRender =======================================================
- /** Call to view filter shaders after rendering is complete.
- */
- //=============================================================================
- Bool W3DShaderManager::filterPostRender(FilterTypes filter, enum FilterModes mode, Coord2D &scrollDelta, Bool &doExtraRender)
- {
- if (W3DFilters[filter])
- return W3DFilters[filter]->postRender(mode, scrollDelta,doExtraRender);
- m_currentFilter = FT_NULL_FILTER;
- return FALSE;
- }
- // W3DShaderManager::filterPostRender =======================================================
- /** Call to view filter shaders after rendering is complete.
- */
- //=============================================================================
- static Bool filterSetup(FilterTypes filter, enum FilterModes mode);
- Bool W3DShaderManager::filterSetup(FilterTypes filter, enum FilterModes mode)
- {
- if (W3DFilters[filter])
- return W3DFilters[filter]->setup(mode);
- return FALSE;
- }
- /*Draws 2 triangles covering the viewport given the current render states*/
- void W3DShaderManager::drawViewport(Int color)
- {
- LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8();
- struct _TRANS_LIT_TEX_VERTEX {
- D3DXVECTOR4 p;
- DWORD color; // diffuse color
- float u;
- float v;
- } v[4];
- Int xpos, ypos, width, height;
- TheTacticalView->getOrigin(&xpos,&ypos);
- width=TheTacticalView->getWidth();
- height=TheTacticalView->getHeight();
- //bottom right
- v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top right
- v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- //bottom left
- v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f );
- v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight();
- //top left
- v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f );
- v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight();
- v[0].color = color;
- v[1].color = color;
- v[2].color = color;
- v[3].color = color;
- //draw polygons like this is very inefficient but for only 2 triangles, it's
- //not worth bothering with index/vertex buffers.
- pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
- pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX));
- }
- // W3DShaderManager::startRenderToTexture =======================================================
- /** Starts rendering to a texture.
- */
- //=============================================================================
- void W3DShaderManager::startRenderToTexture(void)
- {
- DEBUG_ASSERTCRASH(!m_renderingToTexture, ("Already rendering to texture - cannot nest calls."));
- if (m_renderingToTexture || m_newRenderSurface==NULL || m_oldDepthSurface==NULL) return;
- HRESULT hr = DX8Wrapper::_Get_D3D_Device8()->SetRenderTarget(m_newRenderSurface,m_oldDepthSurface);
- DEBUG_ASSERTCRASH(hr==S_OK, ("Set target failed unexpectedly."));
- if (hr != S_OK)
- return;
- m_renderingToTexture = true;
- if (TheGlobalData->m_showSoftWaterEdge)
- { //Soft water edges use frame buffer destination alpha so we must clear it to a known value.
- if (m_currentFilter == FT_VIEW_MOTION_BLUR_FILTER || m_currentFilter == FT_VIEW_CROSSFADE)
- { //these filters rely on the previous frame being visible so we must be careful about clearing
- //frame buffer. Only clear the alpha channel
- DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_ALPHA); //only clear alpha
- ShaderClass shader=ShaderClass::_PresetOpaqueSolidShader;
- shader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS);
- shader.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE);
- DX8Wrapper::Set_Shader(shader);
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset.
-
- drawViewport(0x00ffffff | (((Int)(TheWaterTransparency->m_minWaterOpacity*255.0f)) <<24));
- DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE); //disable writes to alpha
- }
- else //normal clear that overwrites everything.
- DX8Wrapper::Clear(true, false, Vector3( 0.0f, 0.0f, 0.0f ), TheWaterTransparency->m_minWaterOpacity);
- }
- }
- // W3DShaderManager::startRenderToTexture =======================================================
- /** Ends rendering to a texture.
- */
- //=============================================================================
- IDirect3DTexture8 *W3DShaderManager::endRenderToTexture(void)
- {
- DEBUG_ASSERTCRASH(m_renderingToTexture, ("Not rendering to texture."));
- if (!m_renderingToTexture) return NULL;
- HRESULT hr = DX8Wrapper::_Get_D3D_Device8()->SetRenderTarget(m_oldRenderSurface,m_oldDepthSurface); //restore original render target
- DEBUG_ASSERTCRASH(hr==S_OK, ("Set target failed unexpectedly."));
- if (hr == S_OK)
- {
- //assume render target texure will be in stage 0. Most hardware has "conditional" support for
- //non-power-of-2 textures so we must force some required states:
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
- m_renderingToTexture = false;
- }
- return m_renderTexture;
- }
- /**Returns texture containing the image that was last rendered using any of the effects requiring render target
- textures. Used mostly for cross-fading effects that need an unmodified version of the view before the effect
- was applied. NOTE: This texture does not survive device reset.. so quit effect on reset!*/
- IDirect3DTexture8 *W3DShaderManager::getRenderTexture(void)
- {
- return m_renderTexture;
- }
- #define DC_NVIDIA_VENDOR_ID 0x10DE
- #define DC_3DFX_VENDOR_ID 0x121A
- #define DC_ATI_VENDOR_ID 0x1002
- // W3DShaderManager::ChipsetType =======================================================
- /** Returns the chipset used by the currently active rendering device. Can be useful
- for coding around specific driver bugs.
- */
- //=============================================================================
- ChipsetType W3DShaderManager::getChipset( void )
- {
- //check if globaldata has an override for current chipset
- if (TheGlobalData && TheGlobalData->m_chipSetType != DC_UNKNOWN)
- return (ChipsetType)TheGlobalData->m_chipSetType;
- ChipsetType chip=DC_UNKNOWN;
- IDirect3D8* d3d8Interface=DX8Wrapper::_Get_D3D8();
- if (d3d8Interface && DX8Wrapper::_Get_D3D_Device8())
- {
- D3DADAPTER_IDENTIFIER8 did;
- ::ZeroMemory(&did, sizeof(D3DADAPTER_IDENTIFIER8));
- /* HRESULT res = */ d3d8Interface->GetAdapterIdentifier(0,D3DENUM_NO_WHQL_LEVEL,&did);
-
- if(did.VendorId == DC_NVIDIA_VENDOR_ID)
- {
- if (did.DeviceId == 0x20)
- return DC_TNT;
-
- if (did.DeviceId >= 0x28 && did.DeviceId < 0x100)
- return DC_TNT2;
- if ( (did.DeviceId >= 0x100 && did.DeviceId <= 0x103) || //GeForce
- (did.DeviceId >= 0x110 && did.DeviceId <= 0x113) || //GeForce2 MX
- (did.DeviceId >= 0x150 && did.DeviceId <= 0x153) ) //GeForce2
- return DC_GEFORCE2;
- if (did.DeviceId >= 0x200 && did.DeviceId < 0x250)
- return DC_GEFORCE3;
- if (did.DeviceId >= 0x250)
- return DC_GEFORCE4;
- }
- else
- if(did.VendorId == DC_3DFX_VENDOR_ID)
- {
- if (did.DeviceId == 0x0002)
- return DC_VOODOO2;
- if (did.DeviceId == 0x0005)
- return DC_VOODOO3;
- if (did.DeviceId == 0x0008) ///@todo: Just guessing on this one - find actual Voodoo4 deviceID.
- return DC_VOODOO4;
- if (did.DeviceId == 0x0009)
- return DC_VOODOO5;
- }
- else
- if(did.VendorId == DC_ATI_VENDOR_ID)
- {
- if (did.DeviceId == 0x5144)
- return DC_RADEON;
- if (did.DeviceId == 0x514C)
- return DC_RADEON_8500;
- if (did.DeviceId == 0x4e44)
- return DC_RADEON_9700;
- }
- //None of the vendor specific ID's matched so use generic means to classify the card
- Int maxTextures=DX8Caps::Get_Max_Simultaneous_Textures();
- Real pixelShaderVersion;
- char buf[256];
- //Convert version to Real
- sprintf(buf,"%d.%d",DX8Caps::Get_Pixel_Shader_Majon_Version(),DX8Caps::Get_Pixel_Shader_Minor_Version());
- sscanf(buf,"%f",&pixelShaderVersion);
- if (maxTextures >= 4)
- { if (pixelShaderVersion >= 1.1f)
- chip=DC_GENERIC_PIXEL_SHADER_1_1;
- if (pixelShaderVersion >= 1.4f)
- chip=DC_GENERIC_PIXEL_SHADER_1_4;
- if (maxTextures >= 8 && pixelShaderVersion >= 2.0f)
- chip=DC_GENERIC_PIXEL_SHADER_2_0;
- }
- } //D3D8 interface and device exist.
-
- return chip;
- }
- //=============================================================================
- // WaterRenderObjClass::LoadAndCreateShader
- //=============================================================================
- /** Loads and creates a D3D pixel or vertex shader.*/
- //=============================================================================
- HRESULT W3DShaderManager::LoadAndCreateD3DShader(char* strFilePath, const DWORD* pDeclaration, DWORD Usage, Bool ShaderType, DWORD* pHandle)
- {
- try
- {
- File *file = NULL;
- HRESULT hr;
- file = TheFileSystem->openFile(strFilePath, File::READ | File::BINARY);
- if (file == NULL)
- {
- OutputDebugString("Could not find file \n" );
- return E_FAIL;
- }
- FileInfo fileInfo;
- TheFileSystem->getFileInfo(AsciiString(strFilePath), &fileInfo);
- DWORD dwFileSize = fileInfo.sizeLow;
- const DWORD* pShader = (DWORD*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwFileSize);
- if (!pShader)
- {
- OutputDebugString( "Failed to allocate memory to load shader\n " );
- return E_FAIL;
- }
- file->read((void *)pShader, dwFileSize);
- file->close();
- file = NULL;
- if (ShaderType == TRUE)//SHADERTYPE_VERTEX)
- {
- hr = DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader(pDeclaration, pShader, pHandle, Usage);
- }
- else if (ShaderType == FALSE)//SHADERTYPE_PIXEL)
- {
- hr = DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader(pShader, pHandle);
- }
- HeapFree(GetProcessHeap(), 0, (void*)pShader);
- if (FAILED(hr))
- {
- OutputDebugString( "Failed to create shader\n ");
- return E_FAIL;
- }
- }
- catch(...)
- {
- OutputDebugString( "Error opening file \n" );
- return E_FAIL;
- }
- return S_OK;
- }
- //For the MP test, we're enforcing high min-spec requirements that need to be verified.
- #define MIN_INTEL_CPU_FREQ 1300
- #define MIN_AMD_CPU_FREQ 1100
- #define MIN_ACCEPTED_FREQUENCY 1300
- #define MIN_ACCEPTED_MEMORY (1024*1024*256) //256 MB
- #define MIN_ACCEPTED_TEXTURE_MEMORY (1024*1024*30) //30 MB
- /**Hack to give gameengine access to this function*/
- Bool testMinimumRequirements(ChipsetType *videoChipType, CpuType *cpuType, Int *cpuFreq, Int *numRAM, Real *intBenchIndex, Real *floatBenchIndex, Real *memBenchIndex)
- {
- return W3DShaderManager::testMinimumRequirements(videoChipType,cpuType,cpuFreq,numRAM,intBenchIndex,floatBenchIndex,memBenchIndex);
- }
- Bool W3DShaderManager::testMinimumRequirements(ChipsetType *videoChipType, CpuType *cpuType, Int *cpuFreq, Int *numRAM, Real *intBenchIndex, Real *floatBenchIndex, Real *memBenchIndex)
- {
- if (videoChipType)
- *videoChipType = getChipset();
- if (cpuType)
- {
- *cpuType = XX; //unknown
- //Check if it's an Athlon
- if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_AMD &&
- CPUDetectClass::Get_AMD_Processor() >= CPUDetectClass::AMD_PROCESSOR_ATHLON_025)
- *cpuType = K7;
- //Check if it's a P3
- if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_INTEL &&
- CPUDetectClass::Get_Intel_Processor() >= CPUDetectClass::INTEL_PROCESSOR_PENTIUM_III_MODEL_7)
- *cpuType = P3;
- //Check if it's a P4
- if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_INTEL &&
- CPUDetectClass::Get_Intel_Processor() >= CPUDetectClass::INTEL_PROCESSOR_PENTIUM4)
- *cpuType = P4;
- }
- if (cpuFreq)
- *cpuFreq=CPUDetectClass::Get_Processor_Speed();
- if (numRAM)
- *numRAM=CPUDetectClass::Get_Total_Physical_Memory();
- if (intBenchIndex && floatBenchIndex && memBenchIndex)
- {
- RunBenchmark(0, NULL, floatBenchIndex, intBenchIndex, memBenchIndex);
- }
- return TRUE;
- }
- /**Try to guess how well the video card will handle the game assuming very fast CPU*/
- StaticGameLODLevel W3DShaderManager::getGPUPerformanceIndex(void)
- {
- ChipsetType chipType;
- StaticGameLODLevel detailSetting=STATIC_GAME_LOD_LOW; //assume lowest settings for now.
- if ((chipType=getChipset()) != DC_UNKNOWN)
- { //a known video card so we can make some assumptions
- if (chipType >= DC_GEFORCE2)
- detailSetting=STATIC_GAME_LOD_LOW; //these cards need multiple terrain passes.
- if (chipType >= DC_GENERIC_PIXEL_SHADER_1_1) //these cards can do terrain in single pass.
- detailSetting=STATIC_GAME_LOD_HIGH;
- }
- return detailSetting;
- }
- /**We need a hardware independent method to compare different CPU's. For lack of anything better, we'll
- use time to calculate PIE using a slow random number algorithm.*/
- /**Used to test function call overhead*/
- void add(float *sum,float *addend)
- {
- *sum = *sum + *addend;
- }
- /**Returns seconds needed to run the test*/
- Real W3DShaderManager::GetCPUBenchTime(void)
- {
- float ztot, yran, ymult, ymod, x, y, z, pi, prod;
- long int low, ixran, itot, j, iprod;
- __int64 endTime64,freq64,startTime64;
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- ztot = 0.0;
- low = 1;
- ixran = 1907;
- yran = 5813.0;
- ymult = 1307.0;
- ymod = 5471.0;
- itot = 560000; //total iterations. This value ends up running at ~30 fps on our P4-2.2Ghz.
- for(j=1; j<=itot; j++)
- {
- iprod = 27611 * ixran;
- ixran = iprod - 74383*(long int)(iprod/74383);
- x = (float)ixran / 74383.0;
- prod = ymult * yran;
- yran = (prod - ymod*(long int)(prod/ymod));
- y = yran / ymod;
- z = x*x + y*y;
- add(&ztot,&z);
- if ( z <= 1.0 )
- {
- low = low + 1;
- }
- }
- pi = 4.0 * (float)low/(float)itot;
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- return ((double)(endTime64-startTime64)/(double)(freq64));
- }
|