1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #ifndef __IMAGE_H__
30 #define __IMAGE_H__
31
32 #include "idlib/containers/List.h"
33 #include "framework/FileSystem.h"
34 #include "renderer/Material.h"
35 #include "renderer/qgl.h"
36
37 /*
38 ====================================================================
39
40 IMAGE
41
42 idImage have a one to one correspondance with OpenGL textures.
43
44 No texture is ever used that does not have a corresponding idImage.
45
46 no code outside this unit should call any of these OpenGL functions:
47
48 qglGenTextures
49 qglDeleteTextures
50 qglBindTexture
51
52 qglTexParameter
53
54 qglTexImage
55 qglTexSubImage
56
57 qglCopyTexImage
58 qglCopyTexSubImage
59
60 qglEnable( GL_TEXTURE_* )
61 qglDisable( GL_TEXTURE_* )
62
63 ====================================================================
64 */
65
66 typedef enum {
67 IS_UNLOADED, // no gl texture number
68 IS_PARTIAL, // has a texture number and the low mip levels loaded
69 IS_LOADED // has a texture number and the full mip hierarchy
70 } imageState_t;
71
72 static const int MAX_TEXTURE_LEVELS = 14;
73
74 // surface description flags
75 const unsigned int DDSF_CAPS = 0x00000001l;
76 const unsigned int DDSF_HEIGHT = 0x00000002l;
77 const unsigned int DDSF_WIDTH = 0x00000004l;
78 const unsigned int DDSF_PITCH = 0x00000008l;
79 const unsigned int DDSF_PIXELFORMAT = 0x00001000l;
80 const unsigned int DDSF_MIPMAPCOUNT = 0x00020000l;
81 const unsigned int DDSF_LINEARSIZE = 0x00080000l;
82 const unsigned int DDSF_DEPTH = 0x00800000l;
83
84 // pixel format flags
85 const unsigned int DDSF_ALPHAPIXELS = 0x00000001l;
86 const unsigned int DDSF_FOURCC = 0x00000004l;
87 const unsigned int DDSF_RGB = 0x00000040l;
88 const unsigned int DDSF_RGBA = 0x00000041l;
89
90 // our extended flags
91 const unsigned int DDSF_ID_INDEXCOLOR = 0x10000000l;
92 const unsigned int DDSF_ID_MONOCHROME = 0x20000000l;
93
94 // dwCaps1 flags
95 const unsigned int DDSF_COMPLEX = 0x00000008l;
96 const unsigned int DDSF_TEXTURE = 0x00001000l;
97 const unsigned int DDSF_MIPMAP = 0x00400000l;
98
99 #define DDS_MAKEFOURCC(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
100
101 typedef struct {
102 unsigned int dwSize;
103 unsigned int dwFlags;
104 unsigned int dwFourCC;
105 unsigned int dwRGBBitCount;
106 unsigned int dwRBitMask;
107 unsigned int dwGBitMask;
108 unsigned int dwBBitMask;
109 unsigned int dwABitMask;
110 } ddsFilePixelFormat_t;
111
112 typedef struct
113 {
114 unsigned int dwSize;
115 unsigned int dwFlags;
116 unsigned int dwHeight;
117 unsigned int dwWidth;
118 unsigned int dwPitchOrLinearSize;
119 unsigned int dwDepth;
120 unsigned int dwMipMapCount;
121 unsigned int dwReserved1[11];
122 ddsFilePixelFormat_t ddspf;
123 unsigned int dwCaps1;
124 unsigned int dwCaps2;
125 unsigned int dwReserved2[3];
126 } ddsFileHeader_t;
127
128
129 // increasing numeric values imply more information is stored
130 typedef enum {
131 TD_SPECULAR, // may be compressed, and always zeros the alpha channel
132 TD_DIFFUSE, // may be compressed
133 TD_DEFAULT, // will use compressed formats when possible
134 TD_BUMP, // may be compressed with 8 bit lookup
135 TD_HIGH_QUALITY // either 32 bit or a component format, no loss at all
136 } textureDepth_t;
137
138 typedef enum {
139 TT_DISABLED,
140 TT_2D,
141 TT_3D,
142 TT_CUBIC,
143 TT_RECT
144 } textureType_t;
145
146 typedef enum {
147 CF_2D, // not a cube map
148 CF_NATIVE, // _px, _nx, _py, etc, directly sent to GL
149 CF_CAMERA // _forward, _back, etc, rotated and flipped as needed before sending to GL
150 } cubeFiles_t;
151
152 #define MAX_IMAGE_NAME 256
153
154 class idImage {
155 public:
156 idImage();
157
158 // Makes this image active on the current GL texture unit.
159 // automatically enables or disables cube mapping or texture3D
160 // May perform file loading if the image was not preloaded.
161 // May start a background image read.
162 void Bind();
163
164 // for use with fragment programs, doesn't change any enable2D/3D/cube states
165 void BindFragment();
166
167 // deletes the texture object, but leaves the structure so it can be reloaded
168 void PurgeImage();
169
170 // used by callback functions to specify the actual data
171 // data goes from the bottom to the top line of the image, as OpenGL expects it
172 // These perform an implicit Bind() on the current texture unit
173 // FIXME: should we implement cinematics this way, instead of with explicit calls?
174 void GenerateImage( const byte *pic, int width, int height,
175 textureFilter_t filter, bool allowDownSize,
176 textureRepeat_t repeat, textureDepth_t depth );
177 void Generate3DImage( const byte *pic, int width, int height, int depth,
178 textureFilter_t filter, bool allowDownSize,
179 textureRepeat_t repeat, textureDepth_t minDepth );
180 void GenerateCubeImage( const byte *pic[6], int size,
181 textureFilter_t filter, bool allowDownSize,
182 textureDepth_t depth );
183
184 void CopyFramebuffer( int x, int y, int width, int height, bool useOversizedBuffer );
185
186 void CopyDepthbuffer( int x, int y, int width, int height );
187
188 void UploadScratch( const byte *pic, int width, int height );
189
190 // just for resource tracking
191 void SetClassification( int tag );
192
193 // estimates size of the GL image based on dimensions and storage type
194 int StorageSize() const;
195
196 // print a one line summary of the image
197 void Print() const;
198
199 // check for changed timestamp on disk and reload if necessary
200 void Reload( bool checkPrecompressed, bool force );
201
AddReference()202 void AddReference() { refCount++; };
203
204 //==========================================================
205
206 void GetDownsize( int &scaled_width, int &scaled_height ) const;
207 void MakeDefault(); // fill with a grid pattern
208 void SetImageFilterAndRepeat() const;
209 bool ShouldImageBePartialCached();
210 void WritePrecompressedImage();
211 bool CheckPrecompressedImage( bool fullLoad );
212 void UploadPrecompressedImage( byte *data, int len );
213 void ActuallyLoadImage( bool checkForPrecompressed, bool fromBackEnd );
214 void StartBackgroundImageLoad();
215 int BitsForInternalFormat( int internalFormat ) const;
216 void UploadCompressedNormalMap( int width, int height, const byte *rgba, int mipLevel );
217 GLenum SelectInternalFormat( const byte **dataPtrs, int numDataPtrs, int width, int height,
218 textureDepth_t minimumDepth ) const;
219 void ImageProgramStringToCompressedFileName( const char *imageProg, char *fileName ) const;
220 int NumLevelsForImageSize( int width, int height ) const;
221
222 // data commonly accessed is grouped here
223 static const int TEXTURE_NOT_LOADED = -1;
224 GLuint texnum; // gl texture binding, will be TEXTURE_NOT_LOADED if not loaded
225 textureType_t type;
226 int frameUsed; // for texture usage in frame statistics
227 int bindCount; // incremented each bind
228
229 // background loading information
230 idImage *partialImage; // shrunken, space-saving version
231 bool isPartialImage; // true if this is pointed to by another image
232 bool backgroundLoadInProgress; // true if another thread is reading the complete d3t file
233 backgroundDownload_t bgl;
234 idImage * bglNext; // linked from tr.backgroundImageLoads
235
236 // parameters that define this image
237 idStr imgName; // game path, including extension (except for cube maps), may be an image program
238 void (*generatorFunction)( idImage *image ); // NULL for files
239 bool allowDownSize; // this also doubles as a don't-partially-load flag
240 textureFilter_t filter;
241 textureRepeat_t repeat;
242 textureDepth_t depth;
243 cubeFiles_t cubeFiles; // determines the naming and flipping conventions for the six images
244
245 bool referencedOutsideLevelLoad;
246 bool levelLoadReferenced; // for determining if it needs to be purged
247 bool precompressedFile; // true when it was loaded from a .d3t file
248 bool defaulted; // true if the default image was generated because a file couldn't be loaded
249 ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command
250
251 int imageHash; // for identical-image checking
252
253 int classification; // just for resource profiling
254
255 // data for listImages
256 int uploadWidth, uploadHeight, uploadDepth; // after power of two, downsample, and MAX_TEXTURE_SIZE
257 int internalFormat;
258
259 idImage *cacheUsagePrev, *cacheUsageNext; // for dynamic cache purging of old images
260
261 idImage * hashNext; // for hash chains to speed lookup
262
263 int refCount; // overall ref count
264 };
265
idImage()266 ID_INLINE idImage::idImage() {
267 texnum = TEXTURE_NOT_LOADED;
268 partialImage = NULL;
269 type = TT_DISABLED;
270 isPartialImage = false;
271 frameUsed = 0;
272 classification = 0;
273 backgroundLoadInProgress = false;
274 bgl.opcode = DLTYPE_FILE;
275 bgl.f = NULL;
276 bglNext = NULL;
277 imgName[0] = '\0';
278 generatorFunction = NULL;
279 allowDownSize = false;
280 filter = TF_DEFAULT;
281 repeat = TR_REPEAT;
282 depth = TD_DEFAULT;
283 cubeFiles = CF_2D;
284 referencedOutsideLevelLoad = false;
285 levelLoadReferenced = false;
286 precompressedFile = false;
287 defaulted = false;
288 timestamp = 0;
289 bindCount = 0;
290 uploadWidth = uploadHeight = uploadDepth = 0;
291 internalFormat = 0;
292 cacheUsagePrev = cacheUsageNext = NULL;
293 hashNext = NULL;
294 refCount = 0;
295 }
296
297
298 // data is RGBA
299 void R_WriteTGA( const char *filename, const byte *data, int width, int height, bool flipVertical = false );
300 // data is an 8 bit index into palette, which is RGB (no A)
301 void R_WritePalTGA( const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical = false );
302 // data is in top-to-bottom raster order unless flipVertical is set
303
304
305 class idImageManager {
306 public:
307 void Init();
308 void Shutdown();
309
310 // If the exact combination of parameters has been asked for already, an existing
311 // image will be returned, otherwise a new image will be created.
312 // Be careful not to use the same image file with different filter / repeat / etc parameters
313 // if possible, because it will cause a second copy to be loaded.
314 // If the load fails for any reason, the image will be filled in with the default
315 // grid pattern.
316 // Will automatically resample non-power-of-two images and execute image programs if needed.
317 idImage * ImageFromFile( const char *name,
318 textureFilter_t filter, bool allowDownSize,
319 textureRepeat_t repeat, textureDepth_t depth, cubeFiles_t cubeMap = CF_2D );
320
321 // look for a loaded image, whatever the parameters
322 idImage * GetImage( const char *name ) const;
323
324 // The callback will be issued immediately, and later if images are reloaded or vid_restart
325 // The callback function should call one of the idImage::Generate* functions to fill in the data
326 idImage * ImageFromFunction( const char *name, void (*generatorFunction)( idImage *image ));
327
328 // called once a frame to allow any background loads that have been completed
329 // to turn into textures.
330 void CompleteBackgroundImageLoads();
331
332 // returns the number of bytes of image data bound in the previous frame
333 int SumOfUsedImages();
334
335 // called each frame to allow some cvars to automatically force changes
336 void CheckCvars();
337
338 // purges all the images before a vid_restart
339 void PurgeAllImages();
340
341 // reloads all apropriate images after a vid_restart
342 void ReloadAllImages();
343
344 // disable the active texture unit
345 void BindNull();
346
347 // Mark all file based images as currently unused,
348 // but don't free anything. Calls to ImageFromFile() will
349 // either mark the image as used, or create a new image without
350 // loading the actual data.
351 // Called only by renderSystem::BeginLevelLoad
352 void BeginLevelLoad();
353
354 // Free all images marked as unused, and load all images that are necessary.
355 // This architecture prevents us from having the union of two level's
356 // worth of data present at one time.
357 // Called only by renderSystem::EndLevelLoad
358 void EndLevelLoad();
359
360 // used to clear and then write the dds conversion batch file
361 void StartBuild();
362 void FinishBuild( bool removeDups = false );
363 void AddDDSCommand( const char *cmd );
364
365 void PrintMemInfo( MemInfo_t *mi );
366
367 // cvars
368 static idCVar image_roundDown; // round bad sizes down to nearest power of two
369 static idCVar image_colorMipLevels; // development aid to see texture mip usage
370 static idCVar image_downSize; // controls texture downsampling
371 static idCVar image_useCompression; // 0 = force everything to high quality
372 static idCVar image_filter; // changes texture filtering on mipmapped images
373 static idCVar image_anisotropy; // set the maximum texture anisotropy if available
374 static idCVar image_lodbias; // change lod bias on mipmapped images
375 static idCVar image_useAllFormats; // allow alpha/intensity/luminance/luminance+alpha
376 static idCVar image_usePrecompressedTextures; // use .dds files if present
377 static idCVar image_writePrecompressedTextures; // write .dds files if necessary
378 static idCVar image_writeNormalTGA; // debug tool to write out .tgas of the final normal maps
379 static idCVar image_writeNormalTGAPalletized; // debug tool to write out palletized versions of the final normal maps
380 static idCVar image_writeTGA; // debug tool to write out .tgas of the non normal maps
381 static idCVar image_useNormalCompression; // 1 = use 256 color compression for normal maps if available, 2 = use rxgb compression
382 static idCVar image_useOffLineCompression; // will write a batch file with commands for the offline compression
383 static idCVar image_preload; // if 0, dynamically load all images
384 static idCVar image_cacheMinK; // maximum K of precompressed files to read at specification time,
385 // the remainder will be dynamically cached
386 static idCVar image_cacheMegs; // maximum bytes set aside for temporary loading of full-sized precompressed images
387 static idCVar image_useCache; // 1 = do background load image caching
388 static idCVar image_showBackgroundLoads; // 1 = print number of outstanding background loads
389 static idCVar image_forceDownSize; // allows the ability to force a downsize
390 static idCVar image_downSizeSpecular; // downsize specular
391 static idCVar image_downSizeSpecularLimit;// downsize specular limit
392 static idCVar image_downSizeBump; // downsize bump maps
393 static idCVar image_downSizeBumpLimit; // downsize bump limit
394 static idCVar image_ignoreHighQuality; // ignore high quality on materials
395 static idCVar image_downSizeLimit; // downsize diffuse limit
396
397 // built-in images
398 idImage * defaultImage;
399 idImage * flatNormalMap; // 128 128 255 in all pixels
400 idImage * ambientNormalMap; // tr.ambientLightVector encoded in all pixels
401 idImage * rampImage; // 0-255 in RGBA in S
402 idImage * alphaRampImage; // 0-255 in alpha, 255 in RGB
403 idImage * alphaNotchImage; // 2x1 texture with just 1110 and 1111 with point sampling
404 idImage * whiteImage; // full of 0xff
405 idImage * blackImage; // full of 0x00
406 idImage * normalCubeMapImage; // cube map to normalize STR into RGB
407 idImage * noFalloffImage; // all 255, but zero clamped
408 idImage * fogImage; // increasing alpha is denser fog
409 idImage * fogEnterImage; // adjust fogImage alpha based on terminator plane
410 idImage * cinematicImage;
411 idImage * scratchImage;
412 idImage * scratchImage2;
413 idImage * accumImage;
414 idImage * currentRenderImage; // for SS_POST_PROCESS shaders
415 idImage * scratchCubeMapImage;
416 idImage * specularTableImage; // 1D intensity texture with our specular function
417 idImage * specular2DTableImage; // 2D intensity texture with our specular function with variable specularity
418 idImage * borderClampImage; // white inside, black outside
419
420 //--------------------------------------------------------
421
422 idImage * AllocImage( const char *name );
423 void SetNormalPalette();
424 void ChangeTextureFilter();
425
426 idList<idImage*> images;
427 idStrList ddsList;
428 idHashIndex ddsHash;
429
430 bool insideLevelLoad; // don't actually load images now
431
432 byte originalToCompressed[256]; // maps normal maps to 8 bit textures
433 byte compressedPalette[768]; // the palette that normal maps use
434
435 // default filter modes for images
436 GLenum textureMinFilter;
437 GLenum textureMaxFilter;
438 float textureAnisotropy;
439 float textureLODBias;
440
441 idImage * imageHashTable[FILE_HASH_SIZE];
442
443 idImage * backgroundImageLoads; // chain of images that have background file loads active
444 idImage cacheLRU; // head/tail of doubly linked list
445 int totalCachedImageSize; // for determining when something should be purged
446
447 int numActiveBackgroundImageLoads;
448 const static int MAX_BACKGROUND_IMAGE_LOADS = 8;
449 };
450
451 extern idImageManager *globalImages; // pointer to global list for the rest of the system
452
453 int MakePowerOfTwo( int num );
454
455 /*
456 ====================================================================
457
458 IMAGEPROCESS
459
460 FIXME: make an "imageBlock" type to hold byte*,width,height?
461 ====================================================================
462 */
463
464 byte *R_Dropsample( const byte *in, int inwidth, int inheight,
465 int outwidth, int outheight );
466 byte *R_ResampleTexture( const byte *in, int inwidth, int inheight,
467 int outwidth, int outheight );
468 byte *R_MipMapWithAlphaSpecularity( const byte *in, int width, int height );
469 byte *R_MipMap( const byte *in, int width, int height, bool preserveBorder );
470 byte *R_MipMap3D( const byte *in, int width, int height, int depth, bool preserveBorder );
471
472 // these operate in-place on the provided pixels
473 void R_SetBorderTexels( byte *inBase, int width, int height, const byte border[4] );
474 void R_SetBorderTexels3D( byte *inBase, int width, int height, int depth, const byte border[4] );
475 void R_BlendOverTexture( byte *data, int pixelCount, const byte blend[4] );
476 void R_HorizontalFlip( byte *data, int width, int height );
477 void R_VerticalFlip( byte *data, int width, int height );
478 void R_RotatePic( byte *data, int width );
479
480 /*
481 ====================================================================
482
483 IMAGEFILES
484
485 ====================================================================
486 */
487
488 void R_LoadImage( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 );
489 // pic is in top to bottom raster format
490 bool R_LoadCubeImages( const char *cname, cubeFiles_t extensions, byte *pic[6], int *size, ID_TIME_T *timestamp );
491
492 /*
493 ====================================================================
494
495 IMAGEPROGRAM
496
497 ====================================================================
498 */
499
500 void R_LoadImageProgram( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, textureDepth_t *depth = NULL );
501 const char *R_ParsePastImageProgram( idLexer &src );
502
503 #endif
504