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/ww3d2/texproject.h

239 lines
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 : WW3D *
* *
* $Archive:: /Commando/Code/ww3d2/texproject.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/19/01 3:30p $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef TEXPROJECT_H
#define TEXPROJECT_H
#include "always.h"
#include "matrix3d.h"
#include "matrix4.h"
#include "obbox.h"
#include "matpass.h"
#include "matrixmapper.h"
#include "cullsys.h"
#include "multilist.h"
#include "projector.h"
class SpecialRenderInfoClass;
class RenderObjClass;
class MaterialPassClass;
class SurfaceClass;
/**
** TexProjectClass
** This class is used to project textures onto object in the world. It contains
** a pointer to the texture to be projected, a bounding volume for the projection,
** and a material pass which can perform the projection.
**
** Design Goals:
** - Texture Projectors should be easy to place in the world and move around.
** solution: Store the bounding volume and any other parameters in a coordinate
** system local to the projector. Update the world-space cache whenever needed.
** The automatically generated shadow texture projectors are a special case subset
** of the general texture projection code. For this reason, a local bounding
** volume will be stored and its world-space equivalent will be updated whenever
** needed.
**
** - Texture projectors need to be compatible with the culling systems.
** solution: inherit the Cullable interface.
**
** - Texture projectors need to be quickly pulled in and out of many lists during
** the rendering process.
** solution: list system similar to PhysListClass? I really need to templatize this.
** - done: MultiListClass!
**
** - Dynamic Texture projectors need to be updated in stages. Update/recompute only the
** bounding volume first, then defer computing the actual texture until it is
** determined that the volume falls into the frustum and is applied to at least one
** object.
** solution: Code the bounding volume/projection paramter generation separate from
** the texture generation code. A derived texture projection object. Let texture
** projectors know about the object they are projecting so that they can have that
** object rendered from the desired viewpoint. Need a 'Dirty' flag and a pointer to
** a 'parent' object. Perhaps separate this code into a ShadowProjectClass since shadows
** are the only case I can think of that need the ability to re-render their 'parent'
** object. Everything else should be a static texture-map either generated 'artistically'
** or generated off-line.
**
*/
class TexProjectClass : public ProjectorClass, public CullableClass, public MultiListObjectClass
{
public:
TexProjectClass(void);
virtual ~TexProjectClass(void);
/*
** Material settings
*/
void Set_Texture_Size(int size);
int Get_Texture_Size(void);
void Init_Multiplicative(void);
void Init_Additive(void);
void Set_Intensity(float intensity,bool immediate = false); // 1.0 = on 100%, 0.0 = 'off'
float Get_Intensity(void);
bool Is_Intensity_Zero(void);
void Set_Attenuation(float attenuation); // 1.0 = on, 0.0 = off
float Get_Attenuation(void);
void Enable_Attenuation(bool onoff);
bool Is_Attenuation_Enabled(void);
MaterialPassClass * Peek_Material_Pass(void);
/*
** Options
*/
void Enable_Affect_Dynamic_Objects(bool onoff) { Set_Flag(AFFECT_DYNAMIC_OBJS,onoff); }
bool Is_Affect_Dynamic_Objects_Enabled(void) { return Get_Flag(AFFECT_DYNAMIC_OBJS); }
void Enable_Affect_Static_Objects(bool onoff) { Set_Flag(AFFECT_STATIC_OBJS,onoff); }
bool Is_Affect_Static_Objects_Enabled(void) { return Get_Flag(AFFECT_STATIC_OBJS); }
void Enable_Depth_Gradient(bool onoff);
bool Is_Depth_Gradient_Enabled(bool onoff);
/*
** Manual initialization of a TexProjectClass
** 1 - call ProjectorClass::Set_Transform
** 2 - call Set_Projection_Perspective -or- Set_Projection_Ortho
** 3 - call Set_Texture.
*/
virtual void Set_Perspective_Projection(float hfov,float vfov,float znear,float zfar);
virtual void Set_Ortho_Projection(float xmin,float xmax,float ymin,float ymax,float znear,float zfar);
void Set_Texture(TextureClass * texture);
TextureClass * Get_Texture(void) const;
TextureClass * Peek_Texture(void) const;
/*
** Automatic initialization of a TexProjectClass.
** First set up your projection parameters, give the projector a render target, then call Compute_Texture
*/
bool Compute_Perspective_Projection(RenderObjClass * obj,const Vector3 & lightpos,float znear=-1.0f,float zfar=-1.0f);
bool Compute_Perspective_Projection(const AABoxClass & obj_box,const Matrix3D & tm,const Vector3 & lightpos,float znear=-1.0f,float zfar=-1.0f);
bool Compute_Ortho_Projection(RenderObjClass * obj,const Vector3 & lightdir,float znear=-1.0f,float zfar=-1.0f);
bool Compute_Ortho_Projection(const AABoxClass & obj_box,const Matrix3D & tm,const Vector3 & lightdir,float znear=-1.0f,float zfar=-1.0f);
bool Needs_Render_Target(void);
void Set_Render_Target(TextureClass * render_target);
TextureClass * Peek_Render_Target(void);
bool Compute_Texture(RenderObjClass * model,SpecialRenderInfoClass * context);
/*
** Prep for rendering, called by the scene prior to usage.
*/
virtual void Pre_Render_Update(const Matrix3D & camera);
/*
** virtual interface for getting the pointer of the object that generated this shadow.
** defaults to returning NULL. This is implemented by some derived classes and used by
** the system to prevent a projection from being applied to the object that generated
** the projection...
** (gth) feels kludgy, this got a little messy when I moved this code into WW3D from WWPhys
*/
virtual void * Get_Projection_Object_ID(void) const { return NULL; }
protected:
void Set_Flag(uint32 flag,bool onoff);
bool Get_Flag(uint32 flag) const;
virtual void Update_WS_Bounding_Volume(void);
void Configure_Camera(CameraClass & camera);
enum FlagsType
{
PERSPECTIVE = 0x00000001, // PERSPECTIVE or ORTHO
ADDITIVE = 0x00000002, // ADDITIVE or MULTIPLICATIVE
TEXTURE_DIRTY = 0x00000004, // used by derived DynTexProjectClass
VOLATILE = 0x00000008, // this is a volatile texture.
ATTENUATE = 0x00000010, // this projector should be attenuated based on distance to viewer
AFFECT_DYNAMIC_OBJS = 0x00000020, // this projector affects dynamic objects
AFFECT_STATIC_OBJS = 0x00000040, // this projector affects static objects
USE_DEPTH_GRADIENT = 0x00000080, // fade the projection as a function of depth
HAS_RENDER_TARGET = 0x00000100, // the texture we have can be a render target
SIZE_MASK = 0xFFF00000, // desired texture size stored in upper 3 nibbles
SIZE_SHIFT = 20,
DEFAULT_FLAGS = ATTENUATE | AFFECT_DYNAMIC_OBJS | AFFECT_STATIC_OBJS
};
uint32 Flags;
/*
** Intensity Controls
*/
float DesiredIntensity; // last input desired intensity.
float Intensity; // basic shadow intensity. value between 0 and 1
float Attenuation; // attenuation factor based on distance from camera. value between 0 and 1
/*
** Material pass to be added to any object that intersects the volume
*/
MaterialPassClass * MaterialPass;
MatrixMapperClass * Mapper1;
TextureClass * RenderTarget;
/*
** I have to remember all of these values so that I can properly initialize a CameraClass
** when we do render-to-texture. Some day we will merge CameraClass and ProjectorClass.
*/
float HFov; // horizontal fov (for perspective mode)
float VFov; // vertical fov (for perspective mode)
float XMin; // left x clip plane (for ortho)
float XMax; // right x clip plane (for ortho)
float YMin; // bottom y clip plane (for ortho)
float YMax; // top y clip plane (for ortho)
float ZNear,ZFar; // z clip planes (for both modes)
};
/*
** Texture Projector Lists
*/
typedef RefMultiListClass<TexProjectClass> TexProjListClass;
typedef RefMultiListIterator<TexProjectClass> TexProjListIterator;
#endif