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/dazzle.h

394 lines
No EOL
12 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/>.
*/
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef DAZZLE_H
#define DAZZLE_H
#include "always.h"
#include "vector3.h"
#include "matrix3d.h"
#include "rendobj.h"
#include "wwstring.h"
#include "proto.h"
#include "w3derr.h"
#include "shader.h"
#include "matrix4.h"
class CameraClass;
class DazzleVisibilityClass;
struct VertexFormatXYZNDUV2;
class DazzleInitClass
{
public:
unsigned type;
bool use_camera_translation;
StringClass primary_texture_name;
StringClass secondary_texture_name;
StringClass lensflare_name;
float halo_intensity;
float halo_scale_x;
float halo_scale_y;
float dazzle_size_pow;
float dazzle_intensity_pow;
float dazzle_intensity;
float dazzle_area;
float dazzle_direction_area;
Vector3 dazzle_direction;
Vector3 dazzle_test_color;
Vector3 dazzle_color;
Vector3 halo_color;
float dazzle_scale_x;
float dazzle_scale_y;
float fadeout_start;
float fadeout_end;
float size_optimization_limit;
float history_weight;
float radius;
float blink_period;
float blink_on_time;
};
class LensflareInitClass
{
public:
LensflareInitClass()
:
flare_locations(0),
flare_sizes(0),
flare_colors(0),
flare_uv(0)
{
}
LensflareInitClass(const LensflareInitClass& lic)
:
type(lic.type),
texture_name(lic.texture_name),
flare_count(lic.flare_count),
flare_locations(0),
flare_sizes(0),
flare_colors(0),
flare_uv(0)
{
if (flare_count) {
flare_locations=new float[flare_count];
memcpy(flare_locations,lic.flare_locations,sizeof(float)*flare_count);
flare_sizes=new float[flare_count];
memcpy(flare_sizes,lic.flare_sizes,sizeof(float)*flare_count);
flare_colors=new Vector3[flare_count];
memcpy(flare_colors,lic.flare_colors,sizeof(Vector3)*flare_count);
flare_uv=new Vector4[flare_count];
memcpy(flare_uv,lic.flare_uv,sizeof(Vector4)*flare_count);
}
}
~LensflareInitClass()
{
delete[] flare_locations;
delete[] flare_sizes;
delete[] flare_colors;
delete[] flare_uv;
}
unsigned type;
StringClass texture_name;
int flare_count;
float* flare_locations;
float* flare_sizes;
Vector3* flare_colors;
Vector4* flare_uv;
};
class DazzleRenderObjClass;
class DazzleLayerClass;
class DazzleTypeClass
{
friend DazzleRenderObjClass;
friend DazzleLayerClass;
TextureClass* primary_texture;
TextureClass* secondary_texture;
DazzleInitClass ic;
float fadeout_end_sqr;
float fadeout_start_sqr;
StringClass name;
unsigned dazzle_test_color_integer;
unsigned dazzle_test_mask_integer;
unsigned lensflare_id;
ShaderClass dazzle_shader;
ShaderClass halo_shader;
float radius;
DazzleTypeClass(const DazzleInitClass& is);
virtual ~DazzleTypeClass();
public:
virtual void Calculate_Intensities(
float& dazzle_intensity,
float& dazzle_size,
float& halo_intensity,
const Vector3& camera_dir,
const Vector3& dazzle_dir,
float distance) const;
void Set_Dazzle_Shader(const ShaderClass& s); // Set shader for the dazzle type
void Set_Halo_Shader(const ShaderClass& s); // Set shader for the dazzle type
TextureClass* Get_Dazzle_Texture();
TextureClass* Get_Halo_Texture();
};
// The DazzleLayerClass is for all the dazzles being rendered with a given
// group of camera settings: for example, different scenes may use different
// z-buffer settings and in such a case each scene should have a dazzle layer
// associated with it. (In some special cases a scene may have more than one
// dazzle layer). A dazzle layer contains visible and invisible lists for
// each dazzle type. During rendering each dazzle is put on the correct list
// (a "current dazzle layer" static variable is set before rendering the
// appropriate scenes to ensure this). After all scenes are rendered, the
// dazzle layers are rendered one by one with the correct camera settings.
// NOTE: dazzle layers must be constructed AFTER all the dazzle types have
// been initialized, since the constructor needs to know how many dazzle types
// there are.
class DazzleLayerClass {
friend DazzleRenderObjClass;
public:
DazzleLayerClass(void);
~DazzleLayerClass(void);
// Render all dazzles in this layer (DazzleRenderObj::Render() only sets visibility)
void Render(CameraClass* camera);
private:
virtual int Get_Visible_Item_Count(unsigned int type) const; // Return visible item count
// virtual void Get_Visible_Item_Locations(unsigned int type, Vector3* locations) const; // Copy locations of visible items to buffer
virtual void Clear_Visible_List(unsigned int type);
// We have an array of visible lists (one for each dazzle type).
DazzleRenderObjClass** visible_lists;
};
class LensflareTypeClass
{
friend DazzleLayerClass;
friend DazzleRenderObjClass;
TextureClass* texture;
LensflareInitClass lic;
StringClass name;
LensflareTypeClass(const LensflareInitClass& is);
virtual ~LensflareTypeClass();
public:
TextureClass* Get_Texture();
void Generate_Vertex_Buffers(
VertexFormatXYZNDUV2* vertex,
int& vertex_count,
float screen_x_scale,
float screen_y_scale,
float dazzle_intensity,
const Vector4& transformed_location);
void Render_Arrays(
const Vector4* vertex_coordinates,
const Vector2* uv_coordinates,
const Vector3* color,
int vertex_count,
int halo_vertex_count,
const Vector2* texture_coordinates);
};
class INIClass;
class DazzleRenderObjClass : public RenderObjClass
{
friend DazzleLayerClass;
DazzleRenderObjClass * succ;
unsigned type;
float current_dazzle_intensity;
float current_dazzle_size;
float current_halo_intensity;
float current_distance;
Vector4 transformed_loc;
Vector3 current_vloc;
Vector3 current_dir;
Vector3 dazzle_color;
Vector3 halo_color;
float lensflare_intensity;
float visibility;
bool on_list; // This is used to avoid insterting a dazzle into a list twice.
float radius; // Used to cast rays against
unsigned int creation_time;
static bool _dazzle_rendering_enabled;
// static void Draw_Debug_Dazzle(int idx);
void vis_render_dazzle(SpecialRenderInfoClass & rinfo);
void Render_Dazzle(CameraClass* camera);
public:
DazzleRenderObjClass(unsigned type);
DazzleRenderObjClass(const char* type_name);
DazzleRenderObjClass(const DazzleRenderObjClass & src);
DazzleRenderObjClass & operator = (const DazzleRenderObjClass &);
DazzleRenderObjClass* Succ() { return succ; }
const DazzleRenderObjClass* Succ() const { return succ; }
/////////////////////////////////////////////////////////////////////////////
// Render Object Interface
/////////////////////////////////////////////////////////////////////////////
virtual RenderObjClass * Clone(void) const;
virtual int Class_ID(void) const { return CLASSID_DAZZLE; }
virtual void Render(RenderInfoClass & rinfo);
virtual void Special_Render(SpecialRenderInfoClass & rinfo);
virtual void Set_Transform(const Matrix3D &m);
virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
virtual void Get_Obj_Space_Bounding_Box(AABoxClass & box) const;
virtual void Scale(float scale) { radius*=scale; };
void Set_Dazzle_Color(const Vector3& col) { dazzle_color=col; }
void Set_Halo_Color(const Vector3& col) { halo_color=col; }
void Set_Lensflare_Intensity (float intensity) {lensflare_intensity=intensity;}
unsigned int Get_Dazzle_Type(void) { return type; }
// Usually, a DazzleRenderObj adds itself to the appropriate visible list
// (determined by the current layer) when it is rendered. This does not
// work for dazzles with "camera transform off", since they are located in
// camera space and the standard worldspace visibility algo will give
// unpredictable results for them (they may never have a Render() call).
// So for these dazzles, you need to call Set_Layer() after constructing
// them (this is instead of putting them in a scene). This function adds
// the dazzle to the appropriate visible list. NOTE: It is also called
// internally by the Render() function.
void Set_Layer(DazzleLayerClass *layer);
// Persistant object save-load interface
// Dazzles save their "dazzle-type" and transform
virtual const PersistFactoryClass & Get_Factory (void) const;
// Set the static "current layer" variable. This variable is used in the
// Render() call so that the dazzle knows which list to add itself to if
// it is visible. This function must be called before rendering the
// scene(s) in which the dazzles are present.
static void Set_Current_Dazzle_Layer(DazzleLayerClass *layer);
static void Init_Type(const DazzleInitClass& i);
static void Init_Lensflare(const LensflareInitClass& i);
static void Init_From_INI(const INIClass* ini);
static unsigned Get_Type_ID(const char* name); // Return the ID of type with given name, or INT_MAX if failed
static const char * Get_Type_Name(unsigned int id); // Return the name of the type with the given ID
static DazzleTypeClass* Get_Type_Class(unsigned id); // Return dazzle type class pointer, or NULL if not found
// The pointer is NOT refcounted - all types are deinitialised
// when exiting the level.
static unsigned Get_Lensflare_ID(const char* name); // Return the ID of lensflare with given name, or INT_MAX if failed
static LensflareTypeClass* Get_Lensflare_Class(unsigned id); // Return lensflare type class pointer, or NULL if not found
static void Deinit();
// Install a class derived from DazzleVisibilityClass to add app-specific
// visibility determination. The default behavior will ask the scene which
// the dazzle is a member of to compute its visibility.
static void Install_Dazzle_Visibility_Handler(const DazzleVisibilityClass * visibility_handler);
// Globally disable/enable dazzle rendering
static void Enable_Dazzle_Rendering(bool onoff) { _dazzle_rendering_enabled = onoff; }
static bool Is_Dazzle_Rendering_Enabled(void) { return _dazzle_rendering_enabled; }
};
/**
** DazzleVisibilityClass
** The user should derive a class from DazzleVisibilityClass and implement an app-specific
** dazzle visibility test. Renegade will use ray-casting to determine visibility. The
** default visibility handler will query the scene which the dazzle is contained in.
*/
class DazzleVisibilityClass
{
public:
virtual float Compute_Dazzle_Visibility( RenderInfoClass & rinfo,
DazzleRenderObjClass * dazzle,
const Vector3 & point) const;
};
/**
** DazzlePrototypeClass
** This description object is generated when reading a W3D_CHUNK_DAZZLE. It stores the
** information needed to construct a particular instance of a dazzle. Prototypes are
** stored in the asset manager and used to construct render objects when needed.
*/
class DazzlePrototypeClass : public PrototypeClass
{
public:
DazzlePrototypeClass(void) : DazzleType(0) { }
virtual ~DazzlePrototypeClass(void) { }
virtual const char * Get_Name(void) const { return Name; }
virtual int Get_Class_ID(void) const { return RenderObjClass::CLASSID_DAZZLE; }
virtual RenderObjClass * Create(void);
WW3DErrorType Load_W3D(ChunkLoadClass & cload);
private:
StringClass Name;
int DazzleType;
};
/**
** DazzleLoaderClass
** An instance of this class is registered with the asset manager and handles loading W3D_CHUNK_DAZZLE.
** It creates DazzlePrototypes from the data in the chunk.
*/
class DazzleLoaderClass : public PrototypeLoaderClass
{
public:
DazzleLoaderClass(void) { }
~DazzleLoaderClass(void) { }
virtual int Chunk_Type(void) { return W3D_CHUNK_DAZZLE; }
virtual PrototypeClass * Load_W3D(ChunkLoadClass & cload);
};
extern DazzleLoaderClass _DazzleLoader;
#endif