| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736 |
- /*
- ** Command & Conquer Generals Zero Hour(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 "W3DDevice/GameClient/W3DSmudge.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
- // Turn this on to turn off pixel shaders. jba[4/3/2003]
- #define do_not_DISABLE_PIXEL_SHADERS 1
- /** 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;
- ChipsetType W3DShaderManager::m_currentChipset;
- GraphicsVenderID W3DShaderManager::m_currentVendor;
- __int64 W3DShaderManager::m_driverVersion;
- 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 =============================================================*/
- /*===========================================================================================*/
- class ScreenDefaultFilter : public W3DFilterInterface
- {
- public:
- virtual Int init(void); ///<perform any one time initialization and validation
- virtual Bool preRender(Bool &skipRender, CustomScenePassModes &scenePassMode); ///< Set up at start of render. Only applies to screen filter shaders.
- virtual Bool postRender(enum FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender); ///< Called after render. Only applies to screen filter shaders.
- virtual Bool setup(enum FilterModes mode){return true;} ///< Called when the filter is started, one time before the first prerender.
- protected:
- virtual Int set(enum FilterModes mode); ///<setup shader for the specified rendering pass.
- virtual void reset(void); ///<do any custom resetting necessary to bring W3D in sync.
- };
- ScreenDefaultFilter screenDefaultFilter;
- ///Default filter that just renders screen to off-screen texture and then copies it the the screen.
- ///Useful because we added some full-time unit effects (microwave tank smudge) to Generals MD that need access
- ///to the background as a texture. This filter makes that texture always available for these effects.
- W3DFilterInterface *ScreenDefaultFilterList[]=
- {
- &screenDefaultFilter,
- NULL
- };
- Int ScreenDefaultFilter::init(void)
- {
- if (!W3DShaderManager::canRenderToTexture()) {
- // Have to be able to render to texture.
- return FALSE;
- }
- //Can render to texture, but we don't know if it can read and write to the same texture.
- //Since there is no D3D caps bit to tell you this, we will just hard-code some specific
- //cards that we know should work.
- Int res;
- if ((res=W3DShaderManager::getChipset()) != DC_UNKNOWN)
- {
- if ( res >= DC_GEFORCE2)
- {
- //Check if their driver is newer than what we tested for this vendor
- /* if (TheGameLODManager)
- {
- if (TheGameLODManager->getTestedDriverVersion(W3DShaderManager::getCurrentVendor()) < W3DShaderManager::getCurrentDriverVersion())
- return FALSE;
- }*/
- }
- }
- W3DFilters[FT_VIEW_DEFAULT]=&screenDefaultFilter;
- return TRUE;
- }
- Bool ScreenDefaultFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode)
- {
- //Right now this filter is only used for smudges, so don't bother if none are present.
- if (TheSmudgeManager)
- { if (((W3DSmudgeManager *)TheSmudgeManager)->getSmudgeCountLastFrame() == 0)
- return FALSE;
- }
- W3DShaderManager::startRenderToTexture();
- return true;
- }
- Bool ScreenDefaultFilter::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 ScreenDefaultFilter::set(enum FilterModes mode)
- {
- 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;
- }
- void ScreenDefaultFilter::reset(void)
- {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture
- DX8Wrapper::Invalidate_Cached_Render_States();
- }
- /*========= 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 (DX8Wrapper::Get_Current_Caps()->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->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_fadePatternTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_fadePatternTexture->Get_Filter().Set_Mip_Mapping(TextureFilterClass::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_D3D_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.
- DX8Wrapper::Set_Texture(stage, W3DShaderManager::getShaderTexture(0)); //shroud always stored in texture 0
- 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;
- Matrix4x4 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), *((Matrix4x4*)&curView));
- }
- m_stageOfSet=stage;
- return TRUE;
- }
- void ShroudTextureShader::reset(void)
- {
- 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);
- }
- ///Shroud layer rendering shader
- class FlatShroudTextureShader : 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;
- } flatShroudTextureShader;
- ///List of different shroud shader implementations in order of preference
- W3DShaderInterface *FlatShroudShaderList[]=
- {
- &flatShroudTextureShader,
- NULL
- };
- //#define SHROUD_STRETCH_FACTOR (1.0f/MAP_XY_FACTOR) //1 texel per heightmap cell width
- Int FlatShroudTextureShader::init(void)
- {
- W3DShaders[W3DShaderManager::ST_FLAT_SHROUD_TEXTURE]=&flatShroudTextureShader;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_SHROUD_TEXTURE]=1;
- return TRUE;
- }
- //Setup a texture projection in the given stage that applies our shroud.
- Int FlatShroudTextureShader::set(Int stage)
- {
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- if (stage < 2)
- DX8Wrapper::Set_Texture(stage, W3DShaderManager::getShaderTexture(stage));
- else //stages larger than 1 are not supported by W3D so set them directly
- DX8Wrapper::Set_DX8_Texture(stage, W3DShaderManager::getShaderTexture(stage)->Peek_D3D_Texture());
- 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_ALPHAOP, D3DTOP_DISABLE );
- //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);
- //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;
- Matrix4x4 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), *((Matrix4x4*)&curView));
- }
- m_stageOfSet=stage;
- return TRUE;
- }
- void FlatShroudTextureShader::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();
- Matrix4x4 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, *((Matrix4x4*)&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;
- ///regular terrain shader that should work on all multi-texture video cards (slowest version)
- class FlatTerrainShader2Stage : public W3DShaderInterface
- {
- public:
- 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.
- } flatTerrainShader2Stage;
- ///regular terrain shader that should work on all multi-texture video cards (slowest version)
- class FlatTerrainShaderPixelShader : public W3DShaderInterface
- {
- public:
- 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
- DWORD m_dwBase0PixelShader; ///<handle to terrain only pixel shader
- 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.
- virtual Int shutdown(void); ///<release resources used by shader
- } flatTerrainShaderPixelShader;
- ///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
- };
- ///List of different terrain shader implementations in order of preference
- W3DShaderInterface *FlatTerrainShaderList[]=
- {
- &flatTerrainShaderPixelShader,
- &flatTerrainShader2Stage,
- 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 );
- while (m_xOffset > 1) m_xOffset -= 1;
- while (m_yOffset > 1) m_yOffset -= 1;
- while (m_xOffset < -1) m_xOffset += 1;
- while (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_D3D_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_D3D_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
- Matrix4x4 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_D3D_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_D3D_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_D3D_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_D3D_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, *((Matrix4x4*)&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_D3D_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_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;
- #ifdef DISABLE_PIXEL_SHADERS
- return false;
- #endif
- //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_D3D_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_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)
- {
- Matrix4x4 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_D3D_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3, W3DShaderManager::getShaderTexture(3)->Peek_D3D_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_D3D_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_D3D_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)
- {
- Matrix4x4 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_D3D_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)
- {
- DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0));
- //force WW3D2 system to set it's states so it won't later overwrite our custom settings.
- DX8Wrapper::Apply_Render_State_Changes();
- //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);
- Matrix4x4 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::Set_Texture(1,W3DShaderManager::getShaderTexture(1));
- DX8Wrapper::Set_Texture(2,W3DShaderManager::getShaderTexture(2));
- 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()->SetPixelShader(0); //turn off pixel shader
- 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)
- {
- //First stage always contains base texture.
- DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0));
- //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);
- // 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
- Matrix4x4 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::Set_Texture(1,W3DShaderManager::getShaderTexture(1));
- 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::Set_Texture(1,W3DShaderManager::getShaderTexture(1));
- 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::Set_Texture(1,W3DShaderManager::getShaderTexture(2));
- 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
- Matrix4x4 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_Texture(1,W3DShaderManager::getShaderTexture(2));
- 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::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,
- FlatShroudShaderList,
- RoadShaderList,
- MaskShaderList,
- CloudShaderList,
- FlatTerrainShaderList,
- 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[]=
- {
- ScreenDefaultFilterList,
- 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.
- ChipsetType res=DC_UNKNOWN;
- if ((res=W3DShaderManager::getChipset()) != 0)
- {
- m_currentChipset = res; //cache the current chipset.
- //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;
- }
- enum GraphicsVenderID
- {
- DC_NVIDIA_VENDOR_ID = 0x10DE,
- DC_3DFX_VENDOR_ID = 0x121A,
- 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);
- *((LARGE_INTEGER*)&m_driverVersion) = did.DriverVersion;
- if(did.VendorId == DC_NVIDIA_VENDOR_ID)
- {
- m_currentVendor = 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)
- {
- m_currentVendor = 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)
- {
- m_currentVendor = 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=DX8Wrapper::Get_Current_Caps()->Get_Max_Simultaneous_Textures();
- Real pixelShaderVersion;
- char buf[256];
- //Convert version to Real
- sprintf(buf,"%d.%d",DX8Wrapper::Get_Current_Caps()->Get_Pixel_Shader_Major_Version(),DX8Wrapper::Get_Current_Caps()->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)
- {
- if (getChipset() < DC_GENERIC_PIXEL_SHADER_1_1)
- return E_FAIL; //don't allow loading any shaders if hardware can't handle it.
-
- 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));
- }
- // W3DShaderManager::setShroudTex =======================================================
- /** Puts the shroud texture into a texture stage.
- */
- //=============================================================================
- Int W3DShaderManager::setShroudTex(Int stage)
- {
- //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)
- {
- DX8Wrapper::Set_Texture(stage, shroud->getShroudTexture());
- 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_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_ALPHAARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
- D3DXMATRIX inv;
- float det;
- Matrix4x4 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), *((Matrix4x4*)&curView));
- return TRUE;
- }
- return FALSE;
- }
- Int FlatTerrainShader2Stage::init( void )
- {
- //no special device validation needed - anything in our min spec should handle this.
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=2;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=2;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShader2Stage;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=2;
- return TRUE;
- }
- void FlatTerrainShader2Stage::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);
- }
- Int FlatTerrainShader2Stage::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_POINT);
- }
- switch (pass)
- {
- case 0:
- 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 );
- if (W3DShaderManager::getShaderTexture(0)) {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
- 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(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- //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)
- {
- D3DXMATRIX inv;
- float det;
- Matrix4x4 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), *((Matrix4x4*)&curView));
- }
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
- }
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- // Modulate the diffuse color with the texture as lighting comes from diffuse.
- 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, 0 );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false);
- break;
- case 1:
- // Noise/cloud pass
- Matrix4x4 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_FLAT_TERRAIN_BASE_NOISE12)
- {
- //setup cloud pass
- terrainShader2Stage.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);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture());
- //setup noise pass
- terrainShader2Stage.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);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture());
- } //ST_TERRAIN_BASE_NOISE12
- else
- { //only 1 noise or cloud texture
- // Now setup the texture pipeline.
- if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1)
- { //setup cloud pass
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture());
- terrainShader2Stage.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_D3D_Texture());
- terrainShader2Stage.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, *((Matrix4x4*)&curView));
- }
- break;
- }
- return TRUE;
- }
- Int FlatTerrainShaderPixelShader::shutdown(void)
- {
- if (m_dwBasePixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBasePixelShader);
- if (m_dwBase0PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBase0PixelShader);
- if (m_dwBaseNoise1PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise1PixelShader);
- if (m_dwBaseNoise2PixelShader)
- DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader);
- m_dwBasePixelShader=NULL;
- m_dwBase0PixelShader=NULL;
- m_dwBaseNoise1PixelShader=NULL;
- m_dwBaseNoise2PixelShader=NULL;
- return TRUE;
- }
- Int FlatTerrainShaderPixelShader::init( void )
- {
- Int res;
- #ifdef DISABLE_PIXEL_SHADERS
- return false;
- #endif
- //this shader will also use the 2Stage shader for some of the passes so initialize it too.
- if ((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\\fterrain.pso", &Declaration[0], 0, false, &m_dwBasePixelShader);
- if (FAILED(hr))
- return FALSE;
- //base version which doesn't apply any shroud textures.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrain0.pso", &Declaration[0], 0, false, &m_dwBase0PixelShader);
- if (FAILED(hr))
- return FALSE;
- //version which blends 1 noise texture.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise.pso", &Declaration[0], 0, false, &m_dwBaseNoise1PixelShader);
- if (FAILED(hr))
- return FALSE;
- //version which blends 2 noise textures.
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader);
- if (FAILED(hr))
- return FALSE;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShaderPixelShader;
- W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShaderPixelShader;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=1;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=1;
- W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=1;
- return TRUE;
- }
- }
- return FALSE;
- }
- Int FlatTerrainShaderPixelShader::set(Int pass)
- {
- //setup base pass
- Int curStage = 1;
- // setup terrain [3/31/2003]
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_Texture(0, W3DShaderManager::getShaderTexture(2));
- DX8Wrapper::Set_Texture(1, W3DShaderManager::getShaderTexture(2));
- //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( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- //tell pixel shader which UV set to use for each stage
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_TEXCOORDINDEX, 0 );
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_POINT);
- }
- if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
- } else {
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
- }
- curStage = 0;
- W3DShroud *shroud = TheTerrainRenderObject->getShroud();
- if (shroud) {
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- //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).
- {
- D3DXMATRIX inv;
- float det;
- Matrix4x4 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+curStage), *((Matrix4x4*)&curView));
- }
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, shroud->getShroudTexture()->Peek_D3D_Texture());
- curStage++;
- if (curStage==1) curStage++;
- }
- Bool doNoise1 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1 ||
- W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12);
- if (doNoise1) { // Cloud pass.
- Matrix4x4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture());
- terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView));
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
-
- curStage++;
- if (curStage==1) curStage++;
- }
- Bool doNoise2 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2 ||
- W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12);
- if (doNoise2)
- {
- Matrix4x4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMATRIX inv;
- float det;
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture());
- terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix
- DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView));
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
- DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
-
- curStage++;
- if (curStage==1) curStage++;
- }
- if (curStage<2) {
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBase0PixelShader);
- } else if (curStage==2) {
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBasePixelShader);
- } else if (curStage==3) {
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise1PixelShader);
- }else if (curStage==4) {
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader);
- }
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture());
- return TRUE;
- }
- void FlatTerrainShaderPixelShader::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();
- }
|