diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 888a8414e..db15bf5d2 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -492,6 +492,7 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) if (next->data) Z_Free(next->data); next->data = NULL; + HWD.pfnDeleteTexture(next); // Free the old colormap mipmap from memory. free(next); diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index b7c46b2e1..b49c0f316 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -253,7 +253,17 @@ enum ETextureFlags TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 }; -typedef struct GLMipmap_s FTextureInfo; +struct FTextureInfo +{ + UINT32 width, height; + UINT32 downloaded; + UINT32 format; + + struct GLMipmap_s *texture; + struct FTextureInfo *prev, *next; +}; +typedef struct FTextureInfo FTextureInfo; + struct FLightInfo { diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 7d58dc495..8376ab405 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -36,8 +36,9 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FBOOLEAN StencilMask, FRGBAFloat *ClearColor); -EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); -EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo); +EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo); +EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo); +EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT16 *dst_data); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -99,6 +100,7 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; UpdateTexture pfnUpdateTexture; + DeleteTexture pfnDeleteTexture; ReadScreenTexture pfnReadScreenTexture; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 131775c53..2f0d72cd7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4947,7 +4947,6 @@ void HWR_ProjectSprite(mobj_t *thing) spritexscale = FIXED_TO_FLOAT(interp.spritexscale); spriteyscale = FIXED_TO_FLOAT(interp.spriteyscale); - // transform the origin point tr_x = FIXED_TO_FLOAT(interp.x) - gr_viewx; tr_y = FIXED_TO_FLOAT(interp.y) - gr_viewy; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9fcf90a62..e8a1cc003 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -79,8 +79,9 @@ static GLuint lt_downloaded = 0; // currently bound lighttable texture static GLfloat fov = 90.0f; static FBITFIELD CurrentPolyFlags; -static FTextureInfo *gr_cachetail = NULL; -static FTextureInfo *gr_cachehead = NULL; +// Linked list of all textures. +static FTextureInfo *TexCacheTail = NULL; +static FTextureInfo *TexCacheHead = NULL; static RGBA_t *textureBuffer = NULL; static size_t textureBufferSize = 0; @@ -935,7 +936,7 @@ void SetStates(void) pglEnable(GL_STENCIL_TEST); pglEnable(GL_DEPTH_TEST); // check the depth buffer - pglDepthMask(GL_TRUE); // enable writing to depth buffer + pglDepthMask(GL_TRUE); // enable writing to depth buffer pglClearDepth(1.0f); pglDepthRange(0.0f, 1.0f); pglDepthFunc(GL_LEQUAL); @@ -954,6 +955,40 @@ void SetStates(void) pglScalef(1.0f, 1.0f, -1.0f); pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } +// -----------------+ +// DeleteTexture : Deletes a texture from the GPU and frees its data +// -----------------+ +EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo) +{ + FTextureInfo *head = TexCacheHead; + + if (!pTexInfo) + return; + else if (pTexInfo->downloaded) + pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded); + + while (head) + { + if (head->downloaded == pTexInfo->downloaded) + { + if (head->next) + head->next->prev = head->prev; + else // no next -> tail is being deleted -> update TexCacheTail + TexCacheTail = head->prev; + if (head->prev) + head->prev->next = head->next; + else // no prev -> head is being deleted -> update TexCacheHead + TexCacheHead = head->next; + free(head); + break; + } + + head = head->next; + } + + pTexInfo->downloaded = 0; +} + // -----------------+ // Flush : flush OpenGL textures @@ -961,21 +996,29 @@ void SetStates(void) // -----------------+ void Flush(void) { - //GL_DBG_Printf("HWR_Flush()\n"); + //GL_DBG_Printf ("HWR_Flush()\n"); - while (gr_cachehead) + while (TexCacheHead) { - // this is not necessary at all, because you have loaded them normally, - // and so they already are in your list! - if (gr_cachehead->downloaded) - pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); - gr_cachehead->downloaded = 0; - gr_cachehead = gr_cachehead->nextmipmap; - } - gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL + FTextureInfo *pTexInfo = TexCacheHead; + GLMipmap_t *texture = pTexInfo->texture; + if (pTexInfo->downloaded) + { + pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded); + pTexInfo->downloaded = 0; + } + + if (texture) + texture->downloaded = 0; + + TexCacheHead = pTexInfo->next; + free(pTexInfo); + } + + TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL tex_downloaded = 0; - + free(textureBuffer); textureBuffer = NULL; textureBufferSize = 0; @@ -1334,7 +1377,7 @@ static void AllocTextureBuffer(GLMipmap_t *pTexInfo) // -----------------+ // UpdateTexture : Updates texture data. // -----------------+ -EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) +EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) { // Upload a texture GLuint num = pTexInfo->downloaded; @@ -1391,7 +1434,6 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) tex[w*j+i].s.alpha = *pImgData; pImgData++; } - } } } @@ -1474,7 +1516,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 16); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); } else @@ -1506,7 +1548,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 16); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); } else @@ -1567,7 +1609,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) // -----------------+ // SetTexture : The mipmap becomes the current texture source // -----------------+ -EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) +EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo) { if (!pTexInfo) { @@ -1584,15 +1626,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } else { + FTextureInfo *newTex = calloc(1, sizeof (*newTex)); + UpdateTexture(pTexInfo); - pTexInfo->nextmipmap = NULL; - if (gr_cachetail) - { // insertion at the tail - gr_cachetail->nextmipmap = pTexInfo; - gr_cachetail = pTexInfo; + + newTex->texture = pTexInfo; + newTex->downloaded = (UINT32)pTexInfo->downloaded; + newTex->width = (UINT32)pTexInfo->width; + newTex->height = (UINT32)pTexInfo->height; + newTex->format = (UINT32)pTexInfo->format; + + // insertion at the tail + if (TexCacheTail) + { + newTex->prev = TexCacheTail; + TexCacheTail->next = newTex; + TexCacheTail = newTex; } else // initialization of the linked list - gr_cachetail = gr_cachehead = pTexInfo; + TexCacheTail = TexCacheHead = newTex; } } @@ -2794,7 +2846,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) EXPORT INT32 HWRAPI(GetTextureUsed) (void) { - FTextureInfo *tmp = gr_cachehead; + FTextureInfo *tmp = TexCacheHead; INT32 res = 0; while (tmp) @@ -2811,7 +2863,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) // Add it up! res += tmp->height*tmp->width*bpp; - tmp = tmp->nextmipmap; + tmp = tmp->next; } return res; diff --git a/src/r_defs.h b/src/r_defs.h index f5a4195bc..5a78a362b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -639,6 +639,10 @@ typedef struct // textures from the TEXTURE1 list of patches. // // WARNING: this structure is cloned in GLPatch_t +#if defined(_MSC_VER) +#pragma pack(1) +#endif + typedef struct { INT16 width; // bounding box size @@ -656,20 +660,6 @@ typedef struct #endif } patch_t; -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -typedef struct -{ - INT16 width; // bounding box size - INT16 height; - INT16 leftoffset; // pixels to the left of origin - INT16 topoffset; // pixels below the origin - INT32 columnofs[8]; // only [width] used - // the [0] is &columnofs[width] -} ATTRPACK softwarepatch_t; - #ifdef _MSC_VER #pragma warning(disable : 4200) #endif diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 64f9b7da9..23526a98f 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -86,6 +86,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(UpdateTexture); + GETFUNC(DeleteTexture); GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a1dd8bef6..1738145e6 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -2268,6 +2268,7 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); + HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL); HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);