From d93593c8b32946e96fb1509afd3440fdc6cea0cf Mon Sep 17 00:00:00 2001 From: black Date: Thu, 22 Nov 2007 00:06:00 +0000 Subject: [PATCH] Add support for dynamic textures to the low-level texture handler. Use R_MakeTextureDynamic to make a standard texture dynamic and set its update callback, etc. and use R_MarkDirtyTexture to mark it dirty (ie. needs an update as soon as it is used again). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7711 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_textures.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- r_textures.h | 6 ++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/gl_textures.c b/gl_textures.c index f26b44ad..f32c848e 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -28,11 +28,13 @@ static mempool_t *texturemempool; // note: this must not conflict with TEXF_ flags in r_textures.h // cleared when a texture is uploaded -#define GLTEXF_UPLOAD 0x00010000 +#define GLTEXF_UPLOAD 0x00010000 // bitmask for mismatch checking #define GLTEXF_IMPORTANTBITS (0) // set when image is uploaded and freed -#define GLTEXF_DESTROYED 0x00040000 +#define GLTEXF_DESTROYED 0x00040000 +// dynamic texture (treat texnum == 0 differently) +#define GLTEXF_DYNAMIC 0x00080000 typedef struct textypeinfo_s { @@ -80,6 +82,13 @@ typedef struct gltexture_s // (must be identical in rtexture_t) int texnum; // GL texture slot number + // dynamic texture stuff [11/22/2007 Black] + // used to hold the texture number of dirty textures + int dirtytexnum; + updatecallback_t updatecallback; + void *updatacallback_data; + // --- [11/22/2007 Black] + // pointer to texturepool (check this to see if the texture is allocated) struct gltexturepool_s *pool; // pointer to next texture in texturepool chain @@ -206,6 +215,34 @@ static textypeinfo_t *R_GetTexTypeInfo(int textype, int flags) return NULL; // this line only to hush compiler warnings } +// dynamic texture code [11/22/2007 Black] +void R_MarkDirtyTexture(rtexture_t *rt) { + gltexture_t *glt = (gltexture_t*) rt; + // dont do anything if the texture is already dirty (and make sure this *is* a dynamic texture after all!) + if( !glt->dirtytexnum && glt->flags & GLTEXF_DYNAMIC ) { + glt->dirtytexnum = glt->texnum; + // mark it as dirty, so R_RealGetTexture gets called + glt->texnum = 0; + } +} + +void R_MakeTextureDynamic(rtexture_t *rt, updatecallback_t updatecallback, void *data) { + gltexture_t *glt = (gltexture_t*) rt; + glt->flags |= GLTEXF_DYNAMIC; + glt->updatecallback = updatecallback; + glt->updatacallback_data = data; +} + +static void R_UpdateDynamicTexture(gltexture_t *glt) { + glt->texnum = glt->dirtytexnum; + // reset dirtytexnum again (not dirty anymore) + glt->dirtytexnum = 0; + // TODO: now assert that t->texnum != 0 ? + if( glt->updatecallback ) { + glt->updatecallback( (rtexture_t*) glt, glt->updatacallback_data ); + } +} + static void R_UploadTexture(gltexture_t *t); static void R_PrecacheTexture(gltexture_t *glt) @@ -232,6 +269,9 @@ int R_RealGetTexture(rtexture_t *rt) glt = (gltexture_t *)rt; if (glt->flags & GLTEXF_UPLOAD) R_UploadTexture(glt); + if (glt->flags & GLTEXF_DYNAMIC) + R_UpdateDynamicTexture(glt); + return glt->texnum; } else @@ -996,6 +1036,10 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden glt->bytesperpixel = texinfo->internalbytesperpixel; glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1; glt->texnum = -1; + // init the dynamic texture attributes, too [11/22/2007 Black] + glt->dirtytexnum = 0; + glt->updatecallback = NULL; + glt->updatacallback_data = NULL; if (data) { diff --git a/r_textures.h b/r_textures.h index 0cef2550..51978f81 100644 --- a/r_textures.h +++ b/r_textures.h @@ -45,6 +45,8 @@ typedef struct rtexturepool_s } rtexturepool_t; +typedef void (*updatecallback_t)(rtexture_t *rt, void *data); + // allocate a texture pool, to be used with R_LoadTexture rtexturepool_t *R_AllocTexturePool(void); // free a texture pool (textures can not be freed individually) @@ -94,5 +96,9 @@ int R_TextureHeight(rtexture_t *rt); // frees processing buffers each frame, and may someday animate procedural textures void R_Textures_Frame(void); +// maybe rename this - sounds awful? [11/21/2007 Black] +void R_MarkDirtyTexture(rtexture_t *rt); +void R_MakeTextureDynamic(rtexture_t *rt, updatecallback_t updatecallback, void *data); + #endif -- 2.39.2