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