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