29 #include "../idlib/precompiled.h"
48 for (pot = 1 ; pot <
num ; pot<<=1) {
61 switch ( internalFormat ) {
66 case GL_LUMINANCE8_ALPHA8:
101 common->
Error(
"R_BitsForInternalFormat: BAD FORMAT:%i", internalFormat );
122 row = width < 4 ? 4 :
width;
124 normals = (
byte *)_alloca( row * height );
126 common->
Error(
"R_UploadCompressedNormalMap: _alloca failed" );
131 for ( i = 0 ; i <
height ; i++, out +=
row, in += width * 4 ) {
132 for ( j = 0 ; j <
width ; j++ ) {
138 if ( x == 128 && y == 128 && z == 128 ) {
151 if ( mipLevel == 0 ) {
156 char *ext = strrchr(filename,
'.');
158 strcpy(ext,
"_pal.tga");
181 static byte mipBlendColors[16][4] = {
211 int rgbOr, rgbAnd, aOr, aAnd;
212 int rgbDiffer, rgbaDiffer;
224 *monochromeResult =
true;
226 for (
int side = 0 ; side < numDataPtrs ; side++ ) {
227 scan = dataPtrs[side];
228 for ( i = 0; i <
c; i++, scan += 4 ) {
234 cor = scan[0] | scan[1] | scan[2];
235 cand = scan[0] & scan[1] & scan[2];
238 rgbDiffer |= ( cor ^ cand );
243 if ( *monochromeResult ) {
244 if ( abs( scan[0] - scan[1] ) > 16
245 || abs( scan[0] - scan[2] ) > 16 ) {
246 *monochromeResult =
false;
256 rgbaDiffer |= ( cor ^ cand );
265 if ( aAnd == 255 || aOr == 0 ) {
272 if ( minimumDepth ==
TD_BUMP ) {
306 }
else if ( ( aAnd == 255 || aOr == 0 ) ) {
340 return GL_INTENSITY8;
348 if ( rgbAnd == 255 ) {
360 return GL_LUMINANCE8_ALPHA8;
450 while ( scaled_width > size || scaled_height > size ) {
451 if ( scaled_width > 1 ) {
454 if ( scaled_height > 1 ) {
461 if ( scaled_width < 1 ) {
464 if ( scaled_height < 1 ) {
514 int scaled_width, scaled_height;
534 preserveBorder =
true;
536 preserveBorder =
false;
543 if ( scaled_width != width || scaled_height != height ) {
544 common->
Error(
"R_CreateImage: not a power of 2 image" );
559 if ( ( scaled_width == width ) && ( scaled_height == height ) ) {
562 scaledBuffer = (
byte *)
R_StaticAlloc(
sizeof(
unsigned ) * scaled_width * scaled_height );
563 memcpy (scaledBuffer, pic, width*height*4);
567 scaledBuffer =
R_MipMap( pic, width, height, preserveBorder );
577 while ( width > scaled_width || height > scaled_height ) {
578 shrunk =
R_MipMap( scaledBuffer, width, height, preserveBorder );
580 scaledBuffer = shrunk;
593 scaled_width =
width;
606 rgba[0] = rgba[1] = rgba[2] = 0;
613 rgba[0] = rgba[1] = rgba[2] = 255;
622 char *ext = strrchr(filename,
'.');
624 strcpy( ext,
".tga" );
634 R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height,
false );
654 for (
int i = 0;
i < scaled_width * scaled_height * 4;
i += 4 ) {
655 scaledBuffer[
i + 3 ] = scaledBuffer[
i ];
656 scaledBuffer[
i ] = 0;
674 qglTexImage2D( GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
681 while ( scaled_width > 1 || scaled_height > 1 ) {
683 shrunk =
R_MipMap( scaledBuffer, scaled_width, scaled_height, preserveBorder );
685 scaledBuffer = shrunk;
689 if ( scaled_width < 1 ) {
692 if ( scaled_height < 1 ) {
709 qglTexImage2D( GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height,
710 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
714 if ( scaledBuffer != 0 ) {
733 int scaled_width, scaled_height, scaled_depth;
740 depth = minDepthParm;
754 if ( scaled_width != width || scaled_height != height || scaled_depth != picDepth ) {
755 common->
Error(
"R_Create3DImage: not a power of 2 image" );
777 qglTexImage3D(
GL_TEXTURE_3D, 0, internalFormat, scaled_width, scaled_height, scaled_depth,
778 0, GL_RGBA, GL_UNSIGNED_BYTE, pic );
782 byte *scaledBuffer, *shrunk;
784 scaledBuffer = (
byte *)
R_StaticAlloc( scaled_width * scaled_height * scaled_depth * 4 );
785 memcpy( scaledBuffer, pic, scaled_width * scaled_height * scaled_depth * 4 );
787 while ( scaled_width > 1 || scaled_height > 1 || scaled_depth > 1 ) {
789 shrunk =
R_MipMap3D( scaledBuffer, scaled_width, scaled_height, scaled_depth,
792 scaledBuffer = shrunk;
797 if ( scaled_width < 1 ) {
800 if ( scaled_height < 1 ) {
803 if ( scaled_depth < 1 ) {
809 qglTexImage3D(
GL_TEXTURE_3D, miplevel, internalFormat, scaled_width, scaled_height, scaled_depth,
810 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
869 int scaled_width, scaled_height;
893 width = height =
size;
902 scaled_width =
width;
934 for ( i = 0 ; i < 6 ; i++ ) {
936 GL_RGBA, GL_UNSIGNED_BYTE, pic[i] );
944 for ( i = 0 ; i < 6 ; i++ ) {
945 shrunk[
i] =
R_MipMap( pic[i], scaled_width, scaled_height,
false );
949 while ( scaled_width > 1 ) {
950 for ( i = 0 ; i < 6 ; i++ ) {
954 scaled_width / 2, scaled_height / 2, 0,
955 GL_RGBA, GL_UNSIGNED_BYTE, shrunk[i] );
957 if ( scaled_width > 2 ) {
958 shrunken =
R_MipMap( shrunk[i], scaled_width/2, scaled_height/2,
false );
964 shrunk[
i] = shrunken;
986 strcpy( fileName,
"dds/" );
987 f = fileName + strlen( fileName );
993 for ( s = imageProg ; *
s ; s++ ) {
994 if ( *s ==
'/' || *s ==
'\\' || *s ==
'(') {
1002 }
else if ( *s ==
'<' || *s ==
'>' || *s ==
':' || *s ==
'|' || *s ==
'"' || *s ==
'.' ) {
1005 }
else if ( *s ==
' ' && *(f-1) ==
'/' ) {
1006 }
else if ( *s ==
')' || *s ==
',' ) {
1013 strcat( fileName,
".dds" );
1024 while ( width > 1 || height > 1 ) {
1060 if ( numLevels > MAX_TEXTURE_LEVELS ) {
1061 common->
Warning(
"R_WritePrecompressedImage: level > MAX_TEXTURE_LEVELS for image %s", filename );
1067 int altInternalFormat = 0;
1069 switch ( internalFormat ) {
1071 case GL_COLOR_INDEX:
1074 altInternalFormat = GL_COLOR_INDEX;
1085 case GL_LUMINANCE8_ALPHA8:
1092 altInternalFormat = GL_ALPHA;
1096 if ( FormatIsDXT( internalFormat ) ) {
1099 common->
Warning(
"Unknown or unsupported format for %s", filename);
1106 idStr inFile = outFile;
1111 format =
"RXGB +red 0.0 +green 0.5 +blue 0.5";
1113 switch ( altInternalFormat ) {
1118 format =
"DXT1 -alpha_threshold";
1134 memset( &header, 0,
sizeof(header) );
1135 header.
dwSize =
sizeof(header);
1145 if ( FormatIsDXT( altInternalFormat ) ) {
1159 if ( numLevels > 1 ) {
1166 if ( FormatIsDXT( altInternalFormat ) ) {
1168 switch ( altInternalFormat ) {
1186 switch ( altInternalFormat ) {
1188 case GL_LUMINANCE_ALPHA:
1194 case GL_COLOR_INDEX:
1204 common->
Warning(
"Unknown or unsupported format for %s", filename );
1211 common->
Warning(
"Could not open %s trying to write precompressed image", filename );
1214 common->
Printf(
"Writing precompressed image: %s\n", filename );
1216 f->
Write(
"DDS ", 4 );
1217 f->
Write( &header,
sizeof(header) );
1233 if ( FormatIsDXT( altInternalFormat ) ) {
1234 size = ( ( uw + 3 ) / 4 ) * ( ( uh + 3 ) / 4 ) *
1237 size = uw * uh * (bitSize / 8);
1244 if ( FormatIsDXT( altInternalFormat ) ) {
1250 f->
Write( data, size );
1306 if (
timestamp == FILE_NOT_FOUND_TIMESTAMP ) {
1341 #if 1 // ( _D3XP had disabled ) - Allow grabbing of DDS's from original Doom pak files
1361 ID_TIME_T precompTimestamp;
1365 if ( precompTimestamp == FILE_NOT_FOUND_TIMESTAMP ) {
1398 f->
Read( data, len );
1402 unsigned long magic =
LittleLong( *(
unsigned long *)data );
1462 int externalFormat = 0;
1492 internalFormat = GL_RGBA8;
1495 internalFormat = GL_RGBA8;
1498 externalFormat = GL_COLOR_INDEX;
1502 internalFormat = GL_RGB8;
1505 externalFormat = GL_ALPHA;
1506 internalFormat = GL_ALPHA8;
1508 common->
Warning(
"Invalid uncompressed internal format\n" );
1535 for (
int i = 0 ;
i < numMipmaps;
i++ ) {
1537 if ( FormatIsDXT( internalFormat ) ) {
1538 size = ( ( uw + 3 ) / 4 ) * ( ( uh + 3 ) / 4 ) *
1547 if ( FormatIsDXT( internalFormat ) ) {
1550 qglTexImage2D( GL_TEXTURE_2D,
i - skipMip, internalFormat, uw, uh, 0, externalFormat, GL_UNSIGNED_BYTE, imagedata );
1605 if ( pics[0] ==
NULL ) {
1614 for (
int i = 0 ;
i < 6 ;
i++ ) {
1632 if ( pic ==
NULL ) {
1780 GLclampf priority = 1.0f;
1862 int potWidth, potHeight;
1878 if ( potWidth == imageWidth && potHeight == imageHeight ) {
1879 qglCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, x, y, imageWidth, imageHeight, 0 );
1886 memset( junk, 0, potWidth * potHeight * 4 );
1887 #if 0 // Disabling because it's unnecessary and introduces a green strip on edge of _currentRender
1888 for (
int i = 0 ;
i < potWidth * potHeight * 4 ;
i+=4 ) {
1892 qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, junk );
1904 if ( imageWidth != potWidth ) {
1907 if ( imageHeight != potHeight ) {
1931 int potWidth, potHeight;
1939 if ( potWidth == imageWidth && potHeight == imageHeight ) {
1940 qglCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, x, y, imageWidth, imageHeight, 0 );
1944 qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, potWidth, potHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,
NULL );
1971 if ( rows == cols * 6 ) {
1986 for ( i = 0 ; i < 6 ; i++ ) {
1988 GL_RGBA, GL_UNSIGNED_BYTE, data + cols*rows*4*i );
1993 for ( i = 0 ; i < 6 ; i++ ) {
1995 GL_RGBA, GL_UNSIGNED_BYTE, data + cols*rows*4*i );
2016 qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
2020 qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
2072 baseSize = baseSize * 4 / 3;
2126 switch ( internalFormat ) {
2132 case GL_LUMINANCE8_ALPHA8:
2174 case GL_COLOR_INDEX:
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
const unsigned long DDSF_ALPHAPIXELS
bool ShouldImageBePartialCached()
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
virtual bool PerformingCopyFiles(void) const =0
idStr & SetFileExtension(const char *extension)
idCVarSystem * cvarSystem
const unsigned long DDSF_LINEARSIZE
void GenerateImage(const byte *pic, int width, int height, textureFilter_t filter, bool allowDownSize, textureRepeat_t repeat, textureDepth_t depth)
#define GL_TEXTURE_LOD_BIAS_EXT
void GL_CheckErrors(void)
static idCVar image_useCompression
void GetDownsize(int &scaled_width, int &scaled_height) const
GLenum GLsizei GLenum format
const unsigned long DDSF_RGB
bool anisotropicAvailable
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
bool textureLODBiasAvailable
idCVar com_purgeAll("com_purgeAll","0", CVAR_BOOL|CVAR_ARCHIVE|CVAR_SYSTEM,"purge everything between level loads")
GLenum SelectInternalFormat(const byte **dataPtrs, int numDataPtrs, int width, int height, textureDepth_t minimumDepth, bool *monochromeResult) const
PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB
static idCVar image_downSizeBump
idFileSystem * fileSystem
idCVar com_machineSpec("com_machineSpec","-1", CVAR_INTEGER|CVAR_ARCHIVE|CVAR_SYSTEM,"hardware classification, -1 = not detected, 0 = low quality, 1 = medium quality, 2 = high quality, 3 = ultra quality")
const unsigned long DDSF_PITCH
#define GL_CLAMP_TO_BORDER
byte * R_MipMap(const byte *in, int width, int height, bool preserveBorder)
#define GL_TEXTURE_WRAP_R
GLint GLint GLsizei GLsizei GLsizei depth
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
const unsigned long DDSF_MIPMAP
const unsigned long DDSF_CAPS
void Generate3DImage(const byte *pic, int width, int height, int depth, textureFilter_t filter, bool allowDownSize, textureRepeat_t repeat, textureDepth_t minDepth)
GLuint GLuint GLsizei GLenum type
#define qglDeleteTextures
void SetClassification(int tag)
void R_LoadImageProgram(const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, textureDepth_t *depth=NULL)
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGB_ARB
bool sharedTexturePaletteAvailable
byte * R_MipMap3D(const byte *in, int width, int height, int depth, bool preserveBorder)
const int MAX_MULTITEXTURE_UNITS
#define GL_TEXTURE_MAX_ANISOTROPY_EXT
void CopyFramebuffer(int x, int y, int width, int height, bool useOversizedBuffer)
bool backgroundLoadInProgress
void R_BlendOverTexture(byte *data, int pixelCount, const byte blend[4])
int Icmpn(const char *text, int n) const
void GenerateCubeImage(const byte *pic[6], int size, textureFilter_t filter, bool allowDownSize, textureDepth_t depth)
idCVar com_makingBuild("com_makingBuild","0", CVAR_BOOL|CVAR_SYSTEM,"1 when making a build")
const unsigned long DDSF_HEIGHT
static idCVar image_forceDownSize
const unsigned long DDSF_FOURCC
#define DDS_MAKEFOURCC(a, b, c, d)
idStr & StripFileExtension(void)
const unsigned long DDSF_MIPMAPCOUNT
const unsigned long DDSF_WIDTH
void UploadScratch(const byte *pic, int width, int height)
void ActuallyLoadImage(bool checkForPrecompressed, bool fromBackEnd)
void R_WritePalTGA(const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical=false)
#define GL_COLOR_INDEX8_EXT
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT
static idCVar image_downSizeBumpLimit
static idCVar image_usePrecompressedTextures
GLsizei GLsizei GLenum GLenum const GLvoid * data
int GetInteger(void) const
void UploadCompressedNormalMap(int width, int height, const byte *rgba, int mipLevel)
const unsigned long DDSF_ID_MONOCHROME
idImageManager * globalImages
const unsigned long DDSF_RGBA
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
void StartBackgroundImageLoad()
static idCVar image_useNormalCompression
virtual int Read(void *buffer, int len)
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical=false)
void SetImageFilterAndRepeat() const
static idCVar image_writeTGA
unsigned long MD4_BlockChecksum(const void *data, int length)
#define qglCopyTexImage2D
static idCVar image_downSizeSpecular
static idCVar image_writeNormalTGA
virtual void Printf(const char *fmt,...) id_attribute((format(printf
static idCVar image_downSize
PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB
byte originalToCompressed[256]
GLenum GLsizei GLsizei height
static idCVar image_downSizeLimit
const unsigned long DDSF_TEXTURE
void R_SetBorderTexels(byte *inBase, int width, int height, const byte border[4])
virtual const char * RelativePathToOSPath(const char *relativePath, const char *basePath="fs_devpath")=0
void ImageProgramStringToCompressedFileName(const char *imageProg, char *fileName) const
void UploadPrecompressedImage(byte *data, int len)
static idCVar image_cacheMinK
void(* generatorFunction)(idImage *image)
void RB_LogComment(const char *comment,...)
#define GL_COMPRESSED_RGBA_ARB
#define qglCopyTexSubImage2D
bool textureCompressionAvailable
textureType_t textureType
const unsigned long DDSF_ID_INDEXCOLOR
GLenum GLenum GLvoid * row
static idCVar image_writeNormalTGAPalletized
void * R_StaticAlloc(int bytes)
idCVar com_videoRam("com_videoRam","64", CVAR_INTEGER|CVAR_SYSTEM|CVAR_NOCHEAT|CVAR_ARCHIVE,"holds the last amount of detected video ram")
static idCVar image_useAllFormats
virtual int Write(const void *buffer, int len)
const char * c_str(void) const
static const int TEXTURE_NOT_LOADED
virtual bool GetCVarBool(const char *name) const =0
#define GL_TEXTURE_CUBE_MAP_EXT
void AddDDSCommand(const char *cmd)
static idCVar image_useCache
int MakePowerOfTwo(int num)
void * Mem_Alloc(const int size)
if(!ValidDisplayID(prefInfo.prefDisplayID)) prefInfo.prefDisplayID
char * va(const char *fmt,...)
virtual void CloseFile(idFile *f)=0
void R_StaticFree(void *data)
int BitsForInternalFormat(int internalFormat) const
virtual void Error(const char *fmt,...) id_attribute((format(printf
bool CheckPrecompressedImage(bool fullLoad)
#define GL_TEXTURE_RECTANGLE_NV
int NumLevelsForImageSize(int width, int height) const
void WritePrecompressedImage()
void CopyDepthbuffer(int x, int y, int width, int height)
bool R_LoadCubeImages(const char *cname, cubeFiles_t extensions, byte *pic[6], int *size, ID_TIME_T *timestamp)
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
static idCVar image_useOffLineCompression
static idCVar image_colorMipLevels
static idCVar image_writePrecompressedTextures
const unsigned long DDSF_COMPLEX
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
static idCVar image_downSizeSpecularLimit
const unsigned long DDSF_PIXELFORMAT
#define qglPrioritizeTextures
tmu_t tmu[MAX_MULTITEXTURE_UNITS]
byte compressedPalette[768]