1 /*
2
3 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4 and the "Aleph One" developers.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 This license is contained in the file "COPYING",
17 which is included with this source code; it is available online at
18 http://www.gnu.org/licenses/gpl.html
19
20 OpenGL Texture Manager,
21 by Loren Petrich,
22 March 12, 2000
23
24 This contains functions for handling the texture management for OpenGL.
25
26 Nov 18, 2000 (Loren Petrich):
27 Added support for landscape vertical repeats
28
29 May 3, 2003 (Br'fin (Jeremy Parsons))
30 Added LowLevelShape workaround for passing LowLevelShape info of sprites
31 instead of abusing/overflowing shape_descriptors
32 */
33
34 #ifndef _OGL_TEXTURES
35 #define _OGL_TEXTURES
36
37 #include "OGL_Headers.h"
38 #include "OGL_Subst_Texture_Def.h"
39 #include "scottish_textures.h"
40
41 // Initialize the texture accounting
42 void OGL_StartTextures();
43
44 // Done with the texture accounting
45 void OGL_StopTextures();
46
47 // Call this after every frame for housekeeping stuff
48 void OGL_FrameTickTextures();
49
50 // State of an individual texture set:
51 struct TextureState
52 {
53 // Which member textures?
54 enum
55 {
56 Normal, // Used for all normally-shaded and shadeless textures
57 Glowing, // Used for self-luminous textures
58 Bump, // Bump map for textures
59 NUMBER_OF_TEXTURES
60 };
61 GLuint IDs[NUMBER_OF_TEXTURES]; // Texture ID's
62 bool IsUsed; // Is the texture set being used?
63 bool IsGlowing; // Does the texture have a glow map?
64 bool IsBumped; // Does the texture have a bump map?
65 bool TexGened[NUMBER_OF_TEXTURES]; // Which ID's have had their textures generated?
66 int IDUsage[NUMBER_OF_TEXTURES]; // Which ID's are being used? Reset every frame.
67 int unusedFrames; // How many frames have passed since we were last used.
68 short TextureType;
69
70 GLdouble U_Scale;
71 GLdouble V_Scale;
72 GLdouble U_Offset;
73 GLdouble V_Offset;
74
TextureStateTextureState75 TextureState() {IsUsed = false; Reset(); TextureType = NONE; U_Scale = V_Scale = 1; U_Offset = V_Offset = 0;}
~TextureStateTextureState76 ~TextureState() {Reset();}
77
78 // Allocate some textures and indicate whether an allocation had happened.
79 bool Allocate(short txType);
80
81 // These indicate that some texture
82 bool Use(int Which);
UseNormalTextureState83 bool UseNormal() {return Use(Normal);}
UseGlowingTextureState84 bool UseGlowing() {return Use(Glowing);}
UseBumpTextureState85 bool UseBump() {return Use(Bump);}
86
87 void FrameTick();
88
89 // Reset the texture to unused and force a reload if necessary
90 void Reset();
91 };
92
93
94 /*
95 This is the collected texture states per collection bitmap;
96 it contains both texture-mapping info and the state for each color-table value.
97
98 The GLdouble stuff is for setting up offsets of the texture coordinates, using:
99 Texture Coordinate = (offset) + (scale) * (clip position)
100 where (scale) = (sprite size) / (texture size)
101 and (clip position) = ((clip screen position) - (left screen position)) /
102 ((right screen position) - (left screen position))
103 */
104 struct CollBitmapTextureState
105 {
106 TextureState CTStates[NUMBER_OF_OPENGL_BITMAP_SETS];
107
108 // Sensible default
CollBitmapTextureStateCollBitmapTextureState109 CollBitmapTextureState() {}
110 };
111
112
113 // Modify color-table index if necessary;
114 // makes it the infravision or silhouette one if necessary
115 short ModifyCLUT(short TransferMode, short CLUT);
116
117
118 // Intended to be the no-texture default argument
119 const int BadTextureType = 32767;
120
121 /*
122 Texture-manager object: contains all the handling of textures;
123 it finds their setting up, their dimensions, and so forth.
124
125 It is designed to be created and destroyed
126 once each rendering go-around with each texture.
127 */
128
129 class TextureManager
130 {
131 // Width: along scanlines; height; from scanline to scanline
132 // Wall textures and sprites are horizontal-vertical flipped
133
134 // Various texture ID's:
135 short Collection;
136 short CTable;
137 short Frame;
138 short Bitmap;
139
140 // Info transmitted from the setting-up phase
141 bool IsGlowing;
142
143 // Width and height and whether to do RLE
144 // These are, in order, for the original texture, for the OpenGL texture,
145 // and the offsets in the original in the OpenGL texture.
146 // Also, the loaded-texture dimensions, in case the textures get shrunk.
147 short BaseTxtrWidth, BaseTxtrHeight;
148 short TxtrWidth, TxtrHeight;
149 short WidthOffset, HeightOffset;
150 short LoadedWidth, LoadedHeight;
151
152 // Color table: need it for going from indexed to true color;
153 // both normal and glow-mapped versions are needed
154 uint32 NormalColorTable[MAXIMUM_SHADING_TABLE_INDEXES];
155 uint32 GlowColorTable[MAXIMUM_SHADING_TABLE_INDEXES];
156
157 // Texture buffers for OpenGL
158 uint32 *NormalBuffer, *GlowBuffer;
159
160 // New texture buffers
161 ImageDescriptorManager NormalImage, GlowImage, OffsetImage;
162
163 // Pointer to the appropriate texture-state object
164 TextureState *TxtrStatePtr;
165
166 // Pointer to texture-options object
167 OGL_TextureOptions *TxtrOptsPtr;
168
169 // Private methods
170
171 // This one tries to load substitute textures into NormalBuffer and GlowBuffer;
172 // it returns whether such textures were loaded.
173 bool LoadSubstituteTexture();
174
175 // This one finds the width, height, etc. of a texture type;
176 // it returns "false" if some texture's dimensions do not fit.
177 bool SetupTextureGeometry();
178
179 // This one finds the color tables
180 void FindColorTables();
181
182 // premultiplies color table alpha
183 void PremultiplyColorTables();
184
185 // This one allocates an OpenGL texture buffer and uses a color table
186 uint32 *GetOGLTexture(uint32 *ColorTable);
187
188 // This one creates a fake landscape
189 uint32 *GetFakeLandscape();
190
191 // This is for shrinking a texture
192 uint32 *Shrink(uint32 *Buffer);
193
194 // This is for placing a texture in OpenGL
195 void PlaceTexture(const ImageDescriptor *, bool normal_map = false);
196
197 public:
198
199 // Inputs: get off of texture object passed to scottish_textures.
200 shape_descriptor ShapeDesc;
201 uint16 LowLevelShape;
202 bitmap_definition *Texture;
203 void *ShadingTables;
204 short TransferMode;
205 short TransferData;
206 bool IsShadeless;
207 short TextureType;
208 bool LandscapeVertRepeat;
209
210 bool FastPath;
211
212 // The width of a landscape texture will be 2^(-Landscape_AspRatExp) * (the height)
213 short Landscape_AspRatExp;
214
215 // Sets up all the texture stuff:
216 bool Setup();
217
218 // Results:
219
220 // Various texture ID's:
GetCollection()221 short GetCollection() {return Collection;}
GetCTable()222 short GetCTable() {return CTable;}
GetFrame()223 short GetFrame() {return Frame;}
GetBitmap()224 short GetBitmap() {return Bitmap;}
225
226 // Info transmitted from the setting-up phase:
227 // texture type, whether it is glowmapped,
228 // and whether the textures are blended rather than all-or-nothing crisp-edged
GetTextureType()229 int GetTextureType() {return TextureType;}
IsGlowMapped()230 bool IsGlowMapped() {return IsGlowing;}
IsBlended()231 bool IsBlended() {return (TxtrOptsPtr->OpacityType != OGL_OpacType_Crisp);}
VoidVisible()232 bool VoidVisible() {return (TxtrOptsPtr->VoidVisible);}
NormalBlend()233 short NormalBlend() {return (TxtrOptsPtr->NormalBlend) + ((NormalImage.get() && NormalImage.get()->IsPremultiplied() && TxtrOptsPtr->NormalBlend < OGL_FIRST_PREMULT_ALPHA) ? OGL_FIRST_PREMULT_ALPHA : 0); }
GlowBlend()234 short GlowBlend() {return (TxtrOptsPtr->GlowBlend) + ((GlowImage.get() && GlowImage.get()->IsPremultiplied() && TxtrOptsPtr->GlowBlend < OGL_FIRST_PREMULT_ALPHA) ? OGL_FIRST_PREMULT_ALPHA : 0); }
MinGlowIntensity()235 float MinGlowIntensity() {return (TxtrOptsPtr->MinGlowIntensity);}
BloomScale()236 float BloomScale() {return (TxtrOptsPtr->BloomScale);}
BloomShift()237 float BloomShift() {return (TxtrOptsPtr->BloomShift);}
GlowBloomScale()238 float GlowBloomScale() {return (TxtrOptsPtr->GlowBloomScale);}
GlowBloomShift()239 float GlowBloomShift() {return (TxtrOptsPtr->GlowBloomShift);}
LandscapeBloom()240 float LandscapeBloom() {return (TxtrOptsPtr->LandscapeBloom);}
241
242 // Scaling and offset of the current texture;
243 // important for sprites, which will be padded to make them OpenGL-friendly.
244 GLdouble U_Scale, V_Scale, U_Offset, V_Offset;
245
246 // What to render:
247
248 // Always call this one and call it first; safe to allocate texture ID's in it
249 void RenderNormal();
250 // Call this one after RenderNormal()
251 void RenderGlowing();
252 void RenderBump();
253
254 void SetupTextureMatrix();
255 void RestoreTextureMatrix();
256
257 TextureManager();
258 ~TextureManager();
259 };
260
261
262 // Color-transformation macros:
263
264 // Five-to-eight translation:
265 // takes a 5-bit color value and expands it to 8 bytes
FiveToEight(byte x)266 inline byte FiveToEight(byte x) {return (x << 3) | ((x >> 2) & 0x07);}
267
268 // 16-bit-to-32-bit with opacity = 1;
269 // ARGB 1555 to RGBA 8888
Convert_16to32(uint16 InPxl)270 inline GLuint Convert_16to32(uint16 InPxl)
271 {
272 if (PlatformIsLittleEndian()) {
273 // perfect target for constexpr-if in C++17
274 // Alpha preset
275 GLuint OutPxl = 0xff000000;
276 GLuint Chan;
277 // Red
278 Chan = FiveToEight(InPxl >> 10);
279 OutPxl |= Chan;
280 // Green
281 Chan = FiveToEight(InPxl >> 5);
282 OutPxl |= Chan << 8;
283 // Blue
284 Chan = FiveToEight(InPxl & 0x1F);
285 OutPxl |= Chan << 16;
286 return OutPxl;
287 } else {
288 // Alpha preset
289 GLuint OutPxl = 0x000000ff;
290 GLuint Chan;
291 // Red
292 Chan = FiveToEight(InPxl >> 10);
293 OutPxl |= Chan << 24;
294 // Green
295 Chan = FiveToEight(InPxl >> 5);
296 OutPxl |= Chan << 16;
297 // Blue
298 Chan = FiveToEight(InPxl);
299 OutPxl |= Chan << 8;
300 return OutPxl;
301 }
302
303 }
304
305
306 // Make floating-point colors
MakeFloatColor(RGBColor & InColor,GLfloat * OutColor)307 inline void MakeFloatColor(RGBColor& InColor, GLfloat *OutColor)
308 {
309 OutColor[0] = InColor.red/65535.0F;
310 OutColor[1] = InColor.green/65535.0F;
311 OutColor[2] = InColor.blue/65535.0F;
312 }
313
MakeFloatColor(rgb_color & InColor,GLfloat * OutColor)314 inline void MakeFloatColor(rgb_color& InColor, GLfloat *OutColor)
315 {
316 OutColor[0] = InColor.red/65535.0F;
317 OutColor[1] = InColor.green/65535.0F;
318 OutColor[2] = InColor.blue/65535.0F;
319 }
320
321 /*
322 // Stuff for doing 16->32 pixel-format conversion, 1555 ARGB to 8888 RGBA
323 // The table is created only when necessary, and retained as long as it is necessary
324 extern GLuint *ConversionTable_16to32;
325
326 extern void MakeConversion_16to32(int BitDepth);
327 */
328
329 void LoadModelSkin(ImageDescriptor& Image, short Collection, short CLUT);
330
331 void SetPixelOpacities(OGL_TextureOptions& Options, ImageDescriptorManager &imageManager);
332
333 // Does this for a set of several pixel values or color-table values;
334 // the pixels are assumed to be in OpenGL-friendly byte-by-byte RGBA format.
335 void SetPixelOpacitiesRGBA(OGL_TextureOptions& Options, int NumPixels, uint32 *Pixels);
336
337 // Infravision (I'm blue, are you?)
338 bool& IsInfravisionActive();
339
340 // Sets the infravision tinting color for a shapes collection, and whether to use such tinting;
341 // the color values are from 0 to 1.
342 bool SetInfravisionTint(short Collection, bool IsTinted, float Red, float Green, float Blue);
343
344 void FindInfravisionVersion(short Collection, ImageDescriptorManager &imageManager);
345
346 // Finds the infravision version of a color;
347 // it makes no change if infravision is inactive.
348 void FindInfravisionVersionRGBA(short Collection, GLfloat *Color);
349
350 // Mass-production version of above; suitable for textures
351 void FindInfravisionVersionRGBA(short Collection, int NumPixels, uint32 *Pixels);
352
353 void FindSilhouetteVersion(ImageDescriptorManager &imageManager);
354
355 struct OGL_TexturesStats {
356 int inUse;
357 int binds, totalBind, minBind, maxBind;
358 int longNormalSetups, longGlowSetups, longBumpSetups;
359 int totalAge;
360 };
361
362 extern OGL_TexturesStats gGLTxStats;
363
364 #endif
365