Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
texturefile.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef TEXTUREFILE_H
20#define TEXTUREFILE_H
21
22#if defined(_MSC_VER)
23#pragma once
24#endif
25
26#include "always.h"
27#include "classid.h"
28#include "wwdebug.h"
29#include "wwstring.h"
30
31#ifdef WW3D_DX8
32
33#include <srTexture.hpp>
34
35/*
36** TextureFileClass: this replaces srTextureFile - it is the primary texture
37** class used in WW3D (except for special and rare cases such as animating
38** textures).
39** A TextureFileClass can operate in one of two modes:
40** 1) A simple mode in which every time the GERD requests the texture data
41** (via getMipmapData), the texture is reloaded from its file. This is
42** useful for cases in which the texture must always be seen at its full
43** size and we do not mind waiting for it to load (on startup, and
44** whenever it gets thrown out of the GERD/API/HW texture cache).
45** 2) A mode in which there is a "locked surface" which is always present in
46** the texture. This surface is reduced by some factor relative to the
47** fullsize texture (NOTE: this factor may be 0, in which case the locked
48** texture IS the fullsize texture. This is similar to the srTextureFile's
49** "cached" mode.). In this mode the texture's desired reduction factor
50** changes dynamically according to the screen size of the object to which
51** it belongs. If the difference between the desired and current reduction
52** factors is large enough, the current reduction factor is adjusted to
53** match the desired one: either by using the locked surface (if the
54** desired reduction factor is equal or greater to that of the locked
55** surface), or by asking a background thread to load the surface at the
56** desired reduction factor.
57*/
58class TextureFileClass : public srClassSupport<TextureFileClass,srTexture,false,ID_TEXTURE_FILE_CLASS>
59{
60public:
61
62 TextureFileClass(const char * filename);
63 virtual ~TextureFileClass(void);
64
65 // Copy CTor and assignment operator assert for now - if anyone hits the
66 // assert we might need to actually implement them 8^).
67 TextureFileClass(const TextureFileClass & src);
68 TextureFileClass & TextureFileClass::operator = (const TextureFileClass &that);
69
70 // srClass functions:
71 virtual srClass* vInstance(void) { WWASSERT(0); return W3DNEW TextureFileClass(""); }
72
73 // srTextureIFace functions:
74 virtual FrameHandle getTextureFrameHandle(void);
75 virtual void getMipmapData(MultiRequest& m);
76
77 // srTexture functions:
78 virtual void invalidate(void);
79protected:
80 virtual void setupDefaultValues (void);
81public:
82
83 const char * Get_File_Name(void) { return FileName; }
84
85 void Apply_New_Surface();
86
87 // Performance statistics:
88 static void Switch_Mipmaping_Debug();
89 static int Get_Total_Locked_Surface_Size();
90 static int Get_Total_Texture_Size();
91 static int Get_Total_Non_Reduced_Texture_Size(); // Texture size if reduction was NOT used
92 static int Get_Total_Locked_Surface_Count();
93 static int Get_Total_Texture_Count();
94 static StringClass List_Missing_Files(); // Print out a list of missing files
95 int Get_Texture_Size() const { return TextureSize; } // Actual size is in bytes, reduction applied
96 int Get_Non_Reduced_Texture_Size() const { return NonReducedTextureSize; } // Size is in bytes if texture reduction wasn't used
97 int Get_Locked_Surface_Size() const { return LockedSurfaceSize; } // Size is in bytes
98 int Get_Current_Reduction_Factor() const { return CurrentReductionFactor; }
99 int Get_File_Error() const { return file_error; }
100
101 // This is used by an object to request a reduction factor on all its
102 // textures. Only the smallest reduction factor requested in a given frame
103 // is preserved. See comments for DesiredReductionFactor below on
104 // interpretation of reduction_factor and why it nees to be a float.
105 void Request_Reduction(float reduction_factor);
106
107 // This is used during rendering - if a textures desired reduction level
108 // is "different enough" from its current one, we fix it: either by
109 // updating from the locked surface (if the reduction factor is equal or
110 // greater to that of the locked surface) or by asking the texture loader
111 // to load a new reduction level of the texture in the background.
112 // NOTE - if there is no locked surface, we do nothing (since textures
113 // without locked surfaces do not perform reduction).
114 void Process_Reduction(void);
115
116 // If false is passed, the texture will load the largest LOD size and stick to that
117 void Enable_Reduction(bool b);
118
119 // Reset the current time stamp to the next value (see comments for
120 // _CurrentTimeStamp below)
121 static void _Reset_Time_Stamp(void) { _CurrentTimeStamp++; }
122
123 // See comments for _SwitchThreshold below:
124 static void _Set_Switch_Threshold(float switch_threshold);
125 static float _Get_Switch_Threshold(void);
126
127 // Information structure for texture loader use only
128 struct TextureLoaderInfoStruct {
129 srColorSurfaceIFace* new_surface;
130 TextureFileClass* succ;
131 bool loading;
132 unsigned int reduction_factor;
133 TextureLoaderInfoStruct() : succ(0), new_surface(0), loading(false), reduction_factor(0U) {}
134 } texture_loader_info;
135
136 // Debug functions
137 int ID() const { return id; }
138 void Set_Texture_Flash(bool b); // Make texture flash (Warning! Slow, for debug only!!!)
139 bool Get_Texture_Flash() const; // Return texture flash state
140 static TextureFileClass* Get_Texture(int id);
141 static void Update_Texture_Flash();
142private:
143
144 // Utility functions
145 void Load_Temp_Surface(void);
146 void Release_Temp_Surface(void);
147 void Load_Locked_Surface();
148 void static Fill_Multi_Request_From_Surface(MultiRequest& m, srColorSurfaceIFace* surface);
149
150 // Locked Surface
151 srColorSurfaceIFace * LockedSurface;
152 unsigned int LockedSurfaceReductionFactor;
153
154 TextureFileClass * Succ;
155
156 // For performance statistics
157 int LockedSurfaceSize;
158 int TextureSize;
159 int NonReducedTextureSize;
160
161 /*
162 ** Texture reduction stuff:
163 **
164 ** Reduction factors are the power of two by which the texture size must
165 ** be reduced: e.g. 3 means a reduction by 8 in both x and y.
166 */
167
168 bool ReductionEnabled;
169
170 // The current reduction factor reflects the texture size currently used
171 // in rendering.
172 unsigned int CurrentReductionFactor;
173
174 // The desired reduction factor is a fractional non-negative value. It
175 // needs to be fractional for proper implementation of hysteresis (the
176 // thresholds going up and down are different).
177 float DesiredReductionFactor;
178
179 // The time stamp is used for two purposes:
180 // 1) Determining the first Request_Reduction() call in a frame
181 // 2) Determining the first Process_Reduction() call in a frame
182 static unsigned int _CurrentTimeStamp;
183 unsigned int TimeStampOfLastRequestReductionCall;
184 unsigned int TimeStampOfLastProcessReductionCall;
185
186 // This controls the degree of hysteresis when switching reduction levels.
187 // It is the minimum difference between the current and desired reduction
188 // factors to cause a switch. This number must be greater or equal to 0.5
189 // (no hysteresis) and less than 1 (maximum hysteresis). In theory values
190 // greater than 1 should be possible, producing more hysteresis, but then
191 // there is a problem when switching to 0 (since the desired reduction
192 // factor is clamped to 0. If in future we want greater amounts of
193 // hysteresis, we should consider not clamping.)
194 static float _SwitchThreshold;
195
196 // The texture's file name
197 char * FileName;
198
199 // The texture's frame handle
200 FrameHandle TextureFrameHandle;
201
202 // A temporary surface pointer only used to pass information from
203 // Apply_New_Surface() to setupDefaultValues() and getMipmapData().
204 srColorSurfaceIFace* TempSurfacePtr;
205
206 bool file_error;
207 int id; // Used for debugging purposes (unique id)
208 bool flash; // If true, texture will flash (debug!)
209 srColorSurfaceIFace* flash_store_surface;
210};
211
212#endif //WW3D_DX8
213
214#endif
#define WWASSERT
#define W3DNEW
Definition always.h:109
@ false
Definition bool.h:59