This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwphys/renegadeterrainmaterialpass.cpp

384 lines
9.5 KiB
C++
Raw Permalink Normal View History

/*
** 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 : wwphys *
* *
* $Archive:: /Commando/Code/wwphys/renegadeterrainmaterialpass.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 3/05/02 10:56a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "renegadeterrainmaterialpass.h"
#include "terrainmaterial.h"
#include "vector2.h"
#include "dx8vertexbuffer.h"
#include "dx8indexbuffer.h"
#include "chunkio.h"
////////////////////////////////////////////////////////////////
// Local constants
////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x03040552,
CHUNKID_VERTEX_ALPHAS,
CHUNKID_VERTEX_UVS,
CHUNKID_MATERIAL,
CHUNKID_QUAD_LIST,
CHUNKID_VERTEX_RENDER_LIST,
CHUNKID_VERTEX_INDEX_MAP
};
enum
{
VARID_VERTEX_COUNT = 0x01,
};
////////////////////////////////////////////////////////////////
//
// RenegadeTerrainMaterialPassClass
//
////////////////////////////////////////////////////////////////
RenegadeTerrainMaterialPassClass::RenegadeTerrainMaterialPassClass (void) :
VertexAlpha (NULL),
GridUVs (NULL),
Material (NULL),
VertexCount (0)
{
::memset (VertexIndexMap, 0, sizeof (VertexIndexMap));
::memset (IndexBuffers, 0, sizeof (IndexBuffers));
::memset (VertexBuffers, 0, sizeof (VertexBuffers));
//
// Prep the lists
//
for (int index = 0; index < PASS_COUNT; index ++) {
QuadList[index].Set_Growth_Step (1000);
VertexRenderList[index].Set_Growth_Step (1000);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// ~RenegadeTerrainMaterialPassClass
//
////////////////////////////////////////////////////////////////
RenegadeTerrainMaterialPassClass::~RenegadeTerrainMaterialPassClass (void)
{
REF_PTR_RELEASE (Material);
//
// Free the UV array
//
if (GridUVs != NULL) {
delete [] GridUVs;
GridUVs = NULL;
}
//
// Free the vertex alpha array
//
if (VertexAlpha != NULL) {
delete [] VertexAlpha;
VertexAlpha = NULL;
}
//
// Free the vertex index arrays
//
for (int index = 0; index < PASS_COUNT; index ++) {
if (VertexIndexMap[index] != NULL) {
delete [] VertexIndexMap[index];
VertexIndexMap[index] = NULL;
}
//
// Release our hold on the index and vertex buffers for this pass
//
REF_PTR_RELEASE (IndexBuffers[index]);
REF_PTR_RELEASE (VertexBuffers[index]);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Allocate
//
////////////////////////////////////////////////////////////////
void
RenegadeTerrainMaterialPassClass::Allocate (int vertex_count)
{
//
// Allocate the vertex alpha and UV arrays
//
VertexCount = vertex_count;
VertexAlpha = new float[vertex_count];
GridUVs = new Vector2[vertex_count];
//
// Initialize the arrays
//
for (int index = 0; index < vertex_count; index ++) {
VertexAlpha[index] = 1.0F;
GridUVs[index].Set (0.0F, 0.0F);
}
//
// Allocate the vertex index map
//
for (index = 0; index < PASS_COUNT; index ++) {
VertexIndexMap[index] = new int[vertex_count];
::memset (VertexIndexMap[index], -1, sizeof (int) * vertex_count);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Reset
//
////////////////////////////////////////////////////////////////
void
RenegadeTerrainMaterialPassClass::Reset (void)
{
//
// Allocate the vertex index map
//
for (int index = 0; index < PASS_COUNT; index ++) {
::memset (VertexIndexMap[index], -1, sizeof (int) * VertexCount);
QuadList[index].Reset_Active ();
VertexRenderList[index].Reset_Active ();
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////
bool
RenegadeTerrainMaterialPassClass::Save (ChunkSaveClass &csave)
{
//
// Write the variables
//
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_VERTEX_COUNT, VertexCount);
csave.End_Chunk ();
//
// Save the vertex alpha array
//
csave.Begin_Chunk (CHUNKID_VERTEX_ALPHAS);
csave.Write (VertexAlpha, sizeof (float) * VertexCount);
csave.End_Chunk ();
//
// Save the grid UVs array
//
csave.Begin_Chunk (CHUNKID_VERTEX_UVS);
csave.Write (GridUVs, sizeof (Vector2) * VertexCount);
csave.End_Chunk ();
//
// Save the material
//
csave.Begin_Chunk (CHUNKID_MATERIAL);
Material->Save (csave);
csave.End_Chunk ();
//
// Save the per-pass lists
//
int count = 0;
for (int index = 0; index < PASS_COUNT; index ++) {
//
// Save the quad list
//
csave.Begin_Chunk (CHUNKID_QUAD_LIST);
count = QuadList[index].Count ();
csave.Write (&count, sizeof (int));
csave.Write (&QuadList[index][0], sizeof (int) * QuadList[index].Count ());
csave.End_Chunk ();
//
// Save the vertex render list
//
csave.Begin_Chunk (CHUNKID_VERTEX_RENDER_LIST);
count = VertexRenderList[index].Count ();
csave.Write (&count, sizeof (int));
csave.Write (&VertexRenderList[index][0], sizeof (int) * VertexRenderList[index].Count ());
csave.End_Chunk ();
//
// Save the vertex index map
//
csave.Begin_Chunk (CHUNKID_VERTEX_INDEX_MAP);
csave.Write (VertexIndexMap[index], sizeof (int) * VertexCount);
csave.End_Chunk ();
}
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////
bool
RenegadeTerrainMaterialPassClass::Load (ChunkLoadClass &cload)
{
int pass = -1;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
//
// Load all the variables from this chunk
//
case CHUNKID_VARIABLES:
Load_Variables (cload);
break;
case CHUNKID_VERTEX_ALPHAS:
cload.Read (VertexAlpha, sizeof (float) * VertexCount);
break;
case CHUNKID_VERTEX_UVS:
cload.Read (GridUVs, sizeof (Vector2) * VertexCount);
break;
case CHUNKID_MATERIAL:
{
//
// Load the material
//
Material = new TerrainMaterialClass;
Material->Load (cload);
break;
}
case CHUNKID_QUAD_LIST:
{
pass ++;
//
// Read the number of quads
//
int count = 0;
cload.Read (&count, sizeof (int));
//
// Allocate enough room for this many quads and read them in...
//
QuadList[pass].Resize (count);
if (count > 0) {
cload.Read (&QuadList[pass][0], sizeof (int) * count);
QuadList[pass].Set_Active (count);
}
break;
}
case CHUNKID_VERTEX_RENDER_LIST:
{
//
// Read the number of vertices
//
int count = 0;
cload.Read (&count, sizeof (int));
//
// Allocate enough room for this many vertices and read them in...
//
VertexRenderList[pass].Resize (count);
if (count > 0) {
cload.Read (&VertexRenderList[pass][0], sizeof (int) * count);
VertexRenderList[pass].Set_Active (count);
}
break;
}
case CHUNKID_VERTEX_INDEX_MAP:
cload.Read (VertexIndexMap[pass], sizeof (int) * VertexCount);
break;
}
cload.Close_Chunk ();
}
return true;
}
////////////////////////////////////////////////////////////////
//
// Load_Variables
//
////////////////////////////////////////////////////////////////
void
RenegadeTerrainMaterialPassClass::Load_Variables (ChunkLoadClass &cload)
{
int vertex_count = 0;
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
//
// Read each of the microchunks
//
READ_MICRO_CHUNK (cload, VARID_VERTEX_COUNT, vertex_count);
}
cload.Close_Micro_Chunk ();
}
//
// Allocate the necessary data structures
//
Allocate (vertex_count);
return ;
}