| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916 |
- /*
- ** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***************************************************************************
- * *
- * Project Name : G *
- * *
- * $Archive:: /VSS_Sync/ww3d2/pointgr.cpp $*
- * *
- * Org Author:: Greg Hjelstrom *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 4:04p $*
- * *
- * $Revision:: 38 $*
- * *
- * 06/26/02 KM Matrix name change to avoid MAX conflicts *
- *-------------------------------------------------------------------------*
- * Functions: *
- * PointGroupClass::PointGroupClass -- PointGroupClass CTor. *
- * PointGroupClass::~PointGroupClass -- PointGroupClass DTor. *
- * PointGroupClass::operator = -- PointGroupClass assignment operator. *
- * PointGroupClass::Set_Arrays -- Set point location/color/enable arrays.*
- * PointGroupClass::Set_Point_Size -- Set default point size. *
- * PointGroupClass::Get_Point_Size -- Get default point size. *
- * PointGroupClass::Set_Point_Color -- Set default point color. *
- * PointGroupClass::Get_Point_Color -- Get default point color. *
- * PointGroupClass::Set_Point_Alpha -- Set default point alpha. *
- * PointGroupClass::Get_Point_Alpha -- Get default point alpha. *
- * PointGroupClass::Set_Point_Orientation -- Set default point orientatio*
- * PointGroupClass::Get_Point_Orientation -- Get default point orientatio*
- * PointGroupClass::Set_Point_Frame -- Set default point frame. *
- * PointGroupClass::Get_Point_Frame -- Get default point frame. *
- * PointGroupClass::Set_Point_Mode -- Set point rendering method. *
- * PointGroupClass::Get_Point_Mode -- Get point rendering method. *
- * PointGroupClass::Set_Flag -- Set given flag to on or off. *
- * PointGroupClass::Get_Flag -- Get current value (on/off) of given flag.*
- * PointGroupClass::Set_Texture -- Set texture used. *
- * PointGroupClass::Get_Texture -- Get texture used. *
- * PointGroupClass::Set_Shader -- Set shader used. *
- * PointGroupClass::Get_Shader -- Get shader used. *
- * PointGroupClass::Set_Billboard -- Set whether to billboard. *
- * PointGroupClass::Get_Billboard -- Get whether to billboard. *
- * PointGroupClass::Get_Discrete_Orientation_Count_Log2 -- what it says *
- * PointGroupClass::Set_Discrete_Orientation_Count_Log2 -- what it says. *
- * PointGroupClass::Get_Frame_Row_Column_Count_Log2 -- what it says *
- * PointGroupClass::Set_Frame_Row_Column_Count_Log2 -- what it says. *
- * PointGroupClass::Get_Polygon_Count -- Get estimated polygon count. *
- * PointGroupClass::Render -- draw point group. *
- * PointGroupClass::vInstance -- Create instance of class. *
- * PointGroupClass::sGetClassName -- Get name of class. *
- * PointGroupClass::Update_Arrays -- Update all arrays used in rendering *
- * PointGroupClass::Peek_Texture -- Peeks texture *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "pointgr.h"
- #include "vertmaterial.h"
- #include "ww3d.h"
- #include "aabox.h"
- #include "statistics.h"
- #include "simplevec.h"
- #include "texture.h"
- #include "vector.h"
- #include "vp.h"
- #include "matrix4.h"
- #include "dx8wrapper.h"
- #include "dx8vertexbuffer.h"
- #include "dx8indexbuffer.h"
- #include "rinfo.h"
- #include "camera.h"
- #include "dx8fvf.h"
- #include "D3DXMath.h"
- #include "sortingrenderer.h"
- // Upgraded to DX8 2/2/01 HY
- // static data members
- Vector3 PointGroupClass::_TriVertexLocationOrientationTable[256][3];
- Vector3 PointGroupClass::_QuadVertexLocationOrientationTable[256][4];
- Vector2 *PointGroupClass::_TriVertexUVFrameTable[5] = { NULL, NULL, NULL, NULL, NULL};
- Vector2 *PointGroupClass::_QuadVertexUVFrameTable[5] = { NULL, NULL, NULL, NULL, NULL};
- VertexMaterialClass *PointGroupClass::PointMaterial=NULL;
- // Static arrays for intermediate calcs (never resized down, just up):
- VectorClass<Vector3> PointGroupClass::compressed_loc; // point locations 'compressed' by APT
- VectorClass<Vector4> PointGroupClass::compressed_diffuse; // point colors 'compressed' by APT
- VectorClass<float> PointGroupClass::compressed_size; // point sizes 'compressed' by APT
- VectorClass<unsigned char> PointGroupClass::compressed_orient; // point orientations 'compressed' by APT
- VectorClass<unsigned char> PointGroupClass::compressed_frame; // point frames 'compressed' by APT
- VectorClass<Vector3> PointGroupClass::transformed_loc; // transformed point locations
- // This array has vertex locations for screenspace mode - calculated to cover exactly 1x1 and 2x2 pixels.
- Vector3 PointGroupClass::_ScreenspaceVertexLocationSizeTable[2][3] =
- {
- Vector3(0.5f, 0.0f, -1.0f),
- Vector3(1.0f, 1.0f, -1.0f),
- Vector3(0.0f, 1.0f, -1.0f),
- Vector3(1.0f, -0.5f, -1.0f),
- Vector3(2.7f, 2.0f, -1.0f),
- Vector3(-0.7f, 2.0f, -1.0f)
- };
- // useful for particles that aren't aligned with the screen.
- static Vector3 GroundMultiplierX(1.0f, 0.0f, 0.0f);
- static Vector3 GroundMultiplierY(0.0f, 1.0f, 0.0f);
- // Some internal variables
- VectorClass<Vector3> VertexLoc; // camera-space vertex locations
- VectorClass<Vector4> VertexDiffuse; // vertex diffuse/alpha colors
- VectorClass<Vector2> VertexUV; // vertex texture coords
- // Some DX 8 variables
- #define MAX_VB_SIZE 2048
- #define MAX_TRI_POINTS MAX_VB_SIZE/3
- #define MAX_TRI_IB_SIZE 3*MAX_TRI_POINTS
- #define MAX_QUAD_POINTS MAX_VB_SIZE/4
- #define MAX_QUAD_IB_SIZE 6*MAX_QUAD_POINTS
- DX8IndexBufferClass *Tris, *Quads; // Index buffers.
- SortingIndexBufferClass *SortingTris, *SortingQuads; // Sorting index buffers.
- /**************************************************************************
- * PointGroupClass::PointGroupClass -- PointGroupClass CTor. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- PointGroupClass::PointGroupClass(void) :
- PointLoc(NULL),
- PointDiffuse(NULL),
- APT(NULL),
- PointSize(NULL),
- PointOrientation(NULL),
- PointFrame(NULL),
- PointCount(0),
- FrameRowColumnCountLog2(0),
- Texture(NULL),
- Flags(0),
- Shader(ShaderClass::_PresetAdditiveSpriteShader),
- PointMode(TRIS),
- DefaultPointSize(0.0f),
- DefaultPointColor(1.0f, 1.0f, 1.0f),
- DefaultPointAlpha(1.0f),
- DefaultPointOrientation(0),
- DefaultPointFrame(0),
- VPXMin(0.0f),
- VPYMin(0.0f),
- VPXMax(0.0f),
- VPYMax(0.0f)
- {
- }
- /**************************************************************************
- * PointGroupClass::~PointGroupClass -- PointGroupClass DTor. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- PointGroupClass::~PointGroupClass(void)
- {
- if (PointLoc) {
- PointLoc->Release_Ref();
- PointLoc = NULL;
- }
- if (PointDiffuse) {
- PointDiffuse->Release_Ref();
- PointDiffuse=NULL;
- }
- if (APT) {
- APT->Release_Ref();
- APT = NULL;
- }
- if (PointSize) {
- PointSize->Release_Ref();
- PointSize = NULL;
- }
- if (PointOrientation) {
- PointOrientation->Release_Ref();
- PointOrientation = NULL;
- }
- if (PointFrame) {
- PointFrame->Release_Ref();
- PointFrame = NULL;
- }
- if (Texture) {
- REF_PTR_RELEASE(Texture);
- Texture = NULL;
- }
- }
- /**************************************************************************
- * PointGroupClass::operator = -- PointGroupClass assignment operator. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- PointGroupClass & PointGroupClass::operator = (const PointGroupClass & that)
- {
- if (this != &that) {
- WWASSERT(0); // If you hit this assert implement the function!
- }
- return *this;
- }
- /**************************************************************************
- * PointGroupClass::Set_Arrays -- Set point location/color/enable arrays. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * NOTES: colors, alphas, APT, sizes, orientations and frames are *
- * optional. active_point_count can also be used with a NULL apt.*
- * In this case active_point_count is ignored if it is -1 *
- * (default value) and otherwise it indicates the first N active *
- * points in the arrays. *
- * The view plane rectangle may optionally be passed as well - *
- * this is only used in SCREENSPACE mode. *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- * 08/25/1999 NH : Alphas added. *
- * 06/28/2000 NH : Orientations and frames added. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- void PointGroupClass::Set_Arrays(
- ShareBufferClass<Vector3> *locs,
- ShareBufferClass<Vector4> *diffuse,
- ShareBufferClass<unsigned int> *apt,
- ShareBufferClass<float> *sizes,
- ShareBufferClass<unsigned char> *orientations,
- ShareBufferClass<unsigned char> *frames,
- int active_point_count,
- float vpxmin,
- float vpymin,
- float vpxmax,
- float vpymax)
- {
- // The point locations array is NOT optional!
- WWASSERT(locs);
- // Ensure lengths of all arrays are the same:
- WWASSERT(!diffuse || locs->Get_Count() == diffuse->Get_Count());
- WWASSERT(!apt || locs->Get_Count() == apt->Get_Count());
- WWASSERT(!sizes || locs->Get_Count() == sizes->Get_Count());
- WWASSERT(!orientations || locs->Get_Count() == orientations->Get_Count());
- WWASSERT(!frames || locs->Get_Count() == frames->Get_Count());
- REF_PTR_SET(PointLoc,locs);
- REF_PTR_SET(PointDiffuse,diffuse);
- REF_PTR_SET(APT,apt);
- REF_PTR_SET(PointSize,sizes);
- REF_PTR_SET(PointOrientation,orientations);
- REF_PTR_SET(PointFrame,frames);
- if (APT) {
- PointCount = active_point_count;
- } else {
- PointCount = (active_point_count >= 0) ? active_point_count : PointLoc->Get_Count();
- }
- // Store view plane rectangle (only used in SCREENSPACE mode)
- VPXMin = vpxmin;
- VPYMin = vpymin;
- VPXMax = vpxmax;
- VPYMax = vpymax;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Size -- Set default point size. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This size is ignored if a size array is present. *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Size(float size)
- {
- DefaultPointSize = size;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Size -- Get default point size. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This size is ignored if a size array is present. *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- float PointGroupClass::Get_Point_Size(void)
- {
- return DefaultPointSize;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Color -- Set default point color. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This color is ignored if a color array is present. *
- * *
- * HISTORY: *
- * 04/20/1999 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Color(Vector3 color)
- {
- DefaultPointColor = color;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Color -- Get default point color. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This color is ignored if a color array is present. *
- * *
- * HISTORY: *
- * 04/20/1999 NH : Created. *
- *========================================================================*/
- Vector3 PointGroupClass::Get_Point_Color(void)
- {
- return DefaultPointColor;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Alpha -- Set default point alpha. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This alpha is ignored if an alpha array is present. *
- * *
- * HISTORY: *
- * 08/25/1999 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Alpha(float alpha)
- {
- DefaultPointAlpha = alpha;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Alpha -- Get default point alpha. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This alpha is ignored if an alpha array is present. *
- * *
- * HISTORY: *
- * 08/25/1999 NH : Created. *
- *========================================================================*/
- float PointGroupClass::Get_Point_Alpha(void)
- {
- return DefaultPointAlpha;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Orientation -- Set default point orientation*
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This is ignored if an orientation array is present. *
- * *
- * NOTE: No need to ensure value in valid range - it will be masked later.*
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Orientation(unsigned char orientation)
- {
- DefaultPointOrientation = orientation;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Orientation -- Get default point orientation*
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This is ignored if an orientation array is present. *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- unsigned char PointGroupClass::Get_Point_Orientation(void)
- {
- return DefaultPointOrientation;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Frame -- Set default point frame. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This frame is ignored if an frame array is present. *
- * *
- * NOTE: No need to ensure value in valid range - it will be masked later.*
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Frame(unsigned char frame)
- {
- DefaultPointFrame = frame;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Frame -- Get default point frame. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: This frame is ignored if an frame array is present. *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- unsigned char PointGroupClass::Get_Point_Frame(void)
- {
- return DefaultPointFrame;
- }
- /**************************************************************************
- * PointGroupClass::Set_Point_Mode -- Set point rendering method. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Point_Mode(PointModeEnum mode)
- {
- PointMode = mode;
- }
- /**************************************************************************
- * PointGroupClass::Get_Point_Mode -- Get point rendering method. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- PointGroupClass::PointModeEnum PointGroupClass::Get_Point_Mode(void)
- {
- return PointMode;
- }
- /**************************************************************************
- * Set_Flag -- PointGroupClass::Set given flag to on or off. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Flag(FlagsType flag, bool onoff)
- {
- if (onoff) Flags|=1<<flag;
- else
- Flags&=~(1<<flag);
- }
- /**************************************************************************
- * PointGroupClass::Get_Flag -- Get current value (on/off) of given flag. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- int PointGroupClass::Get_Flag(FlagsType flag)
- {
- return (Flags>>flag) & 0x1;
- }
- /**************************************************************************
- * PointGroupClass::Set_Texture -- Set texture used. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- void PointGroupClass::Set_Texture(TextureClass* texture)
- {
- REF_PTR_SET(Texture,texture);
- }
- /**************************************************************************
- * PointGroupClass::Get_Texture -- Get texture used. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- TextureClass * PointGroupClass::Get_Texture(void)
- {
- if (Texture) Texture->Add_Ref();
- return Texture;
- }
- /***********************************************************************************************
- * PointGroupClass::Peek_Texture -- Peeks texture *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/12/2001 hy : Created. *
- *=============================================================================================*/
- TextureClass * PointGroupClass::Peek_Texture(void)
- {
- return Texture;
- }
- /**************************************************************************
- * PointGroupClass::Set_Shader -- Set shader used. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: the primary gradient will be set to MODULATE/DISABLE in *
- * the shader depending on whether a color or alpha array was *
- * passed in Set_Point_Arrays. also, texturing will be *
- * enabled or disabled dependent on whether a non-NULL *
- * texture was set. *
- * these will override the primary gradient/texturing *
- * settings in the given shader. *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- void PointGroupClass::Set_Shader(ShaderClass shader)
- {
- Shader = shader;
- }
- /**************************************************************************
- * PointGroupClass::Get_Shader -- Get shader used. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- ShaderClass PointGroupClass::Get_Shader(void)
- {
- return Shader;
- }
- /**************************************************************************
- * PointGroupClass::Set_Billboard -- Set whether to Billboard. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 04/25/2002 JM : Created. *
- *========================================================================*/
- void PointGroupClass::Set_Billboard(bool shouldBillboard)
- {
- Billboard = shouldBillboard;
- }
- /**************************************************************************
- * PointGroupClass::Get_Billboard -- Get whether to Billboard. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 04/25/2002 JM : Created. *
- *========================================================================*/
- bool PointGroupClass::Get_Billboard(void)
- {
- return Billboard;
- }
- /**************************************************************************
- * PointGroupClass::Get_Frame_Row_Column_Count_Log2 -- what it says *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- unsigned char PointGroupClass::Get_Frame_Row_Column_Count_Log2(void)
- {
- return FrameRowColumnCountLog2;
- }
- /**************************************************************************
- * PointGroupClass::Set_Frame_Row_Column_Count_Log2 -- what it says. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- void PointGroupClass::Set_Frame_Row_Column_Count_Log2(unsigned char frccl2)
- {
- FrameRowColumnCountLog2 = MIN(frccl2, 4);
- }
- /**************************************************************************
- * PointGroupClass::Get_Polygon_Count -- Get estimated polygon count. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/18/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- int PointGroupClass::Get_Polygon_Count(void)
- {
- switch (PointMode) {
- case TRIS:
- case SCREENSPACE:
- return PointCount;
- break;
- case QUADS:
- return PointCount * 2;
- break;
- }
- WWASSERT(0);
- return 0;
- }
- /**************************************************************************
- * PointGroupClass::Render -- draw point group. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/10/1998 NH : Created. *
- * 02/08/2001 HY : Upgraded to DX8 *
- *========================================================================*/
- static SimpleVecClass<unsigned long> remap;
- void PointGroupClass::Render(RenderInfoClass &rinfo)
- {
- /// @todo lorenzen asks: is particle culling in the shader perhaps faster than in DoParticles? Fix winding and find out...
- // NB: the winding for pointgroups is wrong, but we
- // are disabling culling for particles anyway
- Shader.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE);
- // If no points, do nothing:
- if (PointCount == 0) return;
- WWASSERT(PointLoc && PointLoc->Get_Array());
- // Process texture reductions:
- // if (Texture) Texture->Process_Reduction();
- // Pointers which point into existing buffers (member or static):
- Vector3 *current_loc = NULL;
- Vector4 *current_diffuse = NULL;
- float *current_size = NULL;
- unsigned char *current_orient = NULL;
- unsigned char *current_frame = NULL;
- // If there is a color or alpha array enable gradient in shader - otherwise disable.
- float value_255 = 0.9961f; //254 / 255
- bool default_white_opaque = ( DefaultPointColor.X > value_255 &&
- DefaultPointColor.Y > value_255 &&
- DefaultPointColor.Z > value_255 &&
- DefaultPointAlpha > value_255);
- // The reason we check for lack of texture here is that SR seems to render black triangles
- // rather than white triangles as would be expected) when there is no texture AND no gradient.
- if (PointDiffuse || !default_white_opaque || !Texture) {
- Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_MODULATE);
- } else {
- Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_DISABLE);
- }
- // If Texture is non-NULL enable texturing in shader - otherwise disable.
- if (Texture) {
- Shader.Set_Texturing(ShaderClass::TEXTURING_ENABLE);
- } else {
- Shader.Set_Texturing(ShaderClass::TEXTURING_DISABLE);
- }
- // If there is an active point table, use it to compress the point
- // locations/colors/alphas/sizes/orientations/frames.
- if (APT) {
- // Resize compressed result arrays if needed (2x guardband to prevent
- // frequent reallocations):
- /// @todo lorenzen sez: precompute pointers to indexed array elements, below
- if (compressed_loc.Length() < PointCount) {
- compressed_loc.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_loc[0],
- PointLoc->Get_Array(), APT->Get_Array(), PointCount);
- current_loc = &compressed_loc[0];
- if (PointDiffuse) {
- if (compressed_diffuse.Length() < PointCount) {
- compressed_diffuse.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_diffuse[0],
- PointDiffuse->Get_Array(), APT->Get_Array(), PointCount);
- current_diffuse = &compressed_diffuse[0];
- }
- if (PointSize) {
- if (compressed_size.Length() < PointCount) {
- compressed_size.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_size[0],
- PointSize->Get_Array(), APT->Get_Array(), PointCount);
- current_size = &compressed_size[0];
- }
- if (PointOrientation) {
- if (compressed_orient.Length() < PointCount) {
- compressed_orient.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_orient[0],
- PointOrientation->Get_Array(), APT->Get_Array(), PointCount);
- current_orient = &compressed_orient[0];
- }
- if (PointFrame) {
- if (compressed_frame.Length() < PointCount) {
- compressed_frame.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_frame[0],
- PointFrame->Get_Array(), APT->Get_Array(), PointCount);
- current_frame = &compressed_frame[0];
- }
- } else {
- current_loc = PointLoc->Get_Array();
- if (PointDiffuse) {
- current_diffuse = PointDiffuse->Get_Array();
- }
- if (PointSize) {
- current_size = PointSize->Get_Array();
- }
- if (PointOrientation) {
- current_orient = PointOrientation->Get_Array();
- }
- if (PointFrame) {
- current_frame = PointFrame->Get_Array();
- }
- }
- // Get the world and view matrices
- Matrix4x4 view;
- DX8Wrapper::Get_Transform(D3DTS_VIEW,view);
- // Transform the point locations from worldspace to camera space if needed
- // (i.e. if they are not already in camera space):
- // need to interrupt this processing. If we are not billboarding, then we need the actual position
- // of the vertice to lay it down flat.
-
- // (gth) changed this 'if' to use OR rather than AND... The way it was caused all emitters to break
- if (Get_Flag(TRANSFORM) && Billboard) {
- // Resize transformed location array if needed (2x guardband to prevent
- // frequent reallocations):
- if (transformed_loc.Length() < PointCount) {
- transformed_loc.Resize(PointCount * 2);
- }
- // Not using vector processor class because we are discarding w
- // Not using T&L in DX8 because we don't want DX8 to transform
- // 3 times per particle when we can do it once
- for (int i=0; i<PointCount; i++)
- {
- /// @todo lorenzen sez: use pointer arithmetic here and a fast while loop
- Vector4 result=view*current_loc[i];
- transformed_loc[i].X=result.X;
- transformed_loc[i].Y=result.Y;
- transformed_loc[i].Z=result.Z;
- }
- current_loc = &transformed_loc[0];
- } // if transform
- // Update the arrays with the offsets.
- int vnum, pnum;
- Update_Arrays(current_loc, current_diffuse, current_size, current_orient, current_frame,
- PointCount, PointLoc->Get_Count(), vnum, pnum);
- // the locations are now in view space
- // so set world and view matrices to identity and render
-
- Matrix4x4 identity(true);
- DX8Wrapper::Set_Transform(D3DTS_WORLD,identity);
- DX8Wrapper::Set_Transform(D3DTS_VIEW,identity);
- DX8Wrapper::Set_Material(PointMaterial);
- DX8Wrapper::Set_Shader(Shader);
- DX8Wrapper::Set_Texture(0,Texture);
- // Enable sorting if the primitives are translucent and alpha testing is not enabled.
- const bool sort = (Shader.Get_Dst_Blend_Func() != ShaderClass::DSTBLEND_ZERO) && (Shader.Get_Alpha_Test() == ShaderClass::ALPHATEST_DISABLE) && (WW3D::Is_Sorting_Enabled());
- IndexBufferClass *indexbuffer;
- int verticesperprimitive;/// lorenzen fixed
- int current;
- int delta;
- /// @todo lorenzen sez: if tri-based particles are not supported, elim this test
- if (PointMode == QUADS) {
- verticesperprimitive = 2;
- indexbuffer = sort ? static_cast <IndexBufferClass*> (SortingQuads) : static_cast <IndexBufferClass*> (Quads);
- } else {
- verticesperprimitive = 3;
- indexbuffer = sort ? static_cast <IndexBufferClass*> (SortingTris) : static_cast <IndexBufferClass*> (Tris);
- }
- current = 0;
- while (current<vnum)
- {
- delta=MIN(vnum-current,MAX_VB_SIZE);
- DynamicVBAccessClass PointVerts (sort ? BUFFER_TYPE_DYNAMIC_SORTING : BUFFER_TYPE_DYNAMIC_DX8, dynamic_fvf_type, delta);
- // Copy in the data to the VB
- {
- DynamicVBAccessClass::WriteLockClass Lock(&PointVerts);
- int i;
- unsigned char *vb=(unsigned char*)Lock.Get_Formatted_Vertex_Array();
- const FVFInfoClass& fvfinfo=PointVerts.FVF_Info();
- for (i = current; i < current + delta; i++)
- {
- /// @todo lorenzen sez: use pointer arithmetic throughout this block
- /// @todo lorenzen sez: delare thes locals outside this loop
- /// @todo lorenzen sez: use a fast while loop
- // Copy Locations
- *(Vector3*)(vb+fvfinfo.Get_Location_Offset())=VertexLoc[i];
- if (current_diffuse) {
- unsigned color=DX8Wrapper::Convert_Color_Clamp(VertexDiffuse[i]);
- *(unsigned int*)(vb+fvfinfo.Get_Diffuse_Offset())=color;
- }
- else
- *(unsigned int*)(vb+fvfinfo.Get_Diffuse_Offset())=
- DX8Wrapper::Convert_Color_Clamp(Vector4(DefaultPointColor[0],DefaultPointColor[1],DefaultPointColor[2],DefaultPointAlpha));
- *(Vector2*)(vb+fvfinfo.Get_Tex_Offset(0))=VertexUV[i];
- vb+=fvfinfo.Get_FVF_Size();
- }
- } // copy
- DX8Wrapper::Set_Index_Buffer (indexbuffer, 0);
- DX8Wrapper::Set_Vertex_Buffer (PointVerts);
-
- if ( sort )
- {
- SortingRendererClass::Insert_Triangles (0, delta / verticesperprimitive, 0, delta);
- }
- else
- {
- DX8Wrapper::Draw_Triangles (0, delta / verticesperprimitive, 0, delta);
- }
-
- current+=delta;
- } // loop while (current<vnum)
- // restore the matrices
- DX8Wrapper::Set_Transform(D3DTS_VIEW,view);
- }
- /**************************************************************************
- * PointGroupClass::Update_Arrays -- Update all arrays used in rendering *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 11/17/1998 NH : Created. *
- *========================================================================*/
- void PointGroupClass::Update_Arrays(
- Vector3 *point_loc,
- Vector4 *point_diffuse,
- float *point_size,
- unsigned char *point_orientation,
- unsigned char *point_frame,
- int active_points,
- int total_points,
- int &vnum,
- int &pnum)
- {
- int verts_per_point = (PointMode == QUADS) ? 4 : 3;
- int polys_per_point = (PointMode == QUADS) ? 2 : 1;
- // total_vnum/pnum reflect the size of the point arrays passed to the
- // point group. These (instead of vnum/pnum, which reflect the number of
- // active points) are used for the resize logic - the idea is that these
- // numbers will vary less often than the active numbers.
- int total_vnum = verts_per_point * total_points;
- vnum = verts_per_point * active_points;
- pnum = polys_per_point * active_points;
-
- // Resize the arrays if they are too small. We only need to check the length of one array
- // since they always all have the same length.
- /// @todo lorenzen sez: precompute params below
- if (VertexLoc.Length() < total_vnum) {
- // Resize arrays (2x guardband to prevent frequent reallocations).
- VertexLoc.Resize(total_vnum * 2, false);
- VertexUV.Resize(total_vnum * 2, false);
- VertexDiffuse.Resize(total_vnum * 2, false);
- }
- int vert, i, j;
- /*
- ** Generate the vertex locations from the point locations (note that both are in camera space).
- ** Vertex locations depend on the point mode and the points' orientation and size
- */
- // This defines the loop we run: the LSB indicates whether there is a size override array, the
- // next bit indicates whether there is an orientation override array, and the higher bits
- // indicate the point mode.
- enum LoopSelectionEnum {
- TRIS_NOSIZE_NOORIENT = ((int)TRIS << 2) + 0,
- TRIS_SIZE_NOORIENT = ((int)TRIS << 2) + 1,
- TRIS_NOSIZE_ORIENT = ((int)TRIS << 2) + 2,
- TRIS_SIZE_ORIENT = ((int)TRIS << 2) + 3,
- QUADS_NOSIZE_NOORIENT = ((int)QUADS << 2) + 0,
- QUADS_SIZE_NOORIENT = ((int)QUADS << 2) + 1,
- QUADS_NOSIZE_ORIENT = ((int)QUADS << 2) + 2,
- QUADS_SIZE_ORIENT = ((int)QUADS << 2) + 3,
- SCREEN_NOSIZE_NOORIENT = ((int)SCREENSPACE << 2) + 0,
- SCREEN_SIZE_NOORIENT = ((int)SCREENSPACE << 2) + 1,
- SCREEN_NOSIZE_ORIENT = ((int)SCREENSPACE << 2) + 2,
- SCREEN_SIZE_ORIENT = ((int)SCREENSPACE << 2) + 3,
- };
- LoopSelectionEnum loop_sel = (LoopSelectionEnum)(((int)PointMode << 2) +
- (point_orientation ? 2 : 0) + (point_size ? 1 : 0));
- vert = 0;
- Vector3 *vertex_loc = &VertexLoc[0];
- /// @todo lorenzen sez: this switch statement may be done more compactly another way... look into it
- switch (loop_sel) {
- case TRIS_NOSIZE_NOORIENT:
- {
- // Setup constant vertex offsets (since size and orientation are invariants)
- Vector3 scaled_offset[3];
- scaled_offset[0] = _TriVertexLocationOrientationTable[DefaultPointOrientation][0] * DefaultPointSize;
- scaled_offset[1] = _TriVertexLocationOrientationTable[DefaultPointOrientation][1] * DefaultPointSize;
- scaled_offset[2] = _TriVertexLocationOrientationTable[DefaultPointOrientation][2] * DefaultPointSize;
- // Add vertex offsets to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] + scaled_offset[0];
- vertex_loc[vert + 1] = point_loc[i] + scaled_offset[1];
- vertex_loc[vert + 2] = point_loc[i] + scaled_offset[2];
- vert += 3;
- }
- }
- break;
- case TRIS_SIZE_NOORIENT:
- {
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] +
- _TriVertexLocationOrientationTable[DefaultPointOrientation][0] * point_size[i];
- vertex_loc[vert + 1] = point_loc[i] +
- _TriVertexLocationOrientationTable[DefaultPointOrientation][1] * point_size[i];
- vertex_loc[vert + 2] = point_loc[i] +
- _TriVertexLocationOrientationTable[DefaultPointOrientation][2] * point_size[i];
- vert += 3;
- }
- }
- break;
- case TRIS_NOSIZE_ORIENT:
- {
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][0] * DefaultPointSize;
- vertex_loc[vert + 1] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][1] * DefaultPointSize;
- vertex_loc[vert + 2] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][2] * DefaultPointSize;
- vert += 3;
- }
- }
- break;
- case TRIS_SIZE_ORIENT:
- {
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][0] * point_size[i];
- vertex_loc[vert + 1] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][1] * point_size[i];
- vertex_loc[vert + 2] = point_loc[i] +
- _TriVertexLocationOrientationTable[point_orientation[i]][2] * point_size[i];
- vert += 3;
- }
- }
- break;
- case QUADS_NOSIZE_NOORIENT:
- {
- // Setup constant vertex offsets (since size and orientation are invariants)
- Vector3 scaled_offset[4];
- scaled_offset[0] = _QuadVertexLocationOrientationTable[DefaultPointOrientation][0] * DefaultPointSize;
- scaled_offset[1] = _QuadVertexLocationOrientationTable[DefaultPointOrientation][1] * DefaultPointSize;
- scaled_offset[2] = _QuadVertexLocationOrientationTable[DefaultPointOrientation][2] * DefaultPointSize;
- scaled_offset[3] = _QuadVertexLocationOrientationTable[DefaultPointOrientation][3] * DefaultPointSize;
- // Add vertex offsets to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] + scaled_offset[0];
- vertex_loc[vert + 1] = point_loc[i] + scaled_offset[1];
- vertex_loc[vert + 2] = point_loc[i] + scaled_offset[2];
- vertex_loc[vert + 3] = point_loc[i] + scaled_offset[3];
- vert += 4;
- }
- }
- break;
- case QUADS_SIZE_NOORIENT:
- {
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] +
- _QuadVertexLocationOrientationTable[DefaultPointOrientation][0] * point_size[i];
- vertex_loc[vert + 1] = point_loc[i] +
- _QuadVertexLocationOrientationTable[DefaultPointOrientation][1] * point_size[i];
- vertex_loc[vert + 2] = point_loc[i] +
- _QuadVertexLocationOrientationTable[DefaultPointOrientation][2] * point_size[i];
- vertex_loc[vert + 3] = point_loc[i] +
- _QuadVertexLocationOrientationTable[DefaultPointOrientation][3] * point_size[i];
- vert += 4;
- }
- }
- break;
- case QUADS_NOSIZE_ORIENT:
- {
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][0] * DefaultPointSize;
- vertex_loc[vert + 1] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][1] * DefaultPointSize;
- vertex_loc[vert + 2] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][2] * DefaultPointSize;
- vertex_loc[vert + 3] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][3] * DefaultPointSize;
- vert += 4;
- }
- }
- break;
- case QUADS_SIZE_ORIENT:
- {
- Matrix4x4 view;
- Vector4 result;
- if (!Billboard) {
- DX8Wrapper::Get_Transform(D3DTS_VIEW,view);
- }
- // Scale vertex offsets and add them to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- if (!Billboard) {
- // If we're not billboarding, then the coordinate we have is in screen space.
- Matrix4x4 rotMat;
- D3DXMatrixRotationZ(&(D3DXMATRIX&) rotMat, ((float)point_orientation[i] / 255.0f * 2 * D3DX_PI));
-
- Vector4 orientedVecX = rotMat * GroundMultiplierX;
- Vector4 orientedVecY = rotMat * GroundMultiplierY;
- vertex_loc[vert + 0].X = point_loc[i].X + (orientedVecX.X + orientedVecY.X) * point_size[i];
- vertex_loc[vert + 0].Y = point_loc[i].Y + (orientedVecX.Y + orientedVecY.Y) * point_size[i];
- vertex_loc[vert + 0].Z = point_loc[i].Z;
- vertex_loc[vert + 1].X = point_loc[i].X + (orientedVecX.X - orientedVecY.X) * point_size[i];
- vertex_loc[vert + 1].Y = point_loc[i].Y + (orientedVecX.Y - orientedVecY.Y) * point_size[i];
- vertex_loc[vert + 1].Z = point_loc[i].Z;
- vertex_loc[vert + 2].X = point_loc[i].X + -(orientedVecX.X + orientedVecY.X) * point_size[i];
- vertex_loc[vert + 2].Y = point_loc[i].Y + -(orientedVecX.Y + orientedVecY.Y) * point_size[i];
- vertex_loc[vert + 2].Z = point_loc[i].Z;
- vertex_loc[vert + 3].X = point_loc[i].X + (-orientedVecX.X + orientedVecY.X) * point_size[i];
- vertex_loc[vert + 3].Y = point_loc[i].Y + (-orientedVecX.Y + orientedVecY.Y) * point_size[i];
- vertex_loc[vert + 3].Z = point_loc[i].Z;
- // now apply the view transform so that this data is in the format expected
- // upon the functions return.
- result = view*vertex_loc[vert + 0];
- vertex_loc[vert + 0].X = result.X;
- vertex_loc[vert + 0].Y = result.Y;
- vertex_loc[vert + 0].Z = result.Z;
- result = view*vertex_loc[vert + 1];
- vertex_loc[vert + 1].X = result.X;
- vertex_loc[vert + 1].Y = result.Y;
- vertex_loc[vert + 1].Z = result.Z;
- result = view*vertex_loc[vert + 2];
- vertex_loc[vert + 2].X = result.X;
- vertex_loc[vert + 2].Y = result.Y;
- vertex_loc[vert + 2].Z = result.Z;
- result = view*vertex_loc[vert + 3];
- vertex_loc[vert + 3].X = result.X;
- vertex_loc[vert + 3].Y = result.Y;
- vertex_loc[vert + 3].Z = result.Z;
- } else {
- vertex_loc[vert + 0] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][0] * point_size[i];
- vertex_loc[vert + 1] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][1] * point_size[i];
- vertex_loc[vert + 2] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][2] * point_size[i];
- vertex_loc[vert + 3] = point_loc[i] +
- _QuadVertexLocationOrientationTable[point_orientation[i]][3] * point_size[i];
- }
- vert += 4;
- }
- }
- break;
- // Orientations are ignored for screensize pointgroups
- case SCREEN_NOSIZE_NOORIENT:
- case SCREEN_NOSIZE_ORIENT:
- {
- // Offsets need to be scaled to the current screen resolution
- // First find x and y scale factors (sizes in pixels need to be
- // normalized to 2D cam viewplane of -1,-1 to 1,1)
- int xres, yres, bitdepth;
- bool windowed;
- WW3D::Get_Render_Target_Resolution(xres, yres, bitdepth, windowed);
-
- float x_scale = (VPXMax - VPXMin) / xres;
- float y_scale = (VPYMax - VPYMin) / yres;
-
- Vector3 scaled_locs[2][3];
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < 3; j++) {
- scaled_locs[i][j].X = _ScreenspaceVertexLocationSizeTable[i][j].X * x_scale;
- scaled_locs[i][j].Y = _ScreenspaceVertexLocationSizeTable[i][j].Y * y_scale;
- scaled_locs[i][j].Z = _ScreenspaceVertexLocationSizeTable[i][j].Z;
- }
- }
- // Add vertex offsets to point locations to get vertex locations
- int size_idx = (DefaultPointSize <= 1.0f) ? 0 : 1;
- for (i = 0; i < active_points; i++) {
- vertex_loc[vert + 0] = point_loc[i] + scaled_locs[size_idx][0];
- vertex_loc[vert + 1] = point_loc[i] + scaled_locs[size_idx][1];
- vertex_loc[vert + 2] = point_loc[i] + scaled_locs[size_idx][2];
- vert += 3;
- }
- }
- break;
-
- case SCREEN_SIZE_NOORIENT:
- case SCREEN_SIZE_ORIENT:
- {
- // Offsets need to be scaled to the current screen resolution
- // First find x and y scale factors (sizes in pixels need to be
- // normalized to 2D cam viewplane of -1,-1 to 1,1)
- int xres, yres, bitdepth;
- bool windowed;
- WW3D::Get_Render_Target_Resolution(xres, yres, bitdepth, windowed);
-
- float x_scale = (VPXMax - VPXMin) / xres;
- float y_scale = (VPYMax - VPYMin) / yres;
-
- Vector3 scaled_locs[2][3];
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < 3; j++) {
- scaled_locs[i][j].X = _ScreenspaceVertexLocationSizeTable[i][j].X * x_scale;
- scaled_locs[i][j].Y = _ScreenspaceVertexLocationSizeTable[i][j].Y * y_scale;
- scaled_locs[i][j].Z = _ScreenspaceVertexLocationSizeTable[i][j].Z;
- }
- }
- // Add vertex offsets to point locations to get vertex locations
- for (i = 0; i < active_points; i++) {
- int size_idx = (point_size[i] <= 1.0f) ? 0 : 1;
- vertex_loc[vert + 0] = point_loc[i] + scaled_locs[size_idx][0];
- vertex_loc[vert + 1] = point_loc[i] + scaled_locs[size_idx][1];
- vertex_loc[vert + 2] = point_loc[i] + scaled_locs[size_idx][2];
- vert += 3;
- }
- }
- break;
- default:
- WWASSERT(0);
- break;
- }
- /*
- ** Fill the UV vertex array
- */
- unsigned int frame_mask = ~(0xFFFFFFFF << (FrameRowColumnCountLog2 + FrameRowColumnCountLog2));// To ensure frames in range
- if (point_frame) {
- /// @todo lorenzen sez: use pointer arithmetic below
- // Fill UV array according to frame override array:
- Vector2 *vertex_uv = &VertexUV[0];
- if (PointMode != QUADS) {
- // Modes with three vertices per point:
- Vector2 *uv_ptr = _TriVertexUVFrameTable[FrameRowColumnCountLog2];
- int vert = 0;
- for (int i = 0; i < active_points; i++) {
- int uv_idx = (point_frame[i] & frame_mask) * 3;
- vertex_uv[vert++] = uv_ptr[uv_idx + 0];
- vertex_uv[vert++] = uv_ptr[uv_idx + 1];
- vertex_uv[vert++] = uv_ptr[uv_idx + 2];
- }
- } else {
- // Modes with four vertices per point:
- Vector2 *uv_ptr = _QuadVertexUVFrameTable[FrameRowColumnCountLog2];
- int vert = 0;
- for (int i = 0; i < active_points; i++) {
- int uv_idx = (point_frame[i] & frame_mask) * 4;
- vertex_uv[vert++] = uv_ptr[uv_idx + 0];
- vertex_uv[vert++] = uv_ptr[uv_idx + 1];
- vertex_uv[vert++] = uv_ptr[uv_idx + 2];
- vertex_uv[vert++] = uv_ptr[uv_idx + 3];
- }
- }
- } else {
- /// @todo lorenzen sez: use pointer arithmetic below
- // Fill UV array according to frame state:
- Vector2 *vertex_uv = &VertexUV[0];
- if (PointMode != QUADS) {
- // Modes with three vertices per point:
- Vector2 *uv_ptr = _TriVertexUVFrameTable[FrameRowColumnCountLog2] + ((DefaultPointFrame & frame_mask) * 3);
- int vert = 0;
- for (int i = 0; i < active_points; i++) {
- vertex_uv[vert++] = uv_ptr[0];
- vertex_uv[vert++] = uv_ptr[1];
- vertex_uv[vert++] = uv_ptr[2];
- }
- } else {
- // Modes with four vertices per point:
- Vector2 *uv_ptr = _QuadVertexUVFrameTable[FrameRowColumnCountLog2] + ((DefaultPointFrame & frame_mask) * 4);
- int vert = 0;
- for (int i = 0; i < active_points; i++) {
- vertex_uv[vert++] = uv_ptr[0];
- vertex_uv[vert++] = uv_ptr[1];
- vertex_uv[vert++] = uv_ptr[2];
- vertex_uv[vert++] = uv_ptr[3];
- }
- }
- }
- /*
- ** If we have a point color array, fill the vertex diffuse array from it.
- */
- /// @todo lorenzen sez: use a quicker, unwrapped loop, and pointer arithmetic
- /// @todo lorenzen sez: this is a leaf function, dang it
- vert = 0;
- if (point_diffuse) {
- Vector4* vertex_color = &VertexDiffuse[0];
- for (i = 0; i < active_points; i++) {
- for (j = 0; j < verts_per_point; j++) {
- vertex_color[vert + j] = point_diffuse[i];
- }
- vert += verts_per_point;
- }
- }
- }
- /**************************************************************************
- * PointGroupClass::_Init -- Create static data. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- void PointGroupClass::_Init(void)
- {
- int i, j;
- /*
- ** Fill vertex location orientation tables
- */
- // Unrotated locations
- Vector3 tri_locs[3] = {
- Vector3(0.0f, -2.0f, 0.0f),
- Vector3(-1.732f, 1.0f, 0.0f),
- Vector3(1.732f, 1.0f, 0.0f)
- };
- Vector3 quad_locs[4] = {
- Vector3(-0.5f, 0.5f, 0.0f),
- Vector3(-0.5f, -0.5f, 0.0f),
- Vector3(0.5f, -0.5f, 0.0f),
- Vector3(0.5f, 0.5f, 0.0f)
- };
- /// @todo lorenzen sez: unwrap loop and use pointer arithmetic (if this gets called a lot)
- float angle = 0.0f; // In radians
- float angle_step = (WWMATH_PI * 2.0f) / 256.0f; // In radians
- for (i = 0; i < 256; i++) {
- float c = WWMath::Fast_Cos(angle);
- float s = WWMath::Fast_Sin(angle);
- for (j = 0; j < 3; j++) {
- _TriVertexLocationOrientationTable[i][j].X = tri_locs[j].X * c - tri_locs[j].Y * s;
- _TriVertexLocationOrientationTable[i][j].Y = tri_locs[j].X * s + tri_locs[j].Y * c;
- _TriVertexLocationOrientationTable[i][j].Z = tri_locs[j].Z;
- }
- for (j = 0; j < 4; j++) {
- _QuadVertexLocationOrientationTable[i][j].X = quad_locs[j].X * c - quad_locs[j].Y * s;
- _QuadVertexLocationOrientationTable[i][j].Y = quad_locs[j].X * s + quad_locs[j].Y * c;
- _QuadVertexLocationOrientationTable[i][j].Z = quad_locs[j].Z;
- }
- angle += angle_step;
- }
- /*
- ** Fill frame UV tables
- */
- // Unscaled / untranslated UVs
- Vector2 tri_uvs[3] = {
- Vector2(0.5f, 0.0f),
- Vector2(0.0f, 0.866f),
- Vector2(1.0f, 0.866f)
- };
- Vector2 quad_uvs[4] = {
- Vector2(0.0f, 0.0f),
- Vector2(0.0f, 1.0f),
- Vector2(1.0f, 1.0f),
- Vector2(1.0f, 0.0f)
- };
- /// @todo lorenzen sez: umwrap and use pointers
- for (i = 0; i < 5; i++) {
- unsigned int rows = 1 << i;
- unsigned int count = rows * rows;
- Vector2 *tri_table = _TriVertexUVFrameTable[i] = W3DNEWARRAY Vector2[count * 3];
- Vector2 *quad_table = _QuadVertexUVFrameTable[i] = W3DNEWARRAY Vector2[count * 4];
- Vector2 corner(0.0f, 0.0f);
- float scale = 1.0f / (float)rows;
- int tri_idx = 0;
- int quad_idx = 0;
- for (unsigned int v = 0; v < rows; v++) {
- for (unsigned int u = 0; u < rows; u++) {
- tri_table[tri_idx++] = corner + (tri_uvs[0] * scale);
- tri_table[tri_idx++] = corner + (tri_uvs[1] * scale);
- tri_table[tri_idx++] = corner + (tri_uvs[2] * scale);
- quad_table[quad_idx++] = corner + (quad_uvs[0] * scale);
- quad_table[quad_idx++] = corner + (quad_uvs[1] * scale);
- quad_table[quad_idx++] = corner + (quad_uvs[2] * scale);
- quad_table[quad_idx++] = corner + (quad_uvs[3] * scale);
- corner.X += scale;
- }
- corner.Y += scale;
- corner.X = 0.0f;
- }
- }
- // Create the IBs
- Tris=NEW_REF(DX8IndexBufferClass,(MAX_TRI_IB_SIZE));
- Quads=NEW_REF(DX8IndexBufferClass,(MAX_QUAD_IB_SIZE));
- SortingTris=NEW_REF(SortingIndexBufferClass,(MAX_TRI_IB_SIZE));
- SortingQuads=NEW_REF(SortingIndexBufferClass,(MAX_QUAD_IB_SIZE));
- // Fill up the IBs
- {
- DX8IndexBufferClass::WriteLockClass locktris(Tris);
- unsigned short *ib=locktris.Get_Index_Array();
- for (i=0; i<MAX_TRI_IB_SIZE; i++) ib[i]=(unsigned short) i;
- }
- {
- unsigned short vert=0;
- DX8IndexBufferClass::WriteLockClass lockquads(Quads);
- unsigned short *ib=lockquads.Get_Index_Array();
- vert=0;
- for (i=0; i<MAX_QUAD_IB_SIZE; i+=6)
- {
- /// @todo lorenzen sez: pointer arithmetic like "++ib=vert+1"
- ib[i]=vert;
- ib[i+1]=vert+1;
- ib[i+2]=vert+2;
-
- ib[i+3]=vert+2;
- ib[i+4]=vert+3;
- ib[i+5]=vert;
- vert+=4;
- }
- }
- {
- SortingIndexBufferClass::WriteLockClass locktris(SortingTris);
- unsigned short *ib=locktris.Get_Index_Array();
- for (i=0; i<MAX_TRI_IB_SIZE; i++) ib[i]=(unsigned short) i;
- }
- {
- unsigned short vert=0;
- SortingIndexBufferClass::WriteLockClass lockquads(SortingQuads);
- unsigned short *ib=lockquads.Get_Index_Array();
- vert=0;
- for (i=0; i<MAX_QUAD_IB_SIZE; i+=6)
- {
- /// @todo lorenzen sez: pointers!
- ib[i]=vert;
- ib[i+1]=vert+1;
- ib[i+2]=vert+2;
-
- ib[i+3]=vert+2;
- ib[i+4]=vert+3;
- ib[i+5]=vert;
- vert+=4;
- }
- }
- PointMaterial=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- }
- /**************************************************************************
- * PointGroupClass::_Shutdown -- Destroy static data. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 06/28/2000 NH : Created. *
- *========================================================================*/
- void PointGroupClass::_Shutdown(void)
- {
- for (int i = 0; i < 5; i++) {
- delete [] _TriVertexUVFrameTable[i];
- delete [] _QuadVertexUVFrameTable[i];
- }
- REF_PTR_RELEASE(PointMaterial);
- REF_PTR_RELEASE(SortingQuads);
- REF_PTR_RELEASE(SortingTris);
- REF_PTR_RELEASE(Quads);
- REF_PTR_RELEASE(Tris);
- transformed_loc.Clear();
- VertexLoc.Clear();
- VertexDiffuse.Clear();
- VertexUV.Clear();
- }
- /**************************************************************************
- * PointGroupClass::RenderVolumeParticles -- draw a point group.sandwich *
- * *
- * This is a specialized renderer. It will draw the particle repeatedly *
- * while attenuating opacity appropriately, and bumping the z-position. *
- * This is actually done by cloning the particle over and over at *
- * successively closer positions to the camera. Very Slow! *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: USE SPARINGLY, IT IS EXPENSIVE!!!!! *
- * *
- * HISTORY: *
- * 12/03/2002 Mark Lorenzen Created. *
- * *
- *========================================================================*/
- #define MAX_VOLUME_PARTICLE_DEPTH ( 16 )
- void PointGroupClass::RenderVolumeParticle(RenderInfoClass &rinfo, unsigned int depth )
- {
- if ( depth <= 1 ) //oops,wrong number
- {
- Render( rinfo );
- return;
- }
- if ( depth > MAX_VOLUME_PARTICLE_DEPTH )
- depth = MAX_VOLUME_PARTICLE_DEPTH; // sanity
- Shader.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE);
- if (PointCount == 0)
- return;
- WWASSERT(PointLoc && PointLoc->Get_Array());
- // Pointers which point into existing buffers (member or static):
- Vector3 *current_loc = NULL;
- Vector4 *current_diffuse = NULL;
- float *current_size = NULL;
- unsigned char *current_orient = NULL;
- unsigned char *current_frame = NULL;
- // If there is a color or alpha array enable gradient in shader - otherwise disable.
- float value_255 = 0.9961f; //254 / 255
- bool default_white_opaque = ( DefaultPointColor.X > value_255 &&
- DefaultPointColor.Y > value_255 &&
- DefaultPointColor.Z > value_255 &&
- DefaultPointAlpha > value_255);
- // The reason we check for lack of texture here is that SR seems to render black triangles
- // rather than white triangles as would be expected) when there is no texture AND no gradient.
- if (PointDiffuse || !default_white_opaque || !Texture) {
- Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_MODULATE);
- } else {
- Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_DISABLE);
- }
- // If Texture is non-NULL enable texturing in shader - otherwise disable.
- if (Texture) {
- Shader.Set_Texturing(ShaderClass::TEXTURING_ENABLE);
- } else {
- Shader.Set_Texturing(ShaderClass::TEXTURING_DISABLE);
- }
- // Get the world and view matrices
- Matrix4x4 view;
- DX8Wrapper::Get_Transform(D3DTS_VIEW,view);
- //// VOLUME_PARTICLE LOOP ///////////////
- for ( int t = 0; t < depth; ++t )
- {
- // If there is an active point table, use it to compress the point
- // locations/colors/alphas/sizes/orientations/frames.
- if (APT) {
- // Resize compressed result arrays if needed (2x guardband to prevent
- // frequent reallocations):
- /// @todo lorenzen sez: precompute pointers to indexed array elements, below
- if (compressed_loc.Length() < PointCount) {
- compressed_loc.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_loc[0],
- PointLoc->Get_Array(), APT->Get_Array(), PointCount);
- current_loc = &compressed_loc[0];
- if (PointDiffuse) {
- if (compressed_diffuse.Length() < PointCount) {
- compressed_diffuse.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_diffuse[0],
- PointDiffuse->Get_Array(), APT->Get_Array(), PointCount);
- current_diffuse = &compressed_diffuse[0];
- }
- if (PointSize) {
- if (compressed_size.Length() < PointCount) {
- compressed_size.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_size[0],
- PointSize->Get_Array(), APT->Get_Array(), PointCount);
- current_size = &compressed_size[0];
- }
- if (PointOrientation) {
- if (compressed_orient.Length() < PointCount) {
- compressed_orient.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_orient[0],
- PointOrientation->Get_Array(), APT->Get_Array(), PointCount);
- current_orient = &compressed_orient[0];
- }
- if (PointFrame) {
- if (compressed_frame.Length() < PointCount) {
- compressed_frame.Resize(PointCount * 2);
- }
- VectorProcessorClass::CopyIndexed(&compressed_frame[0],
- PointFrame->Get_Array(), APT->Get_Array(), PointCount);
- current_frame = &compressed_frame[0];
- }
- } else {
- current_loc = PointLoc->Get_Array();
- if (PointDiffuse) {
- current_diffuse = PointDiffuse->Get_Array();
- }
- if (PointSize) {
- current_size = PointSize->Get_Array();
- }
- if (PointOrientation) {
- current_orient = PointOrientation->Get_Array();
- }
- if (PointFrame) {
- current_frame = PointFrame->Get_Array();
- }
- }
- // Transform the point locations from worldspace to camera space if needed
- // (i.e. if they are not already in camera space):
- // need to interrupt this processing. If we are not billboarding, then we need the actual position
- // of the vertice to lay it down flat.
- if (Get_Flag(TRANSFORM) && Billboard) {
- // Resize transformed location array if needed (2x guardband to prevent
- // frequent reallocations):
- if (transformed_loc.Length() < PointCount) {
- transformed_loc.Resize(PointCount * 2);
- }
- // Not using vector processor class because we are discarding w
- // Not using T&L in DX8 because we don't want DX8 to transform
- // 3 times per particle when we can do it once
- float recipDepth = 0.1f / (float)depth;
- float shiftInc = ( t * *current_size * recipDepth );
- Vector3 volumeLayerShift;
- Vector3 cameraPosition = rinfo.Camera.Get_Position();
- for (int i=0; i<PointCount; i++)
- {
- /// @todo lorenzen sez: use pointer arithmetic here and a fast while loop
- Vector3 cameraToPointDelta;
- Vector3::Subtract( cameraPosition, current_loc[i], &cameraToPointDelta );
- cameraToPointDelta.Normalize();
- cameraToPointDelta.X *= shiftInc;
- cameraToPointDelta.Y *= shiftInc;
- cameraToPointDelta.Z *= shiftInc;
- Vector3 temp;
- temp.X = current_loc[i].X + cameraToPointDelta.X;
- temp.Y = current_loc[i].Y + cameraToPointDelta.Y;
- temp.Z = current_loc[i].Z + cameraToPointDelta.Z;
- Vector4 result= view * temp;
- transformed_loc[i].X=result.X;
- transformed_loc[i].Y=result.Y;
- transformed_loc[i].Z=result.Z;
- }
- current_loc = &transformed_loc[0];
- } // if transform
- // Update the arrays with the offsets.
- int vnum, pnum;
- //float attenuator = 1.0f - (1.0f/(float)depth);
- //current_diffuse->X *= attenuator;
- //current_diffuse->Y *= attenuator;
- //current_diffuse->Z *= attenuator;
- //current_diffuse->W *= attenuator;
- Update_Arrays(current_loc, current_diffuse, current_size, current_orient, current_frame,
- PointCount, PointLoc->Get_Count(), vnum, pnum);
- // the locations are now in view space
- // so set world and view matrices to identity and render
-
- Matrix4x4 identity(true);
- DX8Wrapper::Set_Transform(D3DTS_WORLD,identity);
- DX8Wrapper::Set_Transform(D3DTS_VIEW,identity);
- DX8Wrapper::Set_Material(PointMaterial);
- DX8Wrapper::Set_Shader(Shader);
- DX8Wrapper::Set_Texture(0,Texture);
- // Enable sorting if the primitives are translucent and alpha testing is not enabled.
- const bool sort = (Shader.Get_Dst_Blend_Func() != ShaderClass::DSTBLEND_ZERO) && (Shader.Get_Alpha_Test() == ShaderClass::ALPHATEST_DISABLE) && (WW3D::Is_Sorting_Enabled());
- IndexBufferClass *indexbuffer;
- int verticesperprimitive;/// lorenzen fixed
- int current;
- int delta;
- /// @todo lorenzen sez: if tri-based particles are not supported, elim this test
- if (PointMode == QUADS) {
- verticesperprimitive = 2;
- indexbuffer = sort ? static_cast <IndexBufferClass*> (SortingQuads) : static_cast <IndexBufferClass*> (Quads);
- } else {
- verticesperprimitive = 3;
- indexbuffer = sort ? static_cast <IndexBufferClass*> (SortingTris) : static_cast <IndexBufferClass*> (Tris);
- }
- float nudge = 0;
- current = 0;
- while (current<vnum)
- {
- delta=MIN(vnum-current,MAX_VB_SIZE);
- DynamicVBAccessClass PointVerts (sort ? BUFFER_TYPE_DYNAMIC_SORTING : BUFFER_TYPE_DYNAMIC_DX8, dynamic_fvf_type, delta);
- // Copy in the data to the VB
- {
- DynamicVBAccessClass::WriteLockClass Lock(&PointVerts);
- int i;
- unsigned char *vb=(unsigned char*)Lock.Get_Formatted_Vertex_Array();
- const FVFInfoClass& fvfinfo = PointVerts.FVF_Info();
- for (i = current; i < current + delta; i++)
- {
- /// @todo lorenzen sez: use pointer arithmetic throughout this block
- /// @todo lorenzen sez: delare thes locals outside this loop
- /// @todo lorenzen sez: use a fast while loop
- // Copy Locations
- *(Vector3*)(vb+fvfinfo.Get_Location_Offset()) = VertexLoc[i];
- if (current_diffuse) {
- unsigned color=DX8Wrapper::Convert_Color_Clamp(VertexDiffuse[i]);
- *(unsigned int*)(vb+fvfinfo.Get_Diffuse_Offset())=color;
- }
- else
- *(unsigned int*)(vb+fvfinfo.Get_Diffuse_Offset())=
- DX8Wrapper::Convert_Color_Clamp(Vector4(DefaultPointColor[0],DefaultPointColor[1],DefaultPointColor[2],DefaultPointAlpha));
- *(Vector2*)(vb+fvfinfo.Get_Tex_Offset(0))=VertexUV[i];
- vb+=fvfinfo.Get_FVF_Size();
- }
- } // copy
- DX8Wrapper::Set_Index_Buffer (indexbuffer, 0);
- DX8Wrapper::Set_Vertex_Buffer (PointVerts);
-
- /// @todo lorenzen sez: precompute these params, above
- if ( sort )
- SortingRendererClass::Insert_Triangles (0, delta / verticesperprimitive, 0, delta);
- else
- DX8Wrapper::Draw_Triangles (0, delta / verticesperprimitive, 0, delta);
-
- current+=delta;
- } // loop while (current<vnum)
- }// next volume layer
- // restore the matrices
- DX8Wrapper::Set_Transform(D3DTS_VIEW,view);
- }
|