217 lines
No EOL
10 KiB
C++
217 lines
No EOL
10 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***************************************************************************
|
|
* *
|
|
* Project Name : G *
|
|
* *
|
|
* $Archive:: /VSS_Sync/ww3d2/pointgr.h $*
|
|
* *
|
|
* $Author:: Vss_sync $*
|
|
* *
|
|
* $Modtime:: 9/12/01 10:01p $*
|
|
* *
|
|
* $Revision:: 11 $*
|
|
* *
|
|
*-------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifndef POINTGR_H
|
|
#define POINTGR_H
|
|
|
|
#include "sharebuf.h"
|
|
#include "shader.h"
|
|
#include "vector4.h"
|
|
#include "vector3.h"
|
|
#include "vector2.h"
|
|
|
|
class VertexMaterialClass;
|
|
class RenderInfoClass;
|
|
class TextureClass;
|
|
|
|
/*
|
|
** PointGroupClass -- a custom object for rendering
|
|
** groups of points (such as particle systems).
|
|
** It is possible to change mode/number of points/shader/etc. but these
|
|
** changes tend to be expensive if done often. Expected usage is to set the
|
|
** point location/color/active arrays each frame the object is visible (with
|
|
** the same number of points) and perform other changes relatively rarely.
|
|
** NOTE: Currently it is implemented using general triangles (1 or 2 per
|
|
** point), so it is probably suboptimal for software rasterization devices
|
|
** (which would probably perform better with some kind of blit/sprite code).
|
|
*/
|
|
class PointGroupClass
|
|
{
|
|
public:
|
|
|
|
enum PointModeEnum {
|
|
TRIS, // each point is a triangle
|
|
QUADS, // each point is a quad formed out of two triangles
|
|
SCREENSPACE // each point is a tri placed to affect certain pixels (should be used with 2D camera)
|
|
};
|
|
|
|
enum FlagsType {
|
|
TRANSFORM, // transform points w. modelview matrix (worldspace points)
|
|
};
|
|
|
|
PointGroupClass(void);
|
|
virtual ~PointGroupClass(void);
|
|
PointGroupClass & operator = (const PointGroupClass & that);
|
|
|
|
// PointGroupClass interface:
|
|
void Set_Arrays(ShareBufferClass<Vector3> *locs,
|
|
ShareBufferClass<Vector4> *diffuse = NULL,
|
|
ShareBufferClass<unsigned int> *apt = NULL,
|
|
ShareBufferClass<float> *sizes = NULL,
|
|
ShareBufferClass<unsigned char> *orientations = NULL,
|
|
ShareBufferClass<unsigned char> *frames = NULL,
|
|
int active_point_count = -1,
|
|
float vpxmin = 0.0f, float vpymin = 0.0f,
|
|
float vpxmax = 0.0f, float vpymax = 0.0f);
|
|
void Set_Point_Size(float size);
|
|
float Get_Point_Size(void);
|
|
void Set_Point_Color(Vector3 color);
|
|
Vector3 Get_Point_Color(void);
|
|
void Set_Point_Alpha(float alpha);
|
|
float Get_Point_Alpha(void);
|
|
void Set_Point_Orientation(unsigned char orientation);
|
|
unsigned char Get_Point_Orientation(void);
|
|
void Set_Point_Frame(unsigned char frame);
|
|
unsigned char Get_Point_Frame(void);
|
|
void Set_Point_Mode(PointModeEnum mode);
|
|
PointModeEnum Get_Point_Mode(void);
|
|
void Set_Flag(FlagsType flag, bool onoff);
|
|
int Get_Flag(FlagsType flag);
|
|
void Set_Texture(TextureClass* texture);
|
|
TextureClass * Get_Texture(void);
|
|
TextureClass * Peek_Texture(void);
|
|
void Set_Shader(ShaderClass shader);
|
|
ShaderClass Get_Shader(void);
|
|
|
|
// The frame property is taken from a set of possible frames. The rows/columns in the frame
|
|
// texture determine the number of possible frames. Since it must be a power of 2, we represent
|
|
// it as its log base 2. This number cannot be greater than 4 (which corresponds to a 16x16
|
|
// square of frames, i.e. 256 frames).
|
|
unsigned char Get_Frame_Row_Column_Count_Log2(void);
|
|
void Set_Frame_Row_Column_Count_Log2(unsigned char frccl2);
|
|
|
|
int Get_Polygon_Count(void);
|
|
|
|
void Render(RenderInfoClass &rinfo);
|
|
|
|
protected:
|
|
// Update arrays.
|
|
void 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);
|
|
|
|
// These shared buffers are used for communication to the point group - to
|
|
// pass point locations, colors and enables. The location and color arrays
|
|
// are 'compressed' using the active point table (if present) and then
|
|
// are processed into other arrays which are passed to the GERD.
|
|
// SR rather than WWMath types are used so Vector Processors can be used.
|
|
// The arrays override the default value if present.
|
|
// The orientation and frame properties are "index properties": they select one out of a small
|
|
// group of possibilities for each point.
|
|
// Orientation: this is the 2D rotation of the point about its center. There are 256 discrete
|
|
// orientations. The unit circle is evenly subdivided 256 times to create the set of
|
|
// orientations. The reason we discretize orientation is for performance: this way we can
|
|
// precalculate vertex offsets.
|
|
// Frame: the texture is divided into a 2D square grid, and each point uses one grid square
|
|
// instead of the whole texture. The number of possible frames is not invariant - it depends
|
|
// on the number of rows / columns in the grid. The reason we do this instead of having
|
|
// different textures is to avoid texture state changes. Also for performance reasons, the
|
|
// number of possible frames must be a power of two - for this reason the number of frame rows
|
|
// and columns, orientations, etc. are represented as the log base 2 of the actual number.
|
|
ShareBufferClass<Vector3> * PointLoc; // World/cameraspace point locs
|
|
ShareBufferClass<Vector4> * PointDiffuse; // (NULL if not used) RGBA values
|
|
ShareBufferClass<unsigned int> * APT; // (NULL if not used) active point table
|
|
ShareBufferClass<float> * PointSize; // (NULL if not used) size override table
|
|
ShareBufferClass<unsigned char> * PointOrientation; // (NULL if not used) orientation indices
|
|
ShareBufferClass<unsigned char> * PointFrame; // (NULL if not used) frame indices
|
|
int PointCount; // Active (if APT) or total point count
|
|
|
|
// See comments for Get/Set_Frame_Row_Column_Count_Log2 above
|
|
unsigned char FrameRowColumnCountLog2; // MUST be equal or lesser than 4
|
|
|
|
// These parameters are passed to the GERD:
|
|
TextureClass* Texture;
|
|
ShaderClass Shader; // (default created in CTor)
|
|
|
|
// Internal state:
|
|
PointModeEnum PointMode; // are points tris or quads?
|
|
unsigned int Flags; // operation control flags
|
|
float DefaultPointSize; // point size (size array overrides if present)
|
|
Vector3 DefaultPointColor; // point color (color array overrides if present)
|
|
float DefaultPointAlpha; // point alpha (alpha array overrides if present)
|
|
unsigned char DefaultPointOrientation;// point orientation (orientation array overrides if present)
|
|
unsigned char DefaultPointFrame; // point texture frame (frame array overrides if present)
|
|
|
|
// View plane rectangle (only used in SCREENSPACE mode - set by Set_Arrays
|
|
// and used in Update_GERD_Arrays).
|
|
float VPXMin;
|
|
float VPYMin;
|
|
float VPXMax;
|
|
float VPYMax;
|
|
|
|
// Static stuff:
|
|
// For performance / memory reasons we prepare vertex location and UV
|
|
// arrays for various orientations and texture frames, as static data
|
|
// members of this class. This avoids the need to create such arrays over
|
|
// again for each object. The values in the UV arrays are used as-is, the
|
|
// values in the location arrays normally need to be scaled to the point
|
|
// sizes and added to the point location before use. We have distinct sets
|
|
// of arrays for each point mode.
|
|
// There are tables of vertex positions for each of triangle and quad mode
|
|
// with 256 discrete orientations. Each entry contains 3 (for triangle
|
|
// mode) or 4 (for quad mode) Vector3s.
|
|
// There are five tables of texture UVs for each of triangle and quad mode:
|
|
// with 1x1(1), 2x2(4), 4x4(16), 8x8(64) and 16x16(256) frames. Each entry
|
|
// contains 3 (for triangle mode) or 4 (for quad mode) Vector2s.
|
|
// In addition, there is one array of vertex positions for screenspace mode
|
|
// with 2 entries (for size 1 and size 2). Each entry contains 3 Vector3s.
|
|
// the Init function (which is called by WW3D::Init()) creates these
|
|
// arrays, and the Shutdown function (which is called by WW3D::Shutdown()
|
|
// releases them.
|
|
public:
|
|
static void _Init(void);
|
|
static void _Shutdown(void);
|
|
|
|
private:
|
|
static Vector3 _TriVertexLocationOrientationTable[256][3];
|
|
static Vector3 _QuadVertexLocationOrientationTable[256][4];
|
|
static Vector3 _ScreenspaceVertexLocationSizeTable[2][3];
|
|
static Vector2 *_TriVertexUVFrameTable[5];
|
|
static Vector2 *_QuadVertexUVFrameTable[5];
|
|
static VertexMaterialClass *PointMaterial;
|
|
};
|
|
|
|
#endif |