texturefile.h 8.3 KB

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