DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
r_textures.h File Reference
#include "qtypes.h"
#include "qdefs.h"
+ Include dependency graph for r_textures.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rtexture_t
 
struct  rtexturepool_t
 
struct  skinframe_t
 

Macros

#define R_GetTexture(rt)
 
#define TEXF_ALLOWUPDATES   0x00002000
 
#define TEXF_ALPHA   0x00000001
 
#define TEXF_CLAMP   0x00000020
 
#define TEXF_COMPARE   0x00000800
 
#define TEXF_COMPRESS   0x00000200
 
#define TEXF_FORCE_RELOAD   0x80000000
 
#define TEXF_FORCELINEAR   0x00000080
 
#define TEXF_FORCENEAREST   0x00000040
 
#define TEXF_IMPORTANTBITS   (TEXF_ALPHA | TEXF_MIPMAP | TEXF_RGBMULTIPLYBYALPHA | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP | TEXF_COMPARE | TEXF_LOWPRECISION | TEXF_RENDERTARGET)
 
#define TEXF_ISSPRITE   0x00008000
 
#define TEXF_ISWORLD   0x00004000
 
#define TEXF_LOWPRECISION   0x00001000
 
#define TEXF_MIPMAP   0x00000002
 
#define TEXF_PERSISTENT   0x00000400
 
#define TEXF_PICMIP   0x00000100
 
#define TEXF_RENDERTARGET   0x0010000
 
#define TEXF_RGBMULTIPLYBYALPHA   0x00000004
 

Typedefs

typedef void(* updatecallback_t) (rtexture_t *rt, void *data)
 

Enumerations

enum  textype_t {
  TEXTYPE_UNUSED , TEXTYPE_PALETTE , TEXTYPE_RGBA , TEXTYPE_BGRA ,
  TEXTYPE_ALPHA , TEXTYPE_DXT1 , TEXTYPE_DXT1A , TEXTYPE_DXT3 ,
  TEXTYPE_DXT5 , TEXTYPE_ETC1 , TEXTYPE_SRGB_PALETTE , TEXTYPE_SRGB_RGBA ,
  TEXTYPE_SRGB_BGRA , TEXTYPE_SRGB_DXT1 , TEXTYPE_SRGB_DXT1A , TEXTYPE_SRGB_DXT3 ,
  TEXTYPE_SRGB_DXT5 , TEXTYPE_COLORBUFFER , TEXTYPE_COLORBUFFER16F , TEXTYPE_COLORBUFFER32F ,
  TEXTYPE_DEPTHBUFFER16 , TEXTYPE_DEPTHBUFFER24 , TEXTYPE_DEPTHBUFFER24STENCIL8 , TEXTYPE_SHADOWMAP16_COMP ,
  TEXTYPE_SHADOWMAP16_RAW , TEXTYPE_SHADOWMAP24_COMP , TEXTYPE_SHADOWMAP24_RAW
}
 

Functions

rtexturepool_tR_AllocTexturePool (void)
 
void R_ClearTexture (rtexture_t *rt)
 
void R_FreeTexture (rtexture_t *rt)
 
void R_FreeTexturePool (rtexturepool_t **rtexturepool)
 
rtexture_tR_LoadTexture2D (rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
 
rtexture_tR_LoadTexture3D (rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
 
rtexture_tR_LoadTextureCubeMap (rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
 
rtexture_tR_LoadTextureDDSFile (rtexturepool_t *rtexturepool, const char *filename, qbool srgb, int flags, qbool *hasalphaflag, float *avgcolor, int miplevel, qbool optionaltexture)
 
rtexture_tR_LoadTextureRenderBuffer (rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype)
 
rtexture_tR_LoadTextureShadowMap2D (rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype, qbool filter)
 
void R_MakeTextureDynamic (rtexture_t *rt, updatecallback_t updatecallback, void *data)
 
void R_MarkDirtyTexture (rtexture_t *rt)
 
int R_PicmipForFlags (int flags)
 
void R_PurgeTexture (rtexture_t *prt)
 
int R_RealGetTexture (rtexture_t *rt)
 
int R_SaveTextureDDSFile (rtexture_t *rt, const char *filename, qbool skipuncompressed, qbool hasalpha)
 
int R_TextureFlags (rtexture_t *rt)
 
int R_TextureHeight (rtexture_t *rt)
 
void R_Textures_Frame (void)
 
void R_TextureStats_Print (qbool printeach, qbool printpool, qbool printtotal)
 
int R_TextureWidth (rtexture_t *rt)
 
void R_UpdateTexture (rtexture_t *rt, const unsigned char *data, int x, int y, int z, int width, int height, int depth, int combine)
 

Variables

struct cvar_s gl_texturecompression
 
struct cvar_s gl_texturecompression_2d
 
struct cvar_s gl_texturecompression_color
 
struct cvar_s gl_texturecompression_gloss
 
struct cvar_s gl_texturecompression_glow
 
struct cvar_s gl_texturecompression_lightcubemaps
 
struct cvar_s gl_texturecompression_normal
 
struct cvar_s gl_texturecompression_q3bspdeluxemaps
 
struct cvar_s gl_texturecompression_q3bsplightmaps
 
struct cvar_s gl_texturecompression_reflectmask
 
struct cvar_s gl_texturecompression_sky
 
struct cvar_s r_texture_dds_load
 
struct cvar_s r_texture_dds_save
 

Macro Definition Documentation

◆ R_GetTexture

#define R_GetTexture ( rt)
Value:
((rt) ? ((rt)->dirty ? R_RealGetTexture(rt) : (rt)->texnum) : r_texture_white->texnum)
rtexture_t * r_texture_white
Definition gl_rmain.c:273
int R_RealGetTexture(rtexture_t *rt)

Definition at line 214 of file r_textures.h.

Referenced by R_Mesh_TexBind().

◆ TEXF_ALLOWUPDATES

#define TEXF_ALLOWUPDATES   0x00002000

Definition at line 31 of file r_textures.h.

Referenced by Mod_Q1BSP_LoadFaces(), Mod_VBSP_LoadFaces(), and R_SetupTexture().

◆ TEXF_ALPHA

◆ TEXF_CLAMP

◆ TEXF_COMPARE

#define TEXF_COMPARE   0x00000800

Definition at line 27 of file r_textures.h.

◆ TEXF_COMPRESS

◆ TEXF_FORCE_RELOAD

#define TEXF_FORCE_RELOAD   0x80000000

◆ TEXF_FORCELINEAR

◆ TEXF_FORCENEAREST

◆ TEXF_IMPORTANTBITS

◆ TEXF_ISSPRITE

#define TEXF_ISSPRITE   0x00008000

◆ TEXF_ISWORLD

#define TEXF_ISWORLD   0x00004000

◆ TEXF_LOWPRECISION

#define TEXF_LOWPRECISION   0x00001000

Definition at line 29 of file r_textures.h.

◆ TEXF_MIPMAP

◆ TEXF_PERSISTENT

#define TEXF_PERSISTENT   0x00000400

◆ TEXF_PICMIP

◆ TEXF_RENDERTARGET

◆ TEXF_RGBMULTIPLYBYALPHA

#define TEXF_RGBMULTIPLYBYALPHA   0x00000004

Typedef Documentation

◆ updatecallback_t

typedef void(* updatecallback_t) (rtexture_t *rt, void *data)

Definition at line 168 of file r_textures.h.

Enumeration Type Documentation

◆ textype_t

enum textype_t
Enumerator
TEXTYPE_UNUSED 
TEXTYPE_PALETTE 
TEXTYPE_RGBA 
TEXTYPE_BGRA 
TEXTYPE_ALPHA 
TEXTYPE_DXT1 
TEXTYPE_DXT1A 
TEXTYPE_DXT3 
TEXTYPE_DXT5 
TEXTYPE_ETC1 
TEXTYPE_SRGB_PALETTE 
TEXTYPE_SRGB_RGBA 
TEXTYPE_SRGB_BGRA 
TEXTYPE_SRGB_DXT1 
TEXTYPE_SRGB_DXT1A 
TEXTYPE_SRGB_DXT3 
TEXTYPE_SRGB_DXT5 
TEXTYPE_COLORBUFFER 
TEXTYPE_COLORBUFFER16F 
TEXTYPE_COLORBUFFER32F 
TEXTYPE_DEPTHBUFFER16 
TEXTYPE_DEPTHBUFFER24 
TEXTYPE_DEPTHBUFFER24STENCIL8 
TEXTYPE_SHADOWMAP16_COMP 
TEXTYPE_SHADOWMAP16_RAW 
TEXTYPE_SHADOWMAP24_COMP 
TEXTYPE_SHADOWMAP24_RAW 

Definition at line 43 of file r_textures.h.

44{
45 // placeholder for unused textures in r_rendertarget_t
47
48 // 8bit paletted
50 // 32bit RGBA
52 // 32bit BGRA (preferred format due to faster uploads on most hardware)
54 // 8bit ALPHA (used for freetype fonts)
56 // 4x4 block compressed 15bit color (4 bits per pixel)
58 // 4x4 block compressed 15bit color plus 1bit alpha (4 bits per pixel)
60 // 4x4 block compressed 15bit color plus 8bit alpha (8 bits per pixel)
62 // 4x4 block compressed 15bit color plus 8bit alpha (8 bits per pixel)
64
65 // default compressed type for GLES2
67
68 // 8bit paletted in sRGB colorspace
70 // 32bit RGBA in sRGB colorspace
72 // 32bit BGRA (preferred format due to faster uploads on most hardware) in sRGB colorspace
74 // 4x4 block compressed 15bit color (4 bits per pixel) in sRGB colorspace
76 // 4x4 block compressed 15bit color plus 1bit alpha (4 bits per pixel) in sRGB colorspace
78 // 4x4 block compressed 15bit color plus 8bit alpha (8 bits per pixel) in sRGB colorspace
80 // 4x4 block compressed 15bit color plus 8bit alpha (8 bits per pixel) in sRGB colorspace
82
83 // this represents the same format as the framebuffer, for fast copies
85 // this represents an RGBA half_float texture (4 16bit floats)
87 // this represents an RGBA float texture (4 32bit floats)
89 // depth-stencil buffer (or texture)
91 // depth-stencil buffer (or texture)
93 // 32bit D24S8 buffer (24bit depth, 8bit stencil), not supported on OpenGL ES
95 // shadowmap-friendly format with depth comparison (not supported on some hardware)
97 // shadowmap-friendly format with raw reading (not supported on some hardware)
99 // shadowmap-friendly format with depth comparison (not supported on some hardware)
101 // shadowmap-friendly format with raw reading (not supported on some hardware)
103}
@ TEXTYPE_SRGB_DXT1
Definition r_textures.h:75
@ TEXTYPE_DXT5
Definition r_textures.h:63
@ TEXTYPE_PALETTE
Definition r_textures.h:49
@ TEXTYPE_ETC1
Definition r_textures.h:66
@ TEXTYPE_SHADOWMAP16_RAW
Definition r_textures.h:98
@ TEXTYPE_SRGB_BGRA
Definition r_textures.h:73
@ TEXTYPE_ALPHA
Definition r_textures.h:55
@ TEXTYPE_SRGB_RGBA
Definition r_textures.h:71
@ TEXTYPE_COLORBUFFER
Definition r_textures.h:84
@ TEXTYPE_DXT1
Definition r_textures.h:57
@ TEXTYPE_SHADOWMAP16_COMP
Definition r_textures.h:96
@ TEXTYPE_SRGB_DXT5
Definition r_textures.h:81
@ TEXTYPE_SRGB_PALETTE
Definition r_textures.h:69
@ TEXTYPE_SRGB_DXT3
Definition r_textures.h:79
@ TEXTYPE_COLORBUFFER32F
Definition r_textures.h:88
@ TEXTYPE_DEPTHBUFFER24
Definition r_textures.h:92
@ TEXTYPE_DXT1A
Definition r_textures.h:59
@ TEXTYPE_UNUSED
Definition r_textures.h:46
@ TEXTYPE_DEPTHBUFFER16
Definition r_textures.h:90
@ TEXTYPE_BGRA
Definition r_textures.h:53
@ TEXTYPE_DXT3
Definition r_textures.h:61
@ TEXTYPE_SRGB_DXT1A
Definition r_textures.h:77
@ TEXTYPE_RGBA
Definition r_textures.h:51
@ TEXTYPE_SHADOWMAP24_RAW
Definition r_textures.h:102
@ TEXTYPE_DEPTHBUFFER24STENCIL8
Definition r_textures.h:94
@ TEXTYPE_SHADOWMAP24_COMP
Definition r_textures.h:100
@ TEXTYPE_COLORBUFFER16F
Definition r_textures.h:86

Function Documentation

◆ R_AllocTexturePool()

rtexturepool_t * R_AllocTexturePool ( void )

Definition at line 389 of file gl_textures.c.

390{
391 gltexturepool_t *pool;
392 if (texturemempool == NULL)
393 return NULL;
395 if (pool == NULL)
396 return NULL;
397 pool->next = gltexturepoolchain;
398 gltexturepoolchain = pool;
400 return (rtexturepool_t *)pool;
401}
static gltexturepool_t * gltexturepoolchain
static mempool_t * texturemempool
Definition gl_textures.c:58
#define TEXTUREPOOL_SENTINEL
#define NULL
Definition qtypes.h:12
unsigned int sentinel
struct gltexturepool_s * next
#define Mem_Alloc(pool, size)
Definition zone.h:92

References gltexturepoolchain, Mem_Alloc, gltexturepool_t::next, NULL, gltexturepool_t::sentinel, texturemempool, and TEXTUREPOOL_SENTINEL.

Referenced by cl_video_start(), gl_draw_start(), gl_main_start(), Mod_GenerateLightmaps_CreateLightmaps(), Mod_Mesh_Create(), Mod_Q1BSP_LoadFaces(), Mod_Q1BSP_LoadSplitSky(), Mod_Q3BSP_Load(), Mod_VBSP_Load(), Mod_VBSP_LoadFaces(), r_explosion_start(), r_part_start(), R_Shadow_MakeTextures(), and r_sky_start().

◆ R_ClearTexture()

void R_ClearTexture ( rtexture_t * rt)

Definition at line 2387 of file gl_textures.c.

2388{
2389 gltexture_t *glt = (gltexture_t *)rt;
2390
2392}
static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data)

References NULL, and R_UploadFullTexture().

◆ R_FreeTexture()

void R_FreeTexture ( rtexture_t * rt)

Definition at line 351 of file gl_textures.c.

352{
353 gltexture_t *glt, **gltpointer;
354
355 glt = (gltexture_t *)rt;
356 if (glt == NULL)
357 Host_Error("R_FreeTexture: texture == NULL");
358
359 for (gltpointer = &glt->pool->gltchain;*gltpointer && *gltpointer != glt;gltpointer = &(*gltpointer)->chain);
360 if (*gltpointer == glt)
361 *gltpointer = glt->chain;
362 else
363 Host_Error("R_FreeTexture: texture \"%s\" not linked in pool", glt->identifier);
364
366
367 switch(vid.renderpath)
368 {
369 case RENDERPATH_GL32:
370 case RENDERPATH_GLES2:
371 if (glt->texnum)
372 {
374 qglDeleteTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR
375 }
376 if (glt->renderbuffernum)
377 {
379 qglDeleteRenderbuffers(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
380 }
381 break;
382 }
383
384 if (glt->inputtexels)
385 Mem_Free(glt->inputtexels);
387}
void R_Mesh_ClearBindingsForTexture(int texnum)
static memexpandablearray_t texturearray
Definition gl_textures.c:59
unsigned int GLuint
Definition glquake.h:54
#define CHECKGLERROR
Definition glquake.h:1059
void Host_Error(const char *error,...)
Definition host.c:85
int renderbuffernum
char identifier[MAX_QPATH+32]
struct gltexturepool_s * pool
struct gltexture_s * chain
unsigned char * inputtexels
renderpath_t renderpath
Definition vid.h:80
@ RENDERPATH_GLES2
Definition vid.h:38
@ RENDERPATH_GL32
Definition vid.h:37
viddef_t vid
global video state
Definition vid_shared.c:64
void Mem_ExpandableArray_FreeRecord(memexpandablearray_t *l, void *record)
Definition zone.c:743
#define Mem_Free(mem)
Definition zone.h:96

References gltexture_t::chain, CHECKGLERROR, Host_Error(), gltexture_t::identifier, gltexture_t::inputtexels, Mem_ExpandableArray_FreeRecord(), Mem_Free, NULL, gltexture_t::pool, R_Mesh_ClearBindingsForTexture(), gltexture_t::renderbuffernum, viddef_t::renderpath, RENDERPATH_GL32, RENDERPATH_GLES2, gltexture_t::texnum, texturearray, and vid.

Referenced by Mod_GenerateLightmaps_DestroyLightmaps(), R_Bloom_StartFrame(), R_BuildFogHeightTexture(), R_FreeTexturePool(), R_PurgeTexture(), R_RenderTarget_FreeUnused(), R_Shadow_BounceGrid_ConvertPixelsAndUpload(), R_Shadow_BounceGrid_UpdateSpacing(), R_Shadow_FreeDeferred(), R_Shadow_FreeShadowMaps(), r_shadow_newmap(), R_Shadow_UpdateBounceGridTexture(), and SCR_ClearLoadingScreenTexture().

◆ R_FreeTexturePool()

void R_FreeTexturePool ( rtexturepool_t ** rtexturepool)

Definition at line 403 of file gl_textures.c.

404{
405 gltexturepool_t *pool, **poolpointer;
406 if (rtexturepool == NULL)
407 return;
408 if (*rtexturepool == NULL)
409 return;
410 pool = (gltexturepool_t *)(*rtexturepool);
411 *rtexturepool = NULL;
412 if (pool->sentinel != TEXTUREPOOL_SENTINEL)
413 Host_Error("R_FreeTexturePool: pool already freed");
414 for (poolpointer = &gltexturepoolchain;*poolpointer && *poolpointer != pool;poolpointer = &(*poolpointer)->next);
415 if (*poolpointer == pool)
416 *poolpointer = pool->next;
417 else
418 Host_Error("R_FreeTexturePool: pool not linked");
419 while (pool->gltchain)
421 Mem_Free(pool);
422}
void R_FreeTexture(rtexture_t *rt)
struct gltexture_s * gltchain

References gltexturepool_t::gltchain, gltexturepoolchain, Host_Error(), Mem_Free, gltexturepool_t::next, NULL, R_FreeTexture(), gltexturepool_t::sentinel, and TEXTUREPOOL_SENTINEL.

Referenced by cl_video_shutdown(), gl_draw_shutdown(), gl_main_shutdown(), Mod_UnloadModel(), r_explosion_shutdown(), r_part_shutdown(), R_Shadow_MakeTextures(), r_shadow_shutdown(), r_sky_shutdown(), and r_textures_shutdown().

◆ R_LoadTexture2D()

rtexture_t * R_LoadTexture2D ( rtexturepool_t * rtexturepool,
const char * identifier,
int width,
int height,
const unsigned char * data,
textype_t textype,
int flags,
int miplevel,
const unsigned int * palette )

Definition at line 1352 of file gl_textures.c.

1353{
1354 return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, miplevel, textype, GLTEXTURETYPE_2D, data, palette);
1355}
float flags
static rtexture_t * R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, int miplevel, textype_t textype, int texturetype, const unsigned char *data, const unsigned int *palette)
@ GLTEXTURETYPE_2D
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622
GLsizeiptr const GLvoid * data
Definition glquake.h:639

References data, flags, GLTEXTURETYPE_2D, height, R_SetupTexture(), and width.

Referenced by loadtextureimage(), Mod_GenerateLightmaps_CreateLightmaps(), Mod_Q1BSP_LoadFaces(), Mod_Q3BSP_LoadLightmaps(), Mod_VBSP_LoadFaces(), R_Bloom_StartFrame(), R_BuildBlankTextures(), R_BuildFogHeightTexture(), R_BuildFogTexture(), R_BuildNoTexture(), r_explosion_start(), R_InitParticleTexture(), R_RenderTarget_Get(), R_Shadow_MakeShadowMap(), R_Shadow_MakeTextures(), R_Shadow_PrepareLights(), R_SkinFrame_GenerateTexturesFromQPixels(), R_SkinFrame_LoadExternal_SkinFrame(), R_SkinFrame_LoadInternal8bit(), R_SkinFrame_LoadInternalBGRA(), R_UpdateVariables(), and SCR_SetLoadingScreenTexture().

◆ R_LoadTexture3D()

rtexture_t * R_LoadTexture3D ( rtexturepool_t * rtexturepool,
const char * identifier,
int width,
int height,
int depth,
const unsigned char * data,
textype_t textype,
int flags,
int miplevel,
const unsigned int * palette )

Definition at line 1357 of file gl_textures.c.

1358{
1359 return R_SetupTexture(rtexturepool, identifier, width, height, depth, 1, flags, miplevel, textype, GLTEXTURETYPE_3D, data, palette);
1360}
@ GLTEXTURETYPE_3D
GLint GLenum GLsizei GLsizei GLsizei depth
Definition glquake.h:648

References data, depth, flags, GLTEXTURETYPE_3D, height, R_SetupTexture(), and width.

Referenced by Mod_Q3BSP_LoadLightGrid(), and R_Shadow_BounceGrid_ConvertPixelsAndUpload().

◆ R_LoadTextureCubeMap()

rtexture_t * R_LoadTextureCubeMap ( rtexturepool_t * rtexturepool,
const char * identifier,
int width,
const unsigned char * data,
textype_t textype,
int flags,
int miplevel,
const unsigned int * palette )

Definition at line 1362 of file gl_textures.c.

1363{
1364 return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, miplevel, textype, GLTEXTURETYPE_CUBEMAP, data, palette);
1365}
@ GLTEXTURETYPE_CUBEMAP

References data, flags, GLTEXTURETYPE_CUBEMAP, R_SetupTexture(), and width.

Referenced by R_BuildNormalizationCube(), R_BuildWhiteCube(), R_LoadCubemap(), and R_Shadow_MakeVSDCT().

◆ R_LoadTextureDDSFile()

rtexture_t * R_LoadTextureDDSFile ( rtexturepool_t * rtexturepool,
const char * filename,
qbool srgb,
int flags,
qbool * hasalphaflag,
float * avgcolor,
int miplevel,
qbool optionaltexture )

Definition at line 1569 of file gl_textures.c.

1570{
1571 int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height;
1572 //int dds_flags;
1573 textype_t textype;
1574 int bytesperblock, bytesperpixel;
1575 int mipcomplete;
1576 gltexture_t *glt;
1577 gltexturepool_t *pool = (gltexturepool_t *)rtexturepool;
1578 textypeinfo_t *texinfo;
1579 int mip, mipwidth, mipheight, mipsize, mipsize_total;
1580 unsigned int c, r, g, b;
1581 GLint oldbindtexnum = 0;
1582 unsigned char *mippixels;
1583 unsigned char *mippixels_start;
1584 unsigned char *ddspixels;
1585 unsigned char *dds;
1586 fs_offset_t ddsfilesize;
1587 unsigned int ddssize;
1588 qbool force_swdecode;
1589#ifdef __ANDROID__
1590 // ELUAN: FIXME: separate this code
1591 char vabuf[1024];
1592 char vabuf2[1024];
1593 int strsize;
1594 KTX_dimensions sizes;
1595#endif
1596
1597 if (cls.state == ca_dedicated)
1598 return NULL;
1599
1600#ifdef __ANDROID__
1601 // ELUAN: FIXME: separate this code
1603 {
1604 Con_DPrintf("KTX texture format is only supported on the GLES2 renderpath\n");
1605 return NULL;
1606 }
1607
1608 // some textures are specified with extensions, so it becomes .tga.dds
1609 FS_StripExtension (filename, vabuf2, sizeof(vabuf2));
1610 FS_StripExtension (vabuf2, vabuf, sizeof(vabuf));
1611 FS_DefaultExtension (vabuf, ".ktx", sizeof(vabuf));
1612 strsize = strlen(vabuf);
1613 if (strsize > 5)
1614 for (i = 0; i <= strsize - 4; i++) // copy null termination
1615 vabuf[i] = vabuf[i + 4];
1616
1617 Con_DPrintf("Loading %s...\n", vabuf);
1618 dds = FS_LoadFile(vabuf, tempmempool, true, &ddsfilesize);
1619 ddssize = ddsfilesize;
1620
1621 if (!dds)
1622 {
1623 Con_DPrintf("Not found!\n");
1624 return NULL; // not found
1625 }
1626 Con_DPrintf("Found!\n");
1627
1628 if (flags & TEXF_ALPHA)
1629 {
1630 Con_DPrintf("KTX texture with alpha not supported yet, disabling\n");
1631 flags &= ~TEXF_ALPHA;
1632 }
1633
1634 {
1635 GLenum target;
1636 GLenum glerror;
1637 GLboolean isMipmapped;
1638 KTX_error_code ktxerror;
1639
1641
1642 // texture uploading can take a while, so make sure we're sending keepalives
1643 CL_KeepaliveMessage(false);
1644
1645 // create the texture object
1649 qglGenTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR
1651
1652 // upload the texture
1653 // we need to restore the texture binding after finishing the upload
1654
1655 // NOTE: some drivers fail with ETC1 NPOT (only PowerVR?). This may make the driver crash later.
1656 ktxerror = ktxLoadTextureM(dds, ddssize, &glt->texnum, &target, &sizes, &isMipmapped, &glerror,
1657 0, NULL);// can't CHECKGLERROR, the lib catches it
1658
1659 // FIXME: delete texture if we fail here
1660 if (target != GL_TEXTURE_2D)
1661 {
1662 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
1663 Mem_Free(dds);
1664 Con_DPrintf("%s target != GL_TEXTURE_2D, target == %x\n", vabuf, target);
1665 return NULL; // FIXME: delete the texture from memory
1666 }
1667
1668 if (KTX_SUCCESS == ktxerror)
1669 {
1670 textype = TEXTYPE_ETC1;
1671 flags &= ~TEXF_COMPRESS; // don't let the textype be wrong
1672
1673 // return whether this texture is transparent
1674 if (hasalphaflag)
1675 *hasalphaflag = (flags & TEXF_ALPHA) != 0;
1676
1677 // TODO: apply gl_picmip
1678 // TODO: avgcolor
1679 // TODO: srgb
1680 // TODO: only load mipmaps if requested
1681
1682 if (isMipmapped)
1683 flags |= TEXF_MIPMAP;
1684 else
1685 flags &= ~TEXF_MIPMAP;
1686
1687 texinfo = R_GetTexTypeInfo(textype, flags);
1688
1689 dp_strlcpy(glt->identifier, vabuf, sizeof(glt->identifier));
1690 glt->pool = pool;
1691 glt->chain = pool->gltchain;
1692 pool->gltchain = glt;
1693 glt->inputwidth = sizes.width;
1694 glt->inputheight = sizes.height;
1695 glt->inputdepth = 1;
1696 glt->flags = flags;
1697 glt->textype = texinfo;
1699 glt->inputdatasize = ddssize;
1700 glt->glinternalformat = texinfo->glinternalformat;
1701 glt->glformat = texinfo->glformat;
1702 glt->gltype = texinfo->gltype;
1703 glt->bytesperpixel = texinfo->internalbytesperpixel;
1704 glt->sides = 1;
1706 glt->tilewidth = sizes.width;
1707 glt->tileheight = sizes.height;
1708 glt->tiledepth = 1;
1709 glt->miplevels = isMipmapped ? 1 : 0; // FIXME
1710
1711 // after upload we have to set some parameters...
1712#ifdef GL_TEXTURE_MAX_LEVEL
1713 /* FIXME
1714 if (dds_miplevels >= 1 && !mipcomplete)
1715 {
1716 // need to set GL_TEXTURE_MAX_LEVEL
1717 qglTexParameteri(gltexturetypeenums[glt->texturetype], GL_TEXTURE_MAX_LEVEL, dds_miplevels - 1);CHECKGLERROR
1718 }
1719 */
1720#endif
1722
1723 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
1724 Mem_Free(dds);
1725 return (rtexture_t *)glt;
1726 }
1727 else
1728 {
1729 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
1730 Mem_Free(dds);
1731 Con_DPrintf("KTX texture %s failed to load: %x\n", vabuf, ktxerror);
1732 return NULL;
1733 }
1734 }
1735#endif // __ANDROID__
1736
1737 dds = FS_LoadFile(filename, tempmempool, true, &ddsfilesize);
1738 ddssize = ddsfilesize;
1739
1740 if (!dds)
1741 {
1743 Log_Printf("ddstexturefailures.log", "%s\n", filename);
1744 return NULL; // not found
1745 }
1746
1747 if (ddsfilesize <= 128 || memcmp(dds, "DDS ", 4) || ddssize < (unsigned int)BuffLittleLong(dds+4) || BuffLittleLong(dds+76) != 32)
1748 {
1749 Mem_Free(dds);
1750 Con_Printf("^1%s: not a DDS image\n", filename);
1751 return NULL;
1752 }
1753
1754 //dds_flags = BuffLittleLong(dds+8);
1755 dds_format_flags = BuffLittleLong(dds+80);
1756 dds_miplevels = (BuffLittleLong(dds+108) & 0x400000) ? BuffLittleLong(dds+28) : 1;
1757 dds_width = BuffLittleLong(dds+16);
1758 dds_height = BuffLittleLong(dds+12);
1759 ddspixels = dds + 128;
1760
1762 if(!(dds_format_flags & 0x1)) // DDPF_ALPHAPIXELS
1763 flags &= ~TEXF_ALPHA;
1764
1765 //flags &= ~TEXF_ALPHA; // disabled, as we DISABLE TEXF_ALPHA in the alpha detection, not enable it!
1766 if ((dds_format_flags & 0x40) && BuffLittleLong(dds+88) == 32)
1767 {
1768 // very sloppy BGRA 32bit identification
1769 textype = TEXTYPE_BGRA;
1770 flags &= ~TEXF_COMPRESS; // don't let the textype be wrong
1771 bytesperblock = 0;
1772 bytesperpixel = 4;
1773 size = INTOVERFLOW_MUL(INTOVERFLOW_MUL(dds_width, dds_height), bytesperpixel);
1774 if(INTOVERFLOW_ADD(128, size) > INTOVERFLOW_NORMALIZE(ddsfilesize))
1775 {
1776 Mem_Free(dds);
1777 Con_Printf("^1%s: invalid BGRA DDS image\n", filename);
1778 return NULL;
1779 }
1781 {
1782 // check alpha
1783 for (i = 3;i < size;i += 4)
1784 if (ddspixels[i] < 255)
1785 break;
1786 if (i >= size)
1787 flags &= ~TEXF_ALPHA;
1788 }
1789 }
1790 else if (!memcmp(dds+84, "DXT1", 4))
1791 {
1792 // we need to find out if this is DXT1 (opaque) or DXT1A (transparent)
1793 // LadyHavoc: it is my belief that this does not infringe on the
1794 // patent because it is not decoding pixels...
1795 textype = TEXTYPE_DXT1;
1796 bytesperblock = 8;
1797 bytesperpixel = 0;
1798 //size = ((dds_width+3)/4)*((dds_height+3)/4)*bytesperblock;
1799 size = INTOVERFLOW_MUL(INTOVERFLOW_MUL(INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_width, 3), 4), INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_height, 3), 4)), bytesperblock);
1800 if(INTOVERFLOW_ADD(128, size) > INTOVERFLOW_NORMALIZE(ddsfilesize))
1801 {
1802 Mem_Free(dds);
1803 Con_Printf("^1%s: invalid DXT1 DDS image\n", filename);
1804 return NULL;
1805 }
1806 if (flags & TEXF_ALPHA)
1807 {
1809 {
1810 // check alpha
1811 for (i = 0;i < size;i += bytesperblock)
1812 if (ddspixels[i+0] + ddspixels[i+1] * 256 <= ddspixels[i+2] + ddspixels[i+3] * 256)
1813 {
1814 // NOTE: this assumes sizeof(unsigned int) == 4
1815 unsigned int data = * (unsigned int *) &(ddspixels[i+4]);
1816 // check if data, in base 4, contains a digit 3 (DXT1: transparent pixel)
1817 if(data & (data<<1) & 0xAAAAAAAA)//rgh
1818 break;
1819 }
1820 if (i < size)
1821 textype = TEXTYPE_DXT1A;
1822 else
1823 flags &= ~TEXF_ALPHA;
1824 }
1826 textype = TEXTYPE_DXT1A;
1827 else
1828 {
1829 flags &= ~TEXF_ALPHA;
1830 }
1831 }
1832 }
1833 else if (!memcmp(dds+84, "DXT3", 4) || !memcmp(dds+84, "DXT2", 4))
1834 {
1835 if(!memcmp(dds+84, "DXT2", 4))
1836 {
1838 {
1839 Con_Printf("^1%s: expecting DXT3 image without premultiplied alpha, got DXT2 image with premultiplied alpha\n", filename);
1840 }
1841 }
1842 else
1843 {
1845 {
1846 Con_Printf("^1%s: expecting DXT2 image without premultiplied alpha, got DXT3 image without premultiplied alpha\n", filename);
1847 }
1848 }
1849 textype = TEXTYPE_DXT3;
1850 bytesperblock = 16;
1851 bytesperpixel = 0;
1852 size = INTOVERFLOW_MUL(INTOVERFLOW_MUL(INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_width, 3), 4), INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_height, 3), 4)), bytesperblock);
1853 if(INTOVERFLOW_ADD(128, size) > INTOVERFLOW_NORMALIZE(ddsfilesize))
1854 {
1855 Mem_Free(dds);
1856 Con_Printf("^1%s: invalid DXT3 DDS image\n", filename);
1857 return NULL;
1858 }
1859 // we currently always assume alpha
1860 }
1861 else if (!memcmp(dds+84, "DXT5", 4) || !memcmp(dds+84, "DXT4", 4))
1862 {
1863 if(!memcmp(dds+84, "DXT4", 4))
1864 {
1866 {
1867 Con_Printf("^1%s: expecting DXT5 image without premultiplied alpha, got DXT4 image with premultiplied alpha\n", filename);
1868 }
1869 }
1870 else
1871 {
1873 {
1874 Con_Printf("^1%s: expecting DXT4 image without premultiplied alpha, got DXT5 image without premultiplied alpha\n", filename);
1875 }
1876 }
1877 textype = TEXTYPE_DXT5;
1878 bytesperblock = 16;
1879 bytesperpixel = 0;
1880 size = INTOVERFLOW_MUL(INTOVERFLOW_MUL(INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_width, 3), 4), INTOVERFLOW_DIV(INTOVERFLOW_ADD(dds_height, 3), 4)), bytesperblock);
1881 if(INTOVERFLOW_ADD(128, size) > INTOVERFLOW_NORMALIZE(ddsfilesize))
1882 {
1883 Mem_Free(dds);
1884 Con_Printf("^1%s: invalid DXT5 DDS image\n", filename);
1885 return NULL;
1886 }
1887 // we currently always assume alpha
1888 }
1889 else
1890 {
1891 Mem_Free(dds);
1892 Con_Printf("^1%s: unrecognized/unsupported DDS format\n", filename);
1893 return NULL;
1894 }
1895
1896 // when requesting a non-alpha texture and we have DXT3/5, convert to DXT1
1897 if(!(flags & TEXF_ALPHA) && (textype == TEXTYPE_DXT3 || textype == TEXTYPE_DXT5))
1898 {
1899 textype = TEXTYPE_DXT1;
1900 bytesperblock = 8;
1901 ddssize -= 128;
1902 ddssize /= 2;
1903 for (i = 0;i < (int)ddssize;i += bytesperblock)
1904 memcpy(&ddspixels[i], &ddspixels[(i<<1)+8], 8);
1905 ddssize += 128;
1906 }
1907
1908 force_swdecode = false;
1909 if(bytesperblock)
1910 {
1912 {
1914 force_swdecode = true;
1915 }
1916 else
1917 {
1919 {
1920 // unsupported
1921 Mem_Free(dds);
1922 return NULL;
1923 }
1924 force_swdecode = true;
1925 }
1926 }
1927
1928 // return whether this texture is transparent
1929 if (hasalphaflag)
1930 *hasalphaflag = (flags & TEXF_ALPHA) != 0;
1931
1932 // if we SW decode, choose 2 sizes bigger
1933 if(force_swdecode)
1934 {
1935 // this is quarter res, so do not scale down more than we have to
1936 miplevel -= 2;
1937
1938 if(miplevel < 0)
1939 Con_DPrintf("WARNING: fake software decoding of compressed texture %s degraded quality\n", filename);
1940 }
1941
1942 // this is where we apply gl_picmip
1943 mippixels_start = ddspixels;
1944 mipwidth = dds_width;
1945 mipheight = dds_height;
1946 while(miplevel >= 1 && dds_miplevels >= 1)
1947 {
1948 if (mipwidth <= 1 && mipheight <= 1)
1949 break;
1950 mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
1951 mippixels_start += mipsize; // just skip
1952 --dds_miplevels;
1953 --miplevel;
1954 if (mipwidth > 1)
1955 mipwidth >>= 1;
1956 if (mipheight > 1)
1957 mipheight >>= 1;
1958 }
1959 mipsize_total = ddssize - 128 - (mippixels_start - ddspixels);
1960 mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
1961
1962 // from here on, we do not need the ddspixels and ddssize any more (apart from the statistics entry in glt)
1963
1964 // fake decode S3TC if needed
1965 if(force_swdecode)
1966 {
1967 int mipsize_new = mipsize_total / bytesperblock * 4;
1968 unsigned char *mipnewpixels = (unsigned char *) Mem_Alloc(tempmempool, mipsize_new);
1969 unsigned char *p = mipnewpixels;
1970 for (i = bytesperblock == 16 ? 8 : 0;i < (int)mipsize_total;i += bytesperblock, p += 4)
1971 {
1972 // UBSan: unsigned literals because promotion to int causes signed overflow when mippixels_start >= 128
1973 c = mippixels_start[i] + 256u*mippixels_start[i+1] + 65536u*mippixels_start[i+2] + 16777216u*mippixels_start[i+3];
1974 p[2] = (((c >> 11) & 0x1F) + ((c >> 27) & 0x1F)) * (0.5f / 31.0f * 255.0f);
1975 p[1] = (((c >> 5) & 0x3F) + ((c >> 21) & 0x3F)) * (0.5f / 63.0f * 255.0f);
1976 p[0] = (((c ) & 0x1F) + ((c >> 16) & 0x1F)) * (0.5f / 31.0f * 255.0f);
1977 if(textype == TEXTYPE_DXT5)
1978 p[3] = (0.5 * mippixels_start[i-8] + 0.5 * mippixels_start[i-7]);
1979 else if(textype == TEXTYPE_DXT3)
1980 p[3] = (
1981 (mippixels_start[i-8] & 0x0F)
1982 + (mippixels_start[i-8] >> 4)
1983 + (mippixels_start[i-7] & 0x0F)
1984 + (mippixels_start[i-7] >> 4)
1985 + (mippixels_start[i-6] & 0x0F)
1986 + (mippixels_start[i-6] >> 4)
1987 + (mippixels_start[i-5] & 0x0F)
1988 + (mippixels_start[i-5] >> 4)
1989 ) * (0.125f / 15.0f * 255.0f);
1990 else
1991 p[3] = 255;
1992 }
1993
1994 textype = TEXTYPE_BGRA;
1995 bytesperblock = 0;
1996 bytesperpixel = 4;
1997
1998 // as each block becomes a pixel, we must use pixel count for this
1999 mipwidth = (mipwidth + 3) / 4;
2000 mipheight = (mipheight + 3) / 4;
2001 mipsize = bytesperpixel * mipwidth * mipheight;
2002 mippixels_start = mipnewpixels;
2003 mipsize_total = mipsize_new;
2004 }
2005
2006 // start mip counting
2007 mippixels = mippixels_start;
2008
2009 // calculate average color if requested
2010 if (avgcolor)
2011 {
2012 float f;
2013 Vector4Clear(avgcolor);
2014 if (bytesperblock)
2015 {
2016 for (i = bytesperblock == 16 ? 8 : 0;i < mipsize;i += bytesperblock)
2017 {
2018 // UBSan: unsigned literals because promotion to int causes signed overflow when mippixels >= 128
2019 c = mippixels[i] + 256u*mippixels[i+1] + 65536u*mippixels[i+2] + 16777216u*mippixels[i+3];
2020 avgcolor[0] += ((c >> 11) & 0x1F) + ((c >> 27) & 0x1F);
2021 avgcolor[1] += ((c >> 5) & 0x3F) + ((c >> 21) & 0x3F);
2022 avgcolor[2] += ((c ) & 0x1F) + ((c >> 16) & 0x1F);
2023 if(textype == TEXTYPE_DXT5)
2024 avgcolor[3] += (mippixels[i-8] + (int) mippixels[i-7]) * (0.5f / 255.0f);
2025 else if(textype == TEXTYPE_DXT3)
2026 avgcolor[3] += (
2027 (mippixels_start[i-8] & 0x0F)
2028 + (mippixels_start[i-8] >> 4)
2029 + (mippixels_start[i-7] & 0x0F)
2030 + (mippixels_start[i-7] >> 4)
2031 + (mippixels_start[i-6] & 0x0F)
2032 + (mippixels_start[i-6] >> 4)
2033 + (mippixels_start[i-5] & 0x0F)
2034 + (mippixels_start[i-5] >> 4)
2035 ) * (0.125f / 15.0f);
2036 else
2037 avgcolor[3] += 1.0f;
2038 }
2039 f = (float)bytesperblock / mipsize;
2040 avgcolor[0] *= (0.5f / 31.0f) * f;
2041 avgcolor[1] *= (0.5f / 63.0f) * f;
2042 avgcolor[2] *= (0.5f / 31.0f) * f;
2043 avgcolor[3] *= f;
2044 }
2045 else
2046 {
2047 for (i = 0;i < mipsize;i += 4)
2048 {
2049 avgcolor[0] += mippixels[i+2];
2050 avgcolor[1] += mippixels[i+1];
2051 avgcolor[2] += mippixels[i];
2052 avgcolor[3] += mippixels[i+3];
2053 }
2054 f = (1.0f / 255.0f) * bytesperpixel / mipsize;
2055 avgcolor[0] *= f;
2056 avgcolor[1] *= f;
2057 avgcolor[2] *= f;
2058 avgcolor[3] *= f;
2059 }
2060 }
2061
2062 // if we want sRGB, convert now
2063 if(srgb)
2064 {
2066 {
2067 switch(textype)
2068 {
2069 case TEXTYPE_DXT1: textype = TEXTYPE_SRGB_DXT1 ;break;
2070 case TEXTYPE_DXT1A: textype = TEXTYPE_SRGB_DXT1A ;break;
2071 case TEXTYPE_DXT3: textype = TEXTYPE_SRGB_DXT3 ;break;
2072 case TEXTYPE_DXT5: textype = TEXTYPE_SRGB_DXT5 ;break;
2073 case TEXTYPE_RGBA: textype = TEXTYPE_SRGB_RGBA ;break;
2074 default:
2075 break;
2076 }
2077 }
2078 else
2079 {
2080 switch(textype)
2081 {
2082 case TEXTYPE_DXT1:
2083 case TEXTYPE_DXT1A:
2084 case TEXTYPE_DXT3:
2085 case TEXTYPE_DXT5:
2086 {
2087 for (i = bytesperblock == 16 ? 8 : 0;i < mipsize_total;i += bytesperblock)
2088 {
2089 int c0, c1, c0new, c1new;
2090 c0 = mippixels_start[i] + 256*mippixels_start[i+1];
2091 r = ((c0 >> 11) & 0x1F);
2092 g = ((c0 >> 5) & 0x3F);
2093 b = ((c0 ) & 0x1F);
2094 r = floor(Image_LinearFloatFromsRGB(r * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2095 g = floor(Image_LinearFloatFromsRGB(g * (255.0f / 63.0f)) * 63.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2096 b = floor(Image_LinearFloatFromsRGB(b * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2097 c0new = (r << 11) | (g << 5) | b;
2098 c1 = mippixels_start[i+2] + 256*mippixels_start[i+3];
2099 r = ((c1 >> 11) & 0x1F);
2100 g = ((c1 >> 5) & 0x3F);
2101 b = ((c1 ) & 0x1F);
2102 r = floor(Image_LinearFloatFromsRGB(r * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2103 g = floor(Image_LinearFloatFromsRGB(g * (255.0f / 63.0f)) * 63.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2104 b = floor(Image_LinearFloatFromsRGB(b * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB
2105 c1new = (r << 11) | (g << 5) | b;
2106 // swap the colors if needed to fix order
2107 if(c0 > c1) // thirds
2108 {
2109 if(c0new < c1new)
2110 {
2111 c = c0new;
2112 c0new = c1new;
2113 c1new = c;
2114 if(c0new == c1new)
2115 mippixels_start[i+4] ^= 0x55;
2116 mippixels_start[i+5] ^= 0x55;
2117 mippixels_start[i+6] ^= 0x55;
2118 mippixels_start[i+7] ^= 0x55;
2119 }
2120 else if(c0new == c1new)
2121 {
2122 mippixels_start[i+4] = 0x00;
2123 mippixels_start[i+5] = 0x00;
2124 mippixels_start[i+6] = 0x00;
2125 mippixels_start[i+7] = 0x00;
2126 }
2127 }
2128 else // half + transparent
2129 {
2130 if(c0new > c1new)
2131 {
2132 c = c0new;
2133 c0new = c1new;
2134 c1new = c;
2135 mippixels_start[i+4] ^= (~mippixels_start[i+4] >> 1) & 0x55;
2136 mippixels_start[i+5] ^= (~mippixels_start[i+5] >> 1) & 0x55;
2137 mippixels_start[i+6] ^= (~mippixels_start[i+6] >> 1) & 0x55;
2138 mippixels_start[i+7] ^= (~mippixels_start[i+7] >> 1) & 0x55;
2139 }
2140 }
2141 mippixels_start[i] = c0new & 255;
2142 mippixels_start[i+1] = c0new >> 8;
2143 mippixels_start[i+2] = c1new & 255;
2144 mippixels_start[i+3] = c1new >> 8;
2145 }
2146 }
2147 break;
2148 case TEXTYPE_RGBA:
2149 Image_MakeLinearColorsFromsRGB(mippixels, mippixels, mipsize_total / bytesperblock);
2150 break;
2151 default:
2152 break;
2153 }
2154 }
2155 }
2156
2157 // when not requesting mipmaps, do not load them
2158 if(!(flags & TEXF_MIPMAP))
2159 dds_miplevels = 0;
2160
2161 if (dds_miplevels >= 1)
2162 flags |= TEXF_MIPMAP;
2163 else
2164 flags &= ~TEXF_MIPMAP;
2165
2166 texinfo = R_GetTexTypeInfo(textype, flags);
2167
2169 dp_strlcpy (glt->identifier, filename, sizeof(glt->identifier));
2170 glt->pool = pool;
2171 glt->chain = pool->gltchain;
2172 pool->gltchain = glt;
2173 glt->inputwidth = mipwidth;
2174 glt->inputheight = mipheight;
2175 glt->inputdepth = 1;
2176 glt->flags = flags;
2177 glt->textype = texinfo;
2179 glt->inputdatasize = ddssize;
2180 glt->glinternalformat = texinfo->glinternalformat;
2181 glt->glformat = texinfo->glformat;
2182 glt->gltype = texinfo->gltype;
2183 glt->bytesperpixel = texinfo->internalbytesperpixel;
2184 glt->sides = 1;
2186 glt->tilewidth = mipwidth;
2187 glt->tileheight = mipheight;
2188 glt->tiledepth = 1;
2189 glt->miplevels = dds_miplevels;
2190
2191 // texture uploading can take a while, so make sure we're sending keepalives
2192 CL_KeepaliveMessage(false);
2193
2194 // create the texture object
2195 switch(vid.renderpath)
2196 {
2197 case RENDERPATH_GL32:
2198 case RENDERPATH_GLES2:
2201 oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
2202 qglGenTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR
2203 qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
2204 break;
2205 }
2206
2207 // upload the texture
2208 // we need to restore the texture binding after finishing the upload
2209 mipcomplete = false;
2210
2211 for (mip = 0;mip <= dds_miplevels;mip++) // <= to include the not-counted "largest" miplevel
2212 {
2213 unsigned char *upload_mippixels = mippixels;
2214 int upload_mipwidth = mipwidth;
2215 int upload_mipheight = mipheight;
2216 mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
2217 if (mippixels + mipsize > mippixels_start + mipsize_total)
2218 break;
2219 switch(vid.renderpath)
2220 {
2221 case RENDERPATH_GL32:
2222 case RENDERPATH_GLES2:
2223 if (bytesperblock)
2224 {
2225 qglCompressedTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, mipsize, upload_mippixels);CHECKGLERROR
2226 }
2227 else
2228 {
2229 qglTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, glt->glformat, glt->gltype, upload_mippixels);CHECKGLERROR
2230 }
2231 break;
2232 }
2233 if(upload_mippixels != mippixels)
2234 Mem_Free(upload_mippixels);
2235 mippixels += mipsize;
2236 if (mipwidth <= 1 && mipheight <= 1)
2237 {
2238 mipcomplete = true;
2239 break;
2240 }
2241 if (mipwidth > 1)
2242 mipwidth >>= 1;
2243 if (mipheight > 1)
2244 mipheight >>= 1;
2245 }
2246
2247 // after upload we have to set some parameters...
2248 switch(vid.renderpath)
2249 {
2250 case RENDERPATH_GL32:
2251 case RENDERPATH_GLES2:
2252#ifdef GL_TEXTURE_MAX_LEVEL
2253 if (dds_miplevels >= 1 && !mipcomplete)
2254 {
2255 // need to set GL_TEXTURE_MAX_LEVEL
2256 qglTexParameteri(gltexturetypeenums[glt->texturetype], GL_TEXTURE_MAX_LEVEL, dds_miplevels - 1);CHECKGLERROR
2257 }
2258#endif
2260 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
2261 break;
2262 }
2263
2264 Mem_Free(dds);
2265 if(force_swdecode)
2266 Mem_Free((unsigned char *) mippixels_start);
2267 return (rtexture_t *)glt;
2268}
client_static_t cls
Definition cl_main.c:116
void CL_KeepaliveMessage(qbool readmessages)
Definition cl_parse.c:314
@ ca_dedicated
Definition client.h:530
int BuffLittleLong(const unsigned char *buffer)
Extract a little endian 32bit int from the given buffer.
Definition com_msg.c:71
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
void Log_Printf(const char *logfilename, const char *fmt,...)
Definition console.c:655
vector size
void FS_DefaultExtension(char *path, const char *extension, size_t size_path)
Definition fs.c:3641
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
static int(ZEXPORT *qz_inflate)(z_stream *strm
void FS_StripExtension(const char *in, char *out, size_t size_out)
Definition fs.c:3611
int64_t fs_offset_t
Definition fs.h:37
void GL_ActiveTexture(unsigned int num)
int R_Mesh_TexBound(unsigned int unitnum, int id)
static textypeinfo_t * R_GetTexTypeInfo(textype_t textype, int flags)
static void GL_SetupTextureParameters(int flags, textype_t textype, int texturetype)
cvar_t r_texture_dds_swdecode
Definition gl_textures.c:51
static int gltexturetypeenums[GLTEXTURETYPE_TOTAL]
cvar_t r_texture_dds_load_alphamode
Definition gl_textures.c:49
cvar_t r_texture_dds_load_logfailure
Definition gl_textures.c:50
int GLint
Definition glquake.h:51
#define GL_TEXTURE_MAX_LEVEL
Definition glquake.h:98
unsigned char GLboolean
Definition glquake.h:46
unsigned int GLenum
Definition glquake.h:45
#define GL_TEXTURE_2D
Definition glquake.h:89
void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pin, int numpixels)
Definition image.c:930
#define Image_LinearFloatFromsRGB(c)
Definition image.h:69
#define Vector4Clear(a)
Definition mathlib.h:82
float strlen(string s)
float floor(float f)
string target
Definition progsdefs.qc:193
int i
#define INTOVERFLOW_ADD(a, b)
Definition qdefs.h:220
#define INTOVERFLOW_NORMALIZE(a)
Definition qdefs.h:225
#define INTOVERFLOW_MUL(a, b)
Definition qdefs.h:222
#define INTOVERFLOW_DIV(a, b)
Definition qdefs.h:223
bool qbool
Definition qtypes.h:9
#define TEXF_RGBMULTIPLYBYALPHA
Definition r_textures.h:13
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_MIPMAP
Definition r_textures.h:11
textype_t
Definition r_textures.h:44
dp_FragColor r
dp_FragColor g
precision highp float
Definition shader_glsl.h:53
float f
dp_FragColor b
cactive_t state
Definition client.h:568
int integer
Definition cvar.h:73
int gltexturetypeenum
int glinternalformat
textypeinfo_t * textype
int internalbytesperpixel
Definition gl_textures.c:72
textype_t textype
Definition gl_textures.c:70
qbool ext_texture_compression_s3tc
Definition vid.h:48
qbool ext_texture_srgb
Definition vid.h:50
viddef_support_t support
Definition vid.h:89
void * Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l)
Definition zone.c:695
mempool_t * tempmempool
Definition zone.c:794

References b, BuffLittleLong(), gltexture_t::bytesperpixel, ca_dedicated, gltexture_t::chain, CHECKGLERROR, CL_KeepaliveMessage(), cls, Con_DPrintf(), Con_Printf(), data, dp_strlcpy, viddef_support_t::ext_texture_compression_s3tc, viddef_support_t::ext_texture_srgb, f, flags, gltexture_t::flags, float, floor(), FS_DefaultExtension(), FS_LoadFile(), FS_StripExtension(), g, GL_ActiveTexture(), GL_SetupTextureParameters(), GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, gltexture_t::glformat, textypeinfo_t::glformat, gltexture_t::glinternalformat, textypeinfo_t::glinternalformat, gltexturepool_t::gltchain, GLTEXTURETYPE_2D, gltexture_t::gltexturetypeenum, gltexturetypeenums, gltexture_t::gltype, textypeinfo_t::gltype, i, gltexture_t::identifier, Image_LinearFloatFromsRGB, Image_MakeLinearColorsFromsRGB(), gltexture_t::inputdatasize, gltexture_t::inputdepth, gltexture_t::inputheight, gltexture_t::inputwidth, int(), cvar_t::integer, textypeinfo_t::internalbytesperpixel, INTOVERFLOW_ADD, INTOVERFLOW_DIV, INTOVERFLOW_MUL, INTOVERFLOW_NORMALIZE, Log_Printf(), Mem_Alloc, Mem_ExpandableArray_AllocRecord(), Mem_Free, gltexture_t::miplevels, NULL, gltexture_t::pool, r, R_GetTexTypeInfo(), R_Mesh_TexBound(), r_texture_dds_load_alphamode, r_texture_dds_load_logfailure, r_texture_dds_swdecode, viddef_t::renderpath, RENDERPATH_GL32, RENDERPATH_GLES2, gltexture_t::sides, size, client_static_t::state, strlen(), viddef_t::support, target, tempmempool, TEXF_ALPHA, TEXF_MIPMAP, TEXF_RGBMULTIPLYBYALPHA, gltexture_t::texnum, texturearray, gltexture_t::texturetype, gltexture_t::textype, textypeinfo_t::textype, TEXTYPE_BGRA, TEXTYPE_DXT1, TEXTYPE_DXT1A, TEXTYPE_DXT3, TEXTYPE_DXT5, TEXTYPE_ETC1, TEXTYPE_RGBA, TEXTYPE_SRGB_DXT1, TEXTYPE_SRGB_DXT1A, TEXTYPE_SRGB_DXT3, TEXTYPE_SRGB_DXT5, TEXTYPE_SRGB_RGBA, gltexture_t::tiledepth, gltexture_t::tileheight, gltexture_t::tilewidth, Vector4Clear, and vid.

Referenced by R_SkinFrame_LoadExternal_SkinFrame().

◆ R_LoadTextureRenderBuffer()

rtexture_t * R_LoadTextureRenderBuffer ( rtexturepool_t * rtexturepool,
const char * identifier,
int width,
int height,
textype_t textype )

Definition at line 1372 of file gl_textures.c.

1373{
1374 gltexture_t *glt;
1375 gltexturepool_t *pool = (gltexturepool_t *)rtexturepool;
1376 textypeinfo_t *texinfo;
1377
1378 if (cls.state == ca_dedicated)
1379 return NULL;
1380
1381 texinfo = R_GetTexTypeInfo(textype, TEXF_RENDERTARGET | TEXF_CLAMP);
1382
1384 if (identifier)
1385 dp_strlcpy (glt->identifier, identifier, sizeof(glt->identifier));
1386 glt->pool = pool;
1387 glt->chain = pool->gltchain;
1388 pool->gltchain = glt;
1389 glt->inputwidth = width;
1390 glt->inputheight = height;
1391 glt->inputdepth = 1;
1393 glt->miplevel = 0;
1394 glt->textype = texinfo;
1395 glt->texturetype = textype;
1397 glt->palette = NULL;
1398 glt->glinternalformat = texinfo->glinternalformat;
1399 glt->glformat = texinfo->glformat;
1400 glt->gltype = texinfo->gltype;
1401 glt->bytesperpixel = texinfo->internalbytesperpixel;
1402 glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1;
1403 glt->texnum = 0;
1404 glt->dirty = false;
1407 // init the dynamic texture attributes, too [11/22/2007 Black]
1408 glt->updatecallback = NULL;
1410
1411 GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->miplevel, glt->inputwidth, glt->inputheight, glt->inputdepth, &glt->tilewidth, &glt->tileheight, &glt->tiledepth, &glt->miplevels);
1412
1413 // upload the texture
1414 // data may be NULL (blank texture for dynamic rendering)
1415 switch(vid.renderpath)
1416 {
1417 case RENDERPATH_GL32:
1418 case RENDERPATH_GLES2:
1420 qglGenRenderbuffers(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
1421 qglBindRenderbuffer(GL_RENDERBUFFER, glt->renderbuffernum);CHECKGLERROR
1422 qglRenderbufferStorage(GL_RENDERBUFFER, glt->glinternalformat, glt->tilewidth, glt->tileheight);CHECKGLERROR
1423 // note we can query the renderbuffer for info with glGetRenderbufferParameteriv for GL_WIDTH, GL_HEIGHt, GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_GL_ALPHA_SIZE, GL_DEPTH_SIZE, GL_STENCIL_SIZE, GL_INTERNAL_FORMAT
1424 qglBindRenderbuffer(GL_RENDERBUFFER, 0);CHECKGLERROR
1425 break;
1426 }
1427
1428 return (rtexture_t *)glt;
1429}
static void GL_Texture_CalcImageSize(int texturetype, int flags, int miplevel, int inwidth, int inheight, int indepth, int *outwidth, int *outheight, int *outdepth, int *outmiplevels)
#define GL_RENDERBUFFER
Definition glquake.h:322
#define TEXF_FORCENEAREST
Definition r_textures.h:17
#define TEXF_CLAMP
Definition r_textures.h:15
#define TEXF_RENDERTARGET
Definition r_textures.h:37
const unsigned int * palette
qbool glisdepthstencil
void * updatecallback_data
updatecallback_t updatecallback

References gltexture_t::bytesperpixel, ca_dedicated, gltexture_t::chain, CHECKGLERROR, cls, gltexture_t::dirty, dp_strlcpy, gltexture_t::flags, GL_RENDERBUFFER, GL_TEXTURE_2D, GL_Texture_CalcImageSize(), gltexture_t::glformat, textypeinfo_t::glformat, gltexture_t::glinternalformat, textypeinfo_t::glinternalformat, gltexture_t::glisdepthstencil, gltexturepool_t::gltchain, GLTEXTURETYPE_CUBEMAP, gltexture_t::gltexturetypeenum, gltexture_t::gltype, textypeinfo_t::gltype, height, gltexture_t::identifier, gltexture_t::inputdatasize, gltexture_t::inputdepth, gltexture_t::inputheight, gltexture_t::inputwidth, textypeinfo_t::internalbytesperpixel, Mem_ExpandableArray_AllocRecord(), gltexture_t::miplevel, gltexture_t::miplevels, NULL, gltexture_t::palette, gltexture_t::pool, R_GetTexTypeInfo(), gltexture_t::renderbuffernum, viddef_t::renderpath, RENDERPATH_GL32, RENDERPATH_GLES2, gltexture_t::sides, client_static_t::state, TEXF_CLAMP, TEXF_FORCENEAREST, TEXF_RENDERTARGET, gltexture_t::texnum, texturearray, gltexture_t::texturetype, gltexture_t::textype, TEXTYPE_DEPTHBUFFER24STENCIL8, gltexture_t::tiledepth, gltexture_t::tileheight, gltexture_t::tilewidth, gltexture_t::updatecallback, gltexture_t::updatecallback_data, vid, and width.

Referenced by R_RenderTarget_Get(), R_Shadow_MakeShadowMap(), and R_Shadow_PrepareLights().

◆ R_LoadTextureShadowMap2D()

rtexture_t * R_LoadTextureShadowMap2D ( rtexturepool_t * rtexturepool,
const char * identifier,
int width,
int height,
textype_t textype,
qbool filter )

Definition at line 1367 of file gl_textures.c.

1368{
1369 return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_RENDERTARGET | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR : TEXF_FORCENEAREST), -1, textype, GLTEXTURETYPE_2D, NULL, NULL);
1370}
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glquake.h:609
#define TEXF_FORCELINEAR
Definition r_textures.h:19

References filter, GLTEXTURETYPE_2D, height, NULL, R_SetupTexture(), TEXF_CLAMP, TEXF_FORCELINEAR, TEXF_FORCENEAREST, TEXF_RENDERTARGET, and width.

Referenced by R_Shadow_MakeShadowMap().

◆ R_MakeTextureDynamic()

void R_MakeTextureDynamic ( rtexture_t * rt,
updatecallback_t updatecallback,
void * data )

Definition at line 326 of file gl_textures.c.

326 {
327 gltexture_t *glt = (gltexture_t*) rt;
328 if( !glt ) {
329 return;
330 }
331
332 glt->flags |= GLTEXF_DYNAMIC;
333 glt->updatecallback = updatecallback;
335}
#define GLTEXF_DYNAMIC
Definition gl_textures.c:65

References data, gltexture_t::flags, GLTEXF_DYNAMIC, gltexture_t::updatecallback, and gltexture_t::updatecallback_data.

Referenced by LinkVideoTexture().

◆ R_MarkDirtyTexture()

void R_MarkDirtyTexture ( rtexture_t * rt)

Definition at line 312 of file gl_textures.c.

312 {
313 gltexture_t *glt = (gltexture_t*) rt;
314 if( !glt ) {
315 return;
316 }
317
318 // dont do anything if the texture is already dirty (and make sure this *is* a dynamic texture after all!)
319 if (glt->flags & GLTEXF_DYNAMIC)
320 {
321 // mark it as dirty, so R_RealGetTexture gets called
322 glt->dirty = true;
323 }
324}

References gltexture_t::dirty, gltexture_t::flags, and GLTEXF_DYNAMIC.

Referenced by CL_Video_Frame().

◆ R_PicmipForFlags()

int R_PicmipForFlags ( int flags)

Definition at line 2394 of file gl_textures.c.

2395{
2396 int miplevel = 0;
2397 if(flags & TEXF_PICMIP)
2398 {
2399 miplevel += gl_picmip.integer;
2400 if (flags & TEXF_ISWORLD)
2401 {
2403 miplevel += gl_picmip_world.integer;
2404 else
2405 miplevel = 0;
2406 }
2407 else if (flags & TEXF_ISSPRITE)
2408 {
2410 miplevel += gl_picmip_sprites.integer;
2411 else
2412 miplevel = 0;
2413 }
2414 else
2415 miplevel += gl_picmip_other.integer;
2416 }
2417 return max(0, miplevel);
2418}
cvar_t r_picmipworld
Definition gl_textures.c:31
cvar_t gl_picmip_sprites
Definition gl_textures.c:32
cvar_t gl_picmip
Definition gl_textures.c:29
cvar_t gl_picmip_world
Definition gl_textures.c:30
cvar_t gl_picmip_other
Definition gl_textures.c:34
cvar_t r_picmipsprites
Definition gl_textures.c:33
#define max(A, B)
Definition mathlib.h:38
#define TEXF_PICMIP
Definition r_textures.h:21
#define TEXF_ISWORLD
Definition r_textures.h:33
#define TEXF_ISSPRITE
Definition r_textures.h:35

References flags, gl_picmip, gl_picmip_other, gl_picmip_sprites, gl_picmip_world, cvar_t::integer, max, r_picmipsprites, r_picmipworld, TEXF_ISSPRITE, TEXF_ISWORLD, and TEXF_PICMIP.

Referenced by loadtextureimage(), R_SetupTexture(), and R_SkinFrame_LoadExternal_SkinFrame().

◆ R_PurgeTexture()

void R_PurgeTexture ( rtexture_t * prt)

Definition at line 344 of file gl_textures.c.

345{
346 if(rt && !(((gltexture_t*) rt)->flags & TEXF_PERSISTENT)) {
347 R_FreeTexture(rt);
348 }
349}
#define TEXF_PERSISTENT
Definition r_textures.h:25

References flags, R_FreeTexture(), and TEXF_PERSISTENT.

Referenced by R_SkinFrame_PurgeSkinFrame().

◆ R_RealGetTexture()

int R_RealGetTexture ( rtexture_t * rt)

Definition at line 2358 of file gl_textures.c.

2359{
2360 if (rt)
2361 {
2362 gltexture_t *glt;
2363 glt = (gltexture_t *)rt;
2364 if (glt->flags & GLTEXF_DYNAMIC)
2366 if (glt->buffermodified && glt->bufferpixels)
2367 {
2368 glt->buffermodified = false;
2369 // Because we currently don't set the relevant upload stride parameters, just make it full width.
2370 glt->modified_mins[0] = 0;
2371 glt->modified_maxs[0] = glt->tilewidth;
2372 // Check also if it's updating at least half the height of the texture.
2373 if (glt->modified_maxs[1] - glt->modified_mins[1] > glt->tileheight / 2)
2375 else
2376 R_UploadPartialTexture(glt, glt->bufferpixels + (size_t)glt->modified_mins[1] * glt->tilewidth * glt->bytesperpixel, glt->modified_mins[0], glt->modified_mins[1], glt->modified_mins[2], glt->modified_maxs[0] - glt->modified_mins[0], glt->modified_maxs[1] - glt->modified_mins[1], glt->modified_maxs[2] - glt->modified_mins[2]);
2377 }
2380 glt->dirty = false;
2381 return glt->texnum;
2382 }
2383 else
2384 return r_texture_white->texnum;
2385}
static void R_UploadPartialTexture(gltexture_t *glt, const unsigned char *data, int fragx, int fragy, int fragz, int fragwidth, int fragheight, int fragdepth)
static void R_UpdateDynamicTexture(gltexture_t *glt)
#define VectorClear(a)
Definition mathlib.h:97
unsigned char * bufferpixels
int modified_maxs[3]
qbool buffermodified
int modified_mins[3]

References gltexture_t::buffermodified, gltexture_t::bufferpixels, gltexture_t::bytesperpixel, gltexture_t::dirty, gltexture_t::flags, GLTEXF_DYNAMIC, gltexture_t::modified_maxs, gltexture_t::modified_mins, r_texture_white, R_UpdateDynamicTexture(), R_UploadFullTexture(), R_UploadPartialTexture(), gltexture_t::texnum, rtexture_t::texnum, gltexture_t::tileheight, gltexture_t::tilewidth, and VectorClear.

◆ R_SaveTextureDDSFile()

int R_SaveTextureDDSFile ( rtexture_t * rt,
const char * filename,
qbool skipuncompressed,
qbool hasalpha )

Definition at line 1431 of file gl_textures.c.

1432{
1433#ifdef USE_GLES2
1434 return -1; // unsupported on this platform
1435#else
1436 gltexture_t *glt = (gltexture_t *)rt;
1437 unsigned char *dds;
1438 int oldbindtexnum;
1439 int bytesperpixel = 0;
1440 int bytesperblock = 0;
1441 int dds_flags;
1442 int dds_format_flags;
1443 int dds_caps1;
1444 int dds_caps2;
1445 int ret;
1446 int mip;
1447 int mipmaps;
1448 int mipinfo[16][4];
1449 int ddssize = 128;
1451 const char *ddsfourcc;
1452 if (!rt)
1453 return -1; // NULL pointer
1454 if (!strcmp(gl_version, "2.0.5885 WinXP Release"))
1455 return -2; // broken driver - crashes on reading internal format
1456 if (!qglGetTexLevelParameteriv)
1457 return -2;
1459 oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
1460 qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
1461 qglGetTexLevelParameteriv(gltexturetypeenums[glt->texturetype], 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat);
1462 switch(internalformat)
1463 {
1464 default: ddsfourcc = NULL;bytesperpixel = 4;break;
1466 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: ddsfourcc = "DXT1";bytesperblock = 8;break;
1467 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: ddsfourcc = "DXT3";bytesperblock = 16;break;
1468 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: ddsfourcc = "DXT5";bytesperblock = 16;break;
1469 }
1470 // if premultiplied alpha, say so in the DDS file
1472 {
1473 switch(internalformat)
1474 {
1475 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: ddsfourcc = "DXT2";break;
1476 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: ddsfourcc = "DXT4";break;
1477 }
1478 }
1479 if (!bytesperblock && skipuncompressed)
1480 return -3; // skipped
1481 memset(mipinfo, 0, sizeof(mipinfo));
1482 mipinfo[0][0] = glt->tilewidth;
1483 mipinfo[0][1] = glt->tileheight;
1484 mipmaps = 1;
1485 if ((glt->flags & TEXF_MIPMAP) && !(glt->tilewidth == 1 && glt->tileheight == 1))
1486 {
1487 for (mip = 1;mip < 16;mip++)
1488 {
1489 mipinfo[mip][0] = mipinfo[mip-1][0] > 1 ? mipinfo[mip-1][0] >> 1 : 1;
1490 mipinfo[mip][1] = mipinfo[mip-1][1] > 1 ? mipinfo[mip-1][1] >> 1 : 1;
1491 if (mipinfo[mip][0] == 1 && mipinfo[mip][1] == 1)
1492 {
1493 mip++;
1494 break;
1495 }
1496 }
1497 mipmaps = mip;
1498 }
1499 for (mip = 0;mip < mipmaps;mip++)
1500 {
1501 mipinfo[mip][2] = bytesperblock ? ((mipinfo[mip][0]+3)/4)*((mipinfo[mip][1]+3)/4)*bytesperblock : mipinfo[mip][0]*mipinfo[mip][1]*bytesperpixel;
1502 mipinfo[mip][3] = ddssize;
1503 ddssize += mipinfo[mip][2];
1504 }
1505 dds = (unsigned char *)Mem_Alloc(tempmempool, ddssize);
1506 if (!dds)
1507 return -4;
1508 dds_caps1 = 0x1000; // DDSCAPS_TEXTURE
1509 dds_caps2 = 0;
1510 if (bytesperblock)
1511 {
1512 dds_flags = 0x81007; // DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_LINEARSIZE
1513 dds_format_flags = 0x4; // DDPF_FOURCC
1514 }
1515 else
1516 {
1517 dds_flags = 0x100F; // DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH
1518 dds_format_flags = 0x40; // DDPF_RGB
1519 }
1520 if (mipmaps)
1521 {
1522 dds_flags |= 0x20000; // DDSD_MIPMAPCOUNT
1523 dds_caps1 |= 0x400008; // DDSCAPS_MIPMAP | DDSCAPS_COMPLEX
1524 }
1525 if(hasalpha)
1526 dds_format_flags |= 0x1; // DDPF_ALPHAPIXELS
1527 memcpy(dds, "DDS ", 4);
1528 StoreLittleLong(dds+4, 124); // http://msdn.microsoft.com/en-us/library/bb943982%28v=vs.85%29.aspx says so
1529 StoreLittleLong(dds+8, dds_flags);
1530 StoreLittleLong(dds+12, mipinfo[0][1]); // height
1531 StoreLittleLong(dds+16, mipinfo[0][0]); // width
1532 StoreLittleLong(dds+24, 0); // depth
1533 StoreLittleLong(dds+28, mipmaps); // mipmaps
1534 StoreLittleLong(dds+76, 32); // format size
1535 StoreLittleLong(dds+80, dds_format_flags);
1536 StoreLittleLong(dds+108, dds_caps1);
1537 StoreLittleLong(dds+112, dds_caps2);
1538 if (bytesperblock)
1539 {
1540 StoreLittleLong(dds+20, mipinfo[0][2]); // linear size
1541 memcpy(dds+84, ddsfourcc, 4);
1542 for (mip = 0;mip < mipmaps;mip++)
1543 {
1544 qglGetCompressedTexImage(gltexturetypeenums[glt->texturetype], mip, dds + mipinfo[mip][3]);CHECKGLERROR
1545 }
1546 }
1547 else
1548 {
1549 StoreLittleLong(dds+20, mipinfo[0][0]*bytesperpixel); // pitch
1550 StoreLittleLong(dds+88, bytesperpixel*8); // bits per pixel
1551 dds[94] = dds[97] = dds[100] = dds[107] = 255; // bgra byte order masks
1552 for (mip = 0;mip < mipmaps;mip++)
1553 {
1554 qglGetTexImage(gltexturetypeenums[glt->texturetype], mip, GL_BGRA, GL_UNSIGNED_BYTE, dds + mipinfo[mip][3]);CHECKGLERROR
1555 }
1556 }
1557 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
1558 ret = FS_WriteFile(filename, dds, ddssize);
1559 Mem_Free(dds);
1560 return ret ? ddssize : -5;
1561#endif
1562}
void StoreLittleLong(unsigned char *buffer, unsigned int i)
Encode a little endian 32bit int to the given buffer.
Definition com_msg.c:95
qbool FS_WriteFile(const char *filename, const void *data, fs_offset_t len)
Definition fs.c:3592
#define GL_BGRA
Definition glquake.h:547
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
Definition glquake.h:533
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT
Definition glquake.h:530
#define GL_UNSIGNED_BYTE
Definition glquake.h:119
GLenum internalformat
Definition glquake.h:622
#define GL_TEXTURE_INTERNAL_FORMAT
Definition glquake.h:97
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
Definition glquake.h:532
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
Definition glquake.h:531
return ret
const char * gl_version
begins with 1.0.0, 1.1.0, 1.2.0, 1.2.1, 1.3.0, 1.3.1, or 1.4.0
Definition vid_shared.c:194

References CHECKGLERROR, gltexture_t::flags, FS_WriteFile(), GL_ActiveTexture(), GL_BGRA, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_TEXTURE_INTERNAL_FORMAT, GL_UNSIGNED_BYTE, gl_version, gltexturetypeenums, internalformat, Mem_Alloc, Mem_Free, NULL, R_Mesh_TexBound(), ret, StoreLittleLong(), tempmempool, TEXF_MIPMAP, TEXF_RGBMULTIPLYBYALPHA, gltexture_t::texnum, gltexture_t::texturetype, gltexture_t::tileheight, and gltexture_t::tilewidth.

Referenced by R_SkinFrame_LoadExternal_SkinFrame().

◆ R_TextureFlags()

int R_TextureFlags ( rtexture_t * rt)

Definition at line 2280 of file gl_textures.c.

2281{
2282 return rt ? ((gltexture_t *)rt)->flags : 0;
2283}

Referenced by R_SetupShader_Surface().

◆ R_TextureHeight()

int R_TextureHeight ( rtexture_t * rt)

Definition at line 2275 of file gl_textures.c.

2276{
2277 return rt ? ((gltexture_t *)rt)->inputheight : 0;
2278}

Referenced by Draw_CachePic_Flags(), Mod_Q3BSP_LoadFaces(), and R_Shadow_SetShadowmapParametersForLight().

◆ R_Textures_Frame()

void R_Textures_Frame ( void )

Definition at line 753 of file gl_textures.c.

754{
755#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
756 static int old_aniso = 0;
757 static qbool first_time_aniso = true;
758#endif
759
760 // could do procedural texture animation here, if we keep track of which
761 // textures were accessed this frame...
762
763 // free the resize buffers
765 if (resizebuffer)
766 {
769 }
771 {
774 }
775
776#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
777 if (old_aniso != gl_texture_anisotropy.integer)
778 {
779 gltexture_t *glt;
780 gltexturepool_t *pool;
781 GLint oldbindtexnum;
782
784
786
787 switch(vid.renderpath)
788 {
789 case RENDERPATH_GL32:
790 case RENDERPATH_GLES2:
791 // ignore the first difference, any textures loaded by now probably had the same aniso value
792 if (first_time_aniso)
793 {
794 first_time_aniso = false;
795 break;
796 }
799 for (pool = gltexturepoolchain;pool;pool = pool->next)
800 {
801 for (glt = pool->gltchain;glt;glt = glt->chain)
802 {
803 // only update already uploaded images
804 if (glt->texnum && (glt->flags & TEXF_MIPMAP) == TEXF_MIPMAP)
805 {
806 oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
807
808 qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
810
811 qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
812 }
813 }
814 }
815 break;
816 }
817 }
818#endif
819}
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
static unsigned char * resizebuffer
cvar_t gl_texture_anisotropy
Definition gl_textures.c:36
static unsigned char * colorconvertbuffer
static int resizebuffersize
#define GL_TEXTURE_MAX_ANISOTROPY_EXT
Definition glquake.h:199
#define bound(min, num, max)
Definition mathlib.h:34
unsigned int max_anisotropy
Definition vid.h:86

References bound, gltexture_t::chain, CHECKGLERROR, colorconvertbuffer, Cvar_SetValueQuick(), gltexture_t::flags, GL_ActiveTexture(), gl_texture_anisotropy, GL_TEXTURE_MAX_ANISOTROPY_EXT, gltexturepool_t::gltchain, gltexturepoolchain, gltexturetypeenums, cvar_t::integer, viddef_t::max_anisotropy, Mem_Free, gltexturepool_t::next, NULL, R_Mesh_TexBound(), viddef_t::renderpath, RENDERPATH_GL32, RENDERPATH_GLES2, resizebuffer, resizebuffersize, TEXF_MIPMAP, gltexture_t::texnum, gltexture_t::texturetype, and vid.

Referenced by R_UpdateVariables().

◆ R_TextureStats_Print()

void R_TextureStats_Print ( qbool printeach,
qbool printpool,
qbool printtotal )

Definition at line 582 of file gl_textures.c.

583{
584 int glsize;
585 int isloaded;
586 int pooltotal = 0, pooltotalt = 0, pooltotalp = 0, poolloaded = 0, poolloadedt = 0, poolloadedp = 0;
587 int sumtotal = 0, sumtotalt = 0, sumtotalp = 0, sumloaded = 0, sumloadedt = 0, sumloadedp = 0;
588 gltexture_t *glt;
589 gltexturepool_t *pool;
590 if (printeach)
591 Con_Print("glsize input loaded mip alpha name\n");
592 for (pool = gltexturepoolchain;pool;pool = pool->next)
593 {
594 pooltotal = 0;
595 pooltotalt = 0;
596 pooltotalp = 0;
597 poolloaded = 0;
598 poolloadedt = 0;
599 poolloadedp = 0;
600 for (glt = pool->gltchain;glt;glt = glt->chain)
601 {
602 glsize = R_CalcTexelDataSize(glt);
603 isloaded = glt->texnum != 0 || glt->renderbuffernum != 0;
604 pooltotal++;
605 pooltotalt += glsize;
606 pooltotalp += glt->inputdatasize;
607 if (isloaded)
608 {
609 poolloaded++;
610 poolloadedt += glsize;
611 poolloadedp += glt->inputdatasize;
612 }
613 if (printeach)
614 Con_Printf("%c%4i%c%c%4i%c %-24s %s %s %s %s\n", isloaded ? '[' : ' ', (glsize + 1023) / 1024, isloaded ? ']' : ' ', glt->inputtexels ? '[' : ' ', (glt->inputdatasize + 1023) / 1024, glt->inputtexels ? ']' : ' ', glt->textype->name, isloaded ? "loaded" : " ", (glt->flags & TEXF_MIPMAP) ? "mip" : " ", (glt->flags & TEXF_ALPHA) ? "alpha" : " ", glt->identifier);
615 }
616 if (printpool)
617 Con_Printf("texturepool %10p total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", (void *)pool, pooltotal, pooltotalt / 1048576.0, pooltotalp / 1048576.0, poolloaded, poolloadedt / 1048576.0, poolloadedp / 1048576.0, pooltotal - poolloaded, (pooltotalt - poolloadedt) / 1048576.0, (pooltotalp - poolloadedp) / 1048576.0);
618 sumtotal += pooltotal;
619 sumtotalt += pooltotalt;
620 sumtotalp += pooltotalp;
621 sumloaded += poolloaded;
622 sumloadedt += poolloadedt;
623 sumloadedp += poolloadedp;
624 }
625 if (printtotal)
626 Con_Printf("textures total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", sumtotal, sumtotalt / 1048576.0, sumtotalp / 1048576.0, sumloaded, sumloadedt / 1048576.0, sumloadedp / 1048576.0, sumtotal - sumloaded, (sumtotalt - sumloadedt) / 1048576.0, (sumtotalp - sumloadedp) / 1048576.0);
627}
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
static int R_CalcTexelDataSize(gltexture_t *glt)
const char * name
Definition gl_textures.c:69

References gltexture_t::chain, Con_Print(), Con_Printf(), gltexture_t::flags, gltexturepool_t::gltchain, gltexturepoolchain, gltexture_t::identifier, gltexture_t::inputdatasize, gltexture_t::inputtexels, textypeinfo_t::name, gltexturepool_t::next, R_CalcTexelDataSize(), gltexture_t::renderbuffernum, TEXF_ALPHA, TEXF_MIPMAP, gltexture_t::texnum, and gltexture_t::textype.

Referenced by R_TextureStats_f().

◆ R_TextureWidth()

int R_TextureWidth ( rtexture_t * rt)

Definition at line 2270 of file gl_textures.c.

2271{
2272 return rt ? ((gltexture_t *)rt)->inputwidth : 0;
2273}

Referenced by Draw_CachePic_Flags(), Mod_Q3BSP_LoadFaces(), and R_Shadow_SetShadowmapParametersForLight().

◆ R_UpdateTexture()

void R_UpdateTexture ( rtexture_t * rt,
const unsigned char * data,
int x,
int y,
int z,
int width,
int height,
int depth,
int combine )

Definition at line 2285 of file gl_textures.c.

2286{
2287 gltexture_t *glt = (gltexture_t *)rt;
2288 if (data == NULL)
2289 Host_Error("R_UpdateTexture: no data supplied");
2290 if (glt == NULL)
2291 Host_Error("R_UpdateTexture: no texture supplied");
2292 if (!glt->texnum)
2293 {
2294 Con_DPrintf("R_UpdateTexture: texture %p \"%s\" in pool %p has not been uploaded yet\n", (void *)glt, glt->identifier, (void *)glt->pool);
2295 return;
2296 }
2297 // update part of the texture
2298 if (glt->bufferpixels)
2299 {
2300 size_t j, bpp = glt->bytesperpixel;
2301
2302 // depth and sides are not fully implemented here - can still do full updates but not partial.
2303 if (glt->inputdepth != 1 || glt->sides != 1)
2304 Host_Error("R_UpdateTexture on buffered texture that is not 2D\n");
2305 if (x < 0 || y < 0 || z < 0 || glt->tilewidth < x + width || glt->tileheight < y + height || glt->tiledepth < z + depth)
2306 Host_Error("R_UpdateTexture on buffered texture with out of bounds coordinates (%i %i %i to %i %i %i is not within 0 0 0 to %i %i %i)", x, y, z, x + width, y + height, z + depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
2307
2308 for (j = 0; j < (size_t)height; j++)
2309 memcpy(glt->bufferpixels + ((y + j) * glt->tilewidth + x) * bpp, data + j * width * bpp, width * bpp);
2310
2311 switch(combine)
2312 {
2313 case 0:
2314 // immediately update the part of the texture, no combining
2316 break;
2317 case 1:
2318 // keep track of the region that is modified, decide later how big the partial update area is
2319 if (glt->buffermodified)
2320 {
2321 glt->modified_mins[0] = min(glt->modified_mins[0], x);
2322 glt->modified_mins[1] = min(glt->modified_mins[1], y);
2323 glt->modified_mins[2] = min(glt->modified_mins[2], z);
2324 glt->modified_maxs[0] = max(glt->modified_maxs[0], x + width);
2325 glt->modified_maxs[1] = max(glt->modified_maxs[1], y + height);
2326 glt->modified_maxs[2] = max(glt->modified_maxs[2], z + depth);
2327 }
2328 else
2329 {
2330 glt->buffermodified = true;
2331 glt->modified_mins[0] = x;
2332 glt->modified_mins[1] = y;
2333 glt->modified_mins[2] = z;
2334 glt->modified_maxs[0] = x + width;
2335 glt->modified_maxs[1] = y + height;
2336 glt->modified_maxs[2] = z + depth;
2337 }
2338 glt->dirty = true;
2339 break;
2340 default:
2341 case 2:
2342 // mark the entire texture as dirty, it will be uploaded later
2343 glt->buffermodified = true;
2344 glt->modified_mins[0] = 0;
2345 glt->modified_mins[1] = 0;
2346 glt->modified_mins[2] = 0;
2347 glt->modified_maxs[0] = glt->tilewidth;
2348 glt->modified_maxs[1] = glt->tileheight;
2349 glt->modified_maxs[2] = glt->tiledepth;
2350 glt->dirty = true;
2351 break;
2352 }
2353 }
2354 else
2356}
GLubyte GLubyte GLubyte z
Definition glquake.h:782
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
#define min(A, B)
Definition mathlib.h:37

References gltexture_t::buffermodified, gltexture_t::bufferpixels, gltexture_t::bytesperpixel, Con_DPrintf(), data, depth, gltexture_t::dirty, height, Host_Error(), gltexture_t::identifier, gltexture_t::inputdepth, max, min, gltexture_t::modified_maxs, gltexture_t::modified_mins, NULL, R_UploadFullTexture(), R_UploadPartialTexture(), gltexture_t::sides, gltexture_t::texnum, gltexture_t::tiledepth, gltexture_t::tileheight, gltexture_t::tilewidth, width, x, y, and z.

Referenced by Draw_NewPic(), R_BuildFogTexture(), R_BuildLightMap(), R_Shadow_BounceGrid_ConvertPixelsAndUpload(), and R_UpdateVariables().

Variable Documentation

◆ gl_texturecompression

struct cvar_s gl_texturecompression
extern

Definition at line 37 of file gl_textures.c.

37{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression", "0", "whether to compress textures, a value of 0 disables compression (even if the individual cvars are 1), 1 enables fast (low quality) compression at startup, 2 enables slow (high quality) compression at startup"};
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by Draw_CachePic_Flags(), M_Menu_Video_AdjustSliders(), M_Video_Draw(), Mod_Sprite_SharedSetup(), R_LoadCubemap(), R_SkinFrame_LoadExternal_SkinFrame(), R_Textures_Init(), and R_UploadFullTexture().

◆ gl_texturecompression_2d

struct cvar_s gl_texturecompression_2d
extern

Definition at line 42 of file gl_textures.c.

42{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_2d", "0", "whether to compress 2d (hud/menu) textures other than the font"};

Referenced by Draw_CachePic_Flags(), and R_Textures_Init().

◆ gl_texturecompression_color

struct cvar_s gl_texturecompression_color
extern

Definition at line 38 of file gl_textures.c.

38{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_color", "1", "whether to compress colormap (diffuse) textures"};

Referenced by GL_Setup(), R_SkinFrame_LoadExternal_SkinFrame(), and R_Textures_Init().

◆ gl_texturecompression_gloss

struct cvar_s gl_texturecompression_gloss
extern

Definition at line 40 of file gl_textures.c.

40{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_gloss", "1", "whether to compress glossmap (specular) textures"};

Referenced by R_SkinFrame_LoadExternal_SkinFrame(), and R_Textures_Init().

◆ gl_texturecompression_glow

struct cvar_s gl_texturecompression_glow
extern

Definition at line 41 of file gl_textures.c.

41{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_glow", "1", "whether to compress glowmap (luma) textures"};

Referenced by R_SkinFrame_LoadExternal_SkinFrame(), and R_Textures_Init().

◆ gl_texturecompression_lightcubemaps

struct cvar_s gl_texturecompression_lightcubemaps
extern

Definition at line 46 of file gl_textures.c.

46{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_lightcubemaps", "1", "whether to compress light cubemaps (spotlights and other light projection images)"};

Referenced by R_LoadCubemap(), and R_Textures_Init().

◆ gl_texturecompression_normal

struct cvar_s gl_texturecompression_normal
extern

Definition at line 39 of file gl_textures.c.

39{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_normal", "0", "whether to compress normalmap (normalmap) textures"};

Referenced by R_SkinFrame_LoadExternal_SkinFrame(), and R_Textures_Init().

◆ gl_texturecompression_q3bspdeluxemaps

struct cvar_s gl_texturecompression_q3bspdeluxemaps
extern

Definition at line 44 of file gl_textures.c.

44{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_q3bspdeluxemaps", "0", "whether to compress deluxemaps in q3bsp format levels (only levels compiled with q3map2 -deluxe have these)"};

Referenced by Mod_Q3BSP_LoadLightmaps(), and R_Textures_Init().

◆ gl_texturecompression_q3bsplightmaps

struct cvar_s gl_texturecompression_q3bsplightmaps
extern

Definition at line 43 of file gl_textures.c.

43{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_q3bsplightmaps", "0", "whether to compress lightmaps in q3bsp format levels"};

Referenced by Mod_Q3BSP_LoadLightmaps(), and R_Textures_Init().

◆ gl_texturecompression_reflectmask

struct cvar_s gl_texturecompression_reflectmask
extern

Definition at line 47 of file gl_textures.c.

47{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_reflectmask", "1", "whether to compress reflection cubemap masks (mask of which areas of the texture should reflect the generic shiny cubemap)"};

Referenced by R_SkinFrame_LoadExternal_SkinFrame(), and R_Textures_Init().

◆ gl_texturecompression_sky

struct cvar_s gl_texturecompression_sky
extern

Definition at line 45 of file gl_textures.c.

45{CF_CLIENT | CF_ARCHIVE, "gl_texturecompression_sky", "0", "whether to compress sky textures"};

Referenced by R_LoadSkyBox(), and R_Textures_Init().

◆ r_texture_dds_load

struct cvar_s r_texture_dds_load
extern

Definition at line 156 of file gl_rmain.c.

156{CF_CLIENT | CF_ARCHIVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"};

Referenced by GL_Main_Init(), and gl_main_start().

◆ r_texture_dds_save

struct cvar_s r_texture_dds_save
extern

Definition at line 157 of file gl_rmain.c.

157{CF_CLIENT | CF_ARCHIVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"};

Referenced by GL_Main_Init(), gl_main_start(), and R_SkinFrame_LoadExternal_SkinFrame().