/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
*/
/***************************************************************************
*** 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 $*
* *
* $Author:: Vss_sync $*
* *
* $Modtime:: 9/12/01 10:01p $*
* *
* $Revision:: 38 $*
* *
*-------------------------------------------------------------------------*
* 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::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 "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;
// 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)
};
// Some internal variables
VectorClass VertexLoc; // camera-space vertex locations
VectorClass VertexDiffuse; // vertex diffuse/alpha colors
VectorClass VertexUV; // vertex texture coords
// Some DX 8 variables
#define MAX_VB_SIZE 1200
#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 *locs,
ShareBufferClass *diffuse,
ShareBufferClass *apt,
ShareBufferClass *sizes,
ShareBufferClass *orientations,
ShareBufferClass *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) & 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::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 remap;
void PointGroupClass::Render(RenderInfoClass &rinfo)
{
// 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();
// Static arrays for intermediate calcs (never resized down, just up):
static VectorClass compressed_loc; // point locations 'compressed' by APT
static VectorClass compressed_diffuse; // point colors 'compressed' by APT
static VectorClass compressed_size; // point sizes 'compressed' by APT
static VectorClass compressed_orient; // point orientations 'compressed' by APT
static VectorClass compressed_frame; // point frames 'compressed' by APT
static VectorClass transformed_loc; // transformed point locations
// 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):
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
Matrix4 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):
if (Get_Flag(TRANSFORM)) {
// 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; iGet_Count(), vnum, pnum);
// the locations are now in view space
// so set world and view matrices to identity and render
Matrix4 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, current, delta;
if (PointMode == QUADS) {
verticesperprimitive = 2;
indexbuffer = sort ? static_cast (SortingQuads) : static_cast (Quads);
} else {
verticesperprimitive = 3;
indexbuffer = sort ? static_cast (SortingTris) : static_cast (Tris);
}
current = 0;
while (current