diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 593da1058..c9b31932e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -28,66 +28,232 @@ #include "../r_draw.h" #include "../r_patch.h" // patch rotation -// Values set after a call to HWR_ResizeBlock() -static INT32 blocksize, blockwidth, blockheight; - -INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes -INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole +INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes +INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc. - // Returns a pointer to the palette which should be used for caching textures. RGBA_t *HWR_GetTexturePalette(void) { return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette; } -// sprite, use alpha and chroma key for hole +static INT32 format2bpp(GLTextureFormat_t format) +{ + if (format == GL_TEXFMT_RGBA) + return 4; + else if (format == GL_TEXFMT_ALPHA_INTENSITY_88 || format == GL_TEXFMT_AP_88) + return 2; + else + return 1; +} + +// This code was originally placed directly in HWR_DrawPatchInCache. +// It is now split from it for my sanity! (and the sanity of others) +// -- Monster Iestyn (13/02/19) +static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp, RGBA_t *palette) +{ + fixed_t yfrac, position, count; + UINT8 *dest; + const UINT8 *source; + INT32 topdelta, prevdelta = -1; + INT32 originy = 0; + + // for writing a pixel to dest + RGBA_t colortemp; + UINT8 alpha; + UINT8 texel; + UINT16 texelu16; + + (void)patchheight; // This parameter is unused + + if (originPatch) // originPatch can be NULL here, unlike in the software version + originy = originPatch->originy; + + while (patchcol->topdelta != 0xff) + { + topdelta = patchcol->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)patchcol + 3; + count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; + position = originy + topdelta; + + yfrac = 0; + //yfracstep = (patchcol->length << FRACBITS) / count; + if (position < 0) + { + yfrac = -position<> FRACBITS); + position = 0; + } + + position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS; + + if (position < 0) + position = 0; + + if (position + count >= pblockheight) + count = pblockheight - position; + + dest = block + (position*blockmodulo); + while (count > 0) + { + count--; + + texel = source[yfrac>>FRACBITS]; + + alpha = 0xff; + + //Hurdler: not perfect, but better than holes + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + alpha = 0x00; + + //texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + // Lat: Don't do that, some weirdos still use CYAN on their WALLTEXTURES for translucency :V + + //Hurdler: 25/04/2000: now support colormap in hardware mode + else if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // hope compiler will get this switch out of the loops (dreams...) + // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) + // Alam: SRB2 uses Mingw, HUGS + switch (bpp) + { + case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + memcpy(dest, &texelu16, sizeof(UINT16)); + break; + case 3 : colortemp = palette[texel]; + memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); + break; + case 4 : colortemp = palette[texel]; + colortemp.s.alpha = alpha; + memcpy(dest, &colortemp, sizeof(RGBA_t)); + break; + // default is 1 + default: *dest = texel; + break; + } + + dest += blockmodulo; + yfrac += yfracstep; + } + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); + } +} + +// Simplified patch caching function +// for use by sprites and other patches that are not part of a wall texture +// no alpha or flipping should be present since we do not want non-texture graphics to have them +// no offsets are used either +// -- Monster Iestyn (13/02/19) static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, - INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, - INT32 ptexturewidth, INT32 ptextureheight, - INT32 originx, INT32 originy, // where to draw patch in surface block - const patch_t *realpatch, INT32 bpp, RGBA_t *palette) + INT32 pblockwidth, INT32 pblockheight, + INT32 pwidth, INT32 pheight, + const patch_t *realpatch) +{ + INT32 ncols; + fixed_t xfrac, xfracstep; + fixed_t yfracstep, scale_y; + const column_t *patchcol; + UINT8 *block = mipmap->data; + INT32 bpp; + INT32 blockmodulo; + RGBA_t *palette; + + if (pwidth <= 0 || pheight <= 0) + return; + + palette = HWR_GetTexturePalette(); + + ncols = (pwidth * pblockwidth) / pwidth; + + // source advance + xfrac = 0; + xfracstep = (pwidth << FRACBITS) / pblockwidth; + yfracstep = (pheight << FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / pheight; + + bpp = format2bpp(mipmap->format); + + if (bpp < 1 || bpp > 4) + I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + + blockmodulo = pblockwidth*bpp; + + // Draw each column to the block cache + for (; ncols--; block += bpp, xfrac += xfracstep) + { + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + + HWR_DrawColumnInCache(patchcol, block, mipmap, + pblockheight, blockmodulo, + yfracstep, scale_y, + NULL, pheight, // not that pheight is going to get used anyway... + bpp, palette); + } +} + +// This function we use for caching patches that belong to textures +static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, + INT32 pblockwidth, INT32 pblockheight, + texture_t *texture, texpatch_t *patch, + const patch_t *realpatch) { INT32 x, x1, x2; INT32 col, ncols; fixed_t xfrac, xfracstep; - fixed_t yfrac, yfracstep, position, count; - fixed_t scale_y; - RGBA_t colortemp; - UINT8 *dest; - const UINT8 *source; + fixed_t yfracstep, scale_y; const column_t *patchcol; - UINT8 alpha; - UINT8 *block = mipmap->grInfo.data; - UINT8 texel; - UINT16 texelu16; + UINT8 *block = mipmap->data; + INT32 bpp; + INT32 blockmodulo; + INT32 width, height; + RGBA_t *palette; - x1 = originx; - x2 = x1 + SHORT(realpatch->width); + if (texture->width <= 0 || texture->height <= 0) + return; + + palette = HWR_GetTexturePalette(); + x1 = patch->originx; + width = SHORT(realpatch->width); + height = SHORT(realpatch->height); + x2 = x1 + width; + + if (x1 > texture->width || x2 < 0) + return; // patch not located within texture's x bounds, ignore + + if (patch->originy > texture->height || (patch->originy + height) < 0) + return; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; - if (x2 > ptexturewidth) - x2 = ptexturewidth; + // right edge + if (x2 > texture->width) + x2 = texture->width; - if (!ptexturewidth) - return; - - palette = HWR_GetTexturePalette(); - - col = x * pblockwidth / ptexturewidth; - ncols = ((x2 - x) * pblockwidth) / ptexturewidth; + col = x * pblockwidth / texture->width; + ncols = ((x2 - x) * pblockwidth) / texture->width; /* - CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", SHORT(realpatch->width), - SHORT(realpatch->height), - ptexturewidth, - textureheight, - pblockwidth,pblockheight); + CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", + width, height, + texture->width, texture->height, + pblockwidth, pblockheight); CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x); */ @@ -96,221 +262,40 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (x1 < 0) xfrac = -x1< 4) - I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + xfracstep = (texture->width << FRACBITS) / pblockwidth; + yfracstep = (texture->height<< FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / texture->height; + bpp = format2bpp(mipmap->format); + + if (bpp < 1 || bpp > 4) + I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp); + + blockmodulo = pblockwidth*bpp; + + // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { - INT32 topdelta, prevdelta = -1; - patchcol = (const column_t *)((const UINT8 *)realpatch - + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); - scale_y = (pblockheight << FRACBITS) / ptextureheight; - - while (patchcol->topdelta != 0xff) - { - topdelta = patchcol->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (const UINT8 *)patchcol + 3; - count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; - position = originy + topdelta; - - yfrac = 0; - //yfracstep = (patchcol->length << FRACBITS) / count; - if (position < 0) - { - yfrac = -position<> FRACBITS); - position = 0; - } - - position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS; - - if (position < 0) - position = 0; - - if (position + count >= pblockheight) - count = pblockheight - position; - - dest = block + (position*blockmodulo); - while (count > 0) - { - count--; - - texel = source[yfrac>>FRACBITS]; - alpha = 0xff; - - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - alpha = 0x00; - - //texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; - // Lat: Don't do that, some weirdos still use CYAN on their WALLTEXTURES for translucency :V - - //Hurdler: 25/04/2000: now support colormap in hardware mode - if (mipmap->colormap) - texel = mipmap->colormap[texel]; - - // hope compiler will get this switch out of the loops (dreams...) - // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) - // Alam: SRB2 uses Mingw, HUGS - switch (bpp) - { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); - memcpy(dest, &texelu16, sizeof(UINT16)); - break; - case 3 : colortemp = palette[texel]; - memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); - break; - case 4 : colortemp = palette[texel]; - colortemp.s.alpha = alpha; - memcpy(dest, &colortemp, sizeof(RGBA_t)); - break; - // default is 1 - default: *dest = texel; - break; - } - - dest += blockmodulo; - yfrac += yfracstep; - } - patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); - } + HWR_DrawColumnInCache(patchcol, block, mipmap, + pblockheight, blockmodulo, + yfracstep, scale_y, + patch, height, + bpp, palette); } } -// resize the patch -// set : blocksize = blockwidth * blockheight (no bpp used) -// blockwidth -// blockheight -//note : 8bit (1 byte per pixel) palettized format -static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, - GLTexInfo *grInfo) -{ - // Build the full textures from patches. - static const GLlod_t gr_lods[9] = - { - GR_LOD_LOG2_256, - GR_LOD_LOG2_128, - GR_LOD_LOG2_64, - GR_LOD_LOG2_32, - GR_LOD_LOG2_16, - GR_LOD_LOG2_8, - GR_LOD_LOG2_4, - GR_LOD_LOG2_2, - GR_LOD_LOG2_1 - }; - - typedef struct - { - GLAspectRatio_t aspect; - float max_s; - float max_t; - } booring_aspect_t; - - static const booring_aspect_t gr_aspects[8] = - { - {GR_ASPECT_LOG2_1x1, 255, 255}, - {GR_ASPECT_LOG2_2x1, 255, 127}, - {GR_ASPECT_LOG2_4x1, 255, 63}, - {GR_ASPECT_LOG2_8x1, 255, 31}, - - {GR_ASPECT_LOG2_1x1, 255, 255}, - {GR_ASPECT_LOG2_1x2, 127, 255}, - {GR_ASPECT_LOG2_1x4, 63, 255}, - {GR_ASPECT_LOG2_1x8, 31, 255} - }; - - INT32 j,k; - INT32 max,min; - - // size up to nearest power of 2 - blockwidth = 1; - while (blockwidth < originalwidth) - blockwidth <<= 1; - // scale down the original graphics to fit in 2048 - if (blockwidth > 2048) - blockwidth = 2048; - - // size up to nearest power of 2 - blockheight = 1; - while (blockheight < originalheight) - blockheight <<= 1; - // scale down the original graphics to fit in 2048 - if (blockheight > 2048) - blockheight = 2048; - - // do the boring LOD stuff.. blech! - if (blockwidth >= blockheight) - { - max = blockwidth; - min = blockheight; - } - else - { - max = blockheight; - min = blockwidth; - } - - for (k = 2048, j = 0; k > max && j < 8; j++) - k>>=1; - grInfo->smallLodLog2 = gr_lods[j]; - grInfo->largeLodLog2 = gr_lods[j]; - - for (k = max, j = 0; k > min && j < 4; j++) - k>>=1; - // aspect ratio too small for 3Dfx (eg: 8x128 is 1x16 : use 1x8) - if (j == 4) - { - j = 3; - //CONS_Debug(DBG_RENDER, "HWR_ResizeBlock : bad aspect ratio %dx%d\n", blockwidth,blockheight); - if (blockwidth < blockheight) - blockwidth = max>>3; - else - blockheight = max>>3; - } - if (blockwidth < blockheight) - j += 4; - grInfo->aspectRatioLog2 = gr_aspects[j].aspect; - - blocksize = blockwidth * blockheight; - - //CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight); -} - - -static const INT32 format2bpp[16] = -{ - 0, //0 - 0, //1 - 1, //2 GR_TEXFMT_ALPHA_8 - 1, //3 GR_TEXFMT_INTENSITY_8 - 1, //4 GR_TEXFMT_ALPHA_INTENSITY_44 - 1, //5 GR_TEXFMT_P_8 - 4, //6 GR_RGBA - 0, //7 - 0, //8 - 0, //9 - 2, //10 GR_TEXFMT_RGB_565 - 2, //11 GR_TEXFMT_ARGB_1555 - 2, //12 GR_TEXFMT_ARGB_4444 - 2, //13 GR_TEXFMT_ALPHA_INTENSITY_88 - 2, //14 GR_TEXFMT_AP_88 -}; - static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; INT32 bpp, i; UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); + INT32 blocksize = (grMipmap->width * grMipmap->height); - bpp = format2bpp[grMipmap->grInfo.format]; - block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data)); +bpp = format2bpp(grMipmap->format); + block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->data));; switch (bpp) { @@ -331,12 +316,13 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) // Create a composite texture from patches, adapt the texture size to a power of 2 // height and width for the hardware texture cache. // -static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) +static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) { UINT8 *block; texture_t *texture; texpatch_t *patch; patch_t *realpatch; + INT32 blockwidth, blockheight, blocksize; INT32 i; boolean skyspecial = false; //poor hack for Legacy large skies.. @@ -360,15 +346,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) else grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; - HWR_ResizeBlock (texture->width, texture->height, &grtex->mipmap.grInfo); - grtex->mipmap.width = (UINT16)blockwidth; - grtex->mipmap.height = (UINT16)blockheight; - //grtex->mipmap.grInfo.format = textureformat; - + grtex->mipmap.width = (UINT16)texture->width; + grtex->mipmap.height = (UINT16)texture->height; + if (skyspecial) - grtex->mipmap.grInfo.format = GR_RGBA; // that skyspecial code below assumes this format ... + grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... else - grtex->mipmap.grInfo.format = textureformat; + grtex->mipmap.format = textureformat; grtex->mipmap.colormap = colormaps; @@ -376,7 +360,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) if (encoremap) grtex->mipmap.colormap += (256*32); #endif - + + blockwidth = texture->width; + blockheight = texture->height; + blocksize = (blockwidth * blockheight); block = MakeBlock(&grtex->mipmap); if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) @@ -401,17 +388,14 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - HWR_DrawPatchInCache(&grtex->mipmap, + HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, - blockwidth*format2bpp[grtex->mipmap.grInfo.format], - texture->width, texture->height, - patch->originx, patch->originy, - realpatch, - format2bpp[grtex->mipmap.grInfo.format], palette); + texture, patch, + realpatch); Z_Unlock(realpatch); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( - if (format2bpp[grtex->mipmap.grInfo.format]==4) + if (format2bpp(grtex->mipmap.format)==4) { for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp { @@ -430,10 +414,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) // patch may be NULL if grMipmap has been initialised already and makebitmap is false void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) { - INT32 newwidth, newheight; - - RGBA_t *palette = HWR_GetTexturePalette(); - // don't do it twice (like a cache) if (grMipmap->width == 0) { @@ -445,43 +425,28 @@ void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, bo grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->topoffset = SHORT(patch->topoffset); - // resize patch - HWR_ResizeBlock(SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); - grMipmap->width = (UINT16)blockwidth; - grMipmap->height = (UINT16)blockheight; + grMipmap->width = (UINT16)SHORT(patch->width); + grMipmap->height = (UINT16)SHORT(patch->height); // no wrap around, no chroma key grMipmap->flags = 0; // setup the texture info - grMipmap->grInfo.format = patchformat; - } - else - { - blockwidth = grMipmap->width; - blockheight = grMipmap->height; - blocksize = blockwidth * blockheight; + grMipmap->format = patchformat; } - Z_Free(grMipmap->grInfo.data); - grMipmap->grInfo.data = NULL; - - newwidth = min(grPatch->width, blockwidth); - newheight = min(grPatch->height, blockheight); + Z_Free(grMipmap->data); + grMipmap->data = NULL; if (makebitmap) { MakeBlock(grMipmap); HWR_DrawPatchInCache(grMipmap, - newwidth, newheight, - blockwidth*format2bpp[grMipmap->grInfo.format], grPatch->width, grPatch->height, - 0, 0, - patch, - format2bpp[grMipmap->grInfo.format], palette); + grPatch->width, grPatch->height, + patch); } - grPatch->max_s = (float)newwidth / (float)blockwidth; - grPatch->max_t = (float)newheight / (float)blockheight; + grPatch->max_s = grPatch->max_t = 1.0f; } // ================================================= @@ -489,7 +454,7 @@ void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, bo // ================================================= static size_t gr_numtextures; -static GLTexture_t *gr_textures; // for ALL Doom textures +static GLMapTexture_t *gr_textures; // For all textures void HWR_InitTextureCache(void) { @@ -528,16 +493,16 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) pat->mipmap->nextcolormap = next->nextcolormap; // Free image data from memory. - if (next->grInfo.data) - Z_Free(next->grInfo.data); - next->grInfo.data = NULL; + if (next->data) + Z_Free(next->data); + next->data = NULL; - // Free the old colormap from memory. + // Free the old colormap mipmap from memory. free(next); } } -void HWR_FreeTextureCache(void) +void HWR_FreeMipmapCache(void) { INT32 i; // free references to the textures @@ -553,6 +518,12 @@ void HWR_FreeTextureCache(void) // free all patch colormaps after each level: must be done after ClearMipMapCache! for (i = 0; i < numwadfiles; i++) M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); +} + +void HWR_FreeTextureCache(void) +{ + // free references to the textures + HWR_FreeMipmapCache(); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it @@ -562,35 +533,30 @@ void HWR_FreeTextureCache(void) gr_numtextures = 0; } -void HWR_PrepLevelCache(size_t pnumtextures) +void HWR_LoadTextures(size_t pnumtextures) { - // problem: the mipmap cache management hold a list of mipmaps.. but they are - // reallocated on each level.. - //sub-optimal, but 1) just need re-download stuff in hardware cache VERY fast - // 2) sprite/menu stuff mixed with level textures so can't do anything else - // we must free it since numtextures changed HWR_FreeTextureCache(); gr_numtextures = pnumtextures; gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); if (gr_textures == NULL) - I_Error("HWR_PrepLevelCache: can't alloc gr_textures"); + I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!"); } // -------------------------------------------------------------------------- // Make sure texture is downloaded and set it as the source // -------------------------------------------------------------------------- -GLTexture_t *HWR_GetTexture(INT32 tex) +GLMapTexture_t *HWR_GetTexture(INT32 tex) { - GLTexture_t *grtex; + GLMapTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif grtex = &gr_textures[tex]; - if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) + if (!grtex->mipmap.data && !grtex->mipmap.downloaded) HWR_GenerateTexture(tex, grtex); // If hardware does not have the texture, then call pfnSetTexture to upload it @@ -600,7 +566,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) HWR_SetCurrentTexture(&grtex->mipmap); // The system-memory data can be purged now. - Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED); return grtex; } @@ -616,10 +582,7 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) // setup the texture info - grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; - grMipmap->grInfo.format = GR_TEXFMT_P_8; + grMipmap->format = GL_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; size = W_LumpLength(flatlumpnum); @@ -653,10 +616,10 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) // the flat raw data needn't be converted with palettized textures W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum), - PU_HWRCACHE, &grMipmap->grInfo.data)); + PU_HWRCACHE, &grMipmap->data)); #ifdef GLENCORE - flat = grMipmap->grInfo.data; + flat = grMipmap->data; for (steppy = 0; steppy < size; steppy++) if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX) flat[steppy] = grMipmap->colormap[flat[steppy]]; @@ -678,7 +641,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) grmip->colormap += (256*32); #endif - if (!grmip->downloaded && !grmip->grInfo.data) + if (!grmip->downloaded && !grmip->data) HWR_CacheFlat(grmip, flatlumpnum); // If hardware does not have the texture, then call pfnSetTexture to upload it @@ -688,7 +651,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) HWR_SetCurrentTexture(grmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); } // @@ -697,7 +660,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) // static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) { - if (!grmip->downloaded && !grmip->grInfo.data) + if (!grmip->downloaded && !grmip->data) { patch_t *patch = gpatch->rawpatch; if (!patch) @@ -718,7 +681,7 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) HWR_SetCurrentTexture(grmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); } // -----------------+ @@ -726,11 +689,8 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { - /*if (needpatchflush) - W_FlushCachedPatches();*/ - // is it in hardware cache - if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data) + if (!gpatch->mipmap->downloaded && !gpatch->mipmap->data) { // load the software patch, PU_STATIC or the Z_Malloc for hardware patch will // flush the software patch before the conversion! oh yeah I suffered @@ -752,7 +712,7 @@ void HWR_GetPatch(GLPatch_t *gpatch) HWR_SetCurrentTexture(gpatch->mipmap); // The system-memory patch data can be purged now. - Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED); } @@ -802,7 +762,7 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch) if (!gpatch) return; - Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED); } @@ -834,7 +794,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 { INT32 i,j; fixed_t posx, posy, stepx, stepy; - UINT8 *block = mipmap->grInfo.data; // places the data directly into here, it already has the space allocated from HWR_ResizeBlock + UINT8 *block = mipmap->data; // places the data directly into here UINT8 *flat; UINT8 *dest, *src, texel; RGBA_t col; @@ -850,7 +810,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 for (j = 0; j < pblockheight; j++) { posx = 0; - dest = &block[j*blockwidth]; // 1bpp + dest = &block[j*(mipmap->width)]; // 1bpp src = &flat[(posy>>FRACBITS)*SHORT(fmwidth)]; for (i = 0; i < pblockwidth;i++) { @@ -874,7 +834,7 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) UINT16 fmheight = 0, fmwidth = 0; // setup the texture info - grMipmap->grInfo.format = GR_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later + grMipmap->format = GL_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later grMipmap->flags = 0; size = W_LumpLength(fademasklumpnum); @@ -904,15 +864,12 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) } // Thankfully, this will still work for this scenario - HWR_ResizeBlock(fmwidth, fmheight, &grMipmap->grInfo); - - grMipmap->width = blockwidth; - grMipmap->height = blockheight; + grMipmap->width = fmwidth; + grMipmap->height = fmheight; MakeBlock(grMipmap); - HWR_DrawFadeMaskInCache(grMipmap, blockwidth, blockheight, fademasklumpnum, fmwidth, fmheight); - + HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight); // I DO need to convert this because it isn't power of 2 and we need the alpha } @@ -923,13 +880,13 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; - if (!grmip->downloaded && !grmip->grInfo.data) + if (!grmip->downloaded && !grmip->data) HWR_CacheFadeMask(grmip, fademasklumpnum); HWD.pfnSetTexture(grmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); } // ================================================= @@ -979,8 +936,7 @@ void HWR_SetPalette(RGBA_t *palette) // hardware driver will flush there own cache if cache is non paletized // now flush data texture cache so 32 bit texture are recomputed - //if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) - if (patchformat == GR_RGBA || textureformat == GR_RGBA) + if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) { Z_FreeTag(PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE_UNLOCKED); @@ -1057,8 +1013,7 @@ void HWR_SetMapPalette(void) HWR_SetPaletteLookup(mapPalette); HWD.pfnSetTexturePalette(mapPalette); - //if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) - if (patchformat == GR_RGBA || textureformat == GR_RGBA) + if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) { Z_FreeTag(PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE_UNLOCKED); diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 415358a35..569548137 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -21,57 +21,26 @@ // TEXTURE INFO // ========================================================================== -// -// hw_glide.h -// - -typedef long GLAspectRatio_t; -#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ -#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ -#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ -#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ -#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ -#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ -#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ - -typedef long GLlod_t; -#define GR_LOD_LOG2_256 0x8 -#define GR_LOD_LOG2_128 0x7 -#define GR_LOD_LOG2_64 0x6 -#define GR_LOD_LOG2_32 0x5 -#define GR_LOD_LOG2_16 0x4 -#define GR_LOD_LOG2_8 0x3 -#define GR_LOD_LOG2_4 0x2 -#define GR_LOD_LOG2_2 0x1 -#define GR_LOD_LOG2_1 0x0 - -typedef long GLTextureFormat_t; -#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ -#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ -#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 -#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ -#define GR_TEXFMT_RGB_565 0xa -#define GR_TEXFMT_ARGB_1555 0xb -#define GR_TEXFMT_ARGB_4444 0xc -#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd -#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ -#define GR_RGBA 0x6 // 32 bit RGBA ! - -typedef struct +typedef enum GLTextureFormat_e { - GLlod_t smallLodLog2; - GLlod_t largeLodLog2; - GLAspectRatio_t aspectRatioLog2; - GLTextureFormat_t format; - void *data; -} GLTexInfo; + GL_TEXFMT_P_8 = 0x01, /* 8-bit palette */ + GL_TEXFMT_AP_88 = 0x02, /* 8-bit alpha, 8-bit palette */ -// grInfo.data holds the address of the graphics data cached in heap memory + GL_TEXFMT_RGBA = 0x10, /* 32 bit RGBA! */ + + GL_TEXFMT_ALPHA_8 = 0x20, /* (0..0xFF) alpha */ + GL_TEXFMT_INTENSITY_8 = 0x21, /* (0..0xFF) intensity */ + GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22, +} GLTextureFormat_t; + +// data holds the address of the graphics data cached in heap memory // NULL if the texture is not in Doom heap cache. struct GLMipmap_s { - GLTexInfo grInfo; - unsigned long flags; + GLTextureFormat_t format; + void *data; + + UINT32 flags; UINT16 width, height; UINT32 downloaded; // tex_downloaded @@ -84,13 +53,13 @@ typedef struct GLMipmap_s GLMipmap_t; // // Doom texture info, as cached for hardware rendering // -struct GLTexture_s +struct GLMapTexture_s { GLMipmap_t mipmap; float scaleX; //used for scaling textures on walls float scaleY; }; -typedef struct GLTexture_s GLTexture_t; +typedef struct GLMapTexture_s GLMapTexture_t; // a cached patch as converted to hardware format, holding the original patch_t // header so that the existing code can retrieve ->width, ->height as usual @@ -99,19 +68,19 @@ typedef struct GLTexture_s GLTexture_t; struct GLPatch_s { // the 4 first fields come right away from the original patch_t - INT16 width; - INT16 height; - INT16 leftoffset; // pixels to the left of origin - INT16 topoffset; // pixels below the origin + INT16 width; + INT16 height; + INT16 leftoffset; // pixels to the left of origin + INT16 topoffset; // pixels below the origin // - float max_s,max_t; - UINT16 wadnum; // the software patch lump num for when the hardware patch + float max_s,max_t; + UINT16 wadnum; // the software patch lump num for when the hardware patch UINT16 lumpnum; // was flushed, and we need to re-create it void *rawpatch; // :^) - GLMipmap_t *mipmap; - - boolean notfound; // if the texture file was not found, mark it here (used in model texture loading) -} ATTRPACK; + GLMipmap_t *mipmap; + + boolean notfound; // if the texture file was not found, mark it here (used in model texture loading) +}; typedef struct GLPatch_s GLPatch_t; #endif //_HWR_DATA_ diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 9e565a8aa..3617fa228 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -57,12 +57,13 @@ extern size_t addsubsector; // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); +void HWR_FreeMipmapCache(void); void HWR_FreeExtraSubsectors(void); void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap); // ^ some flats must NOT be remapped to encore, since we remap them as we cache them for ease, adding a toggle here seems wise. -GLTexture_t *HWR_GetTexture(INT32 tex); +GLMapTexture_t *HWR_GetTexture(INT32 tex); void HWR_GetPatch(GLPatch_t *gpatch); void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); @@ -80,8 +81,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); // -------- // hw_draw.c // -------- -extern consvar_t cv_grrounddown; // on/off - extern INT32 patchformat; extern INT32 textureformat; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2265928d5..6849ef1de 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -85,8 +85,6 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; -consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, grfiltermode_cons_t, CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL}; @@ -1458,7 +1456,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom fixed_t v1x, v1y, v2x, v2y; #endif - GLTexture_t *grTex = NULL; + GLMapTexture_t *grTex = NULL; float cliplow = 0.0f, cliphigh = 0.0f; INT32 gr_midtexture; fixed_t h, l; // 3D sides and 2s middle textures @@ -6346,7 +6344,7 @@ void HWR_TogglePaletteRendering(void) // The textures will still be converted to RGBA by r_opengl. // This however makes hw_cache use paletted blending for composite textures! // (patchformat is not touched) - textureformat = GR_TEXFMT_P_8; + textureformat = GL_TEXFMT_P_8; HWR_SetMapPalette(); HWR_SetPalette(pLocalPalette); @@ -6363,7 +6361,7 @@ void HWR_TogglePaletteRendering(void) if (gr_palette_rendering_state) { gr_palette_rendering_state = false; - textureformat = GR_RGBA; + textureformat = GL_TEXFMT_RGBA; HWR_SetPalette(pLocalPalette); // If the r_opengl "texture palette" stays the same during this switch, these textures // will not be cleared out. However they are still out of date since the @@ -6376,7 +6374,6 @@ void HWR_TogglePaletteRendering(void) //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_granisotropicmode); CV_RegisterVar(&cv_grcorrecttricks); @@ -6430,7 +6427,7 @@ void HWR_Startup(void) if (!startupdone) { CONS_Printf("HWR_Startup()...\n"); - textureformat = patchformat = GR_RGBA; + textureformat = patchformat = GL_TEXFMT_RGBA; HWR_InitTextureCache(); HWR_InitMD2(); @@ -6459,6 +6456,7 @@ void HWR_Shutdown(void) { CONS_Printf("HWR_Shutdown()\n"); HWR_FreeExtraSubsectors(); + HWR_FreeMipmapCache(); HWR_FreeTextureCache(); HWD.pfnFlushScreenTextures(); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 0d63732e3..f52afd50e 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -160,7 +160,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum); extern boolean gr_maphasportals; // hw_cache.c -void HWR_PrepLevelCache(size_t pnumtextures); +void HWR_LoadTextures(size_t pnumtextures); RGBA_t *HWR_GetTexturePalette(void); // hw_trick.c diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index c64d77639..c017fdbd2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -202,7 +202,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); fclose(png_FILE); - Z_Free(grpatch->mipmap->grInfo.data); + Z_Free(grpatch->mipmap->data); return 0; } #ifdef USE_FAR_KEYWORD @@ -243,7 +243,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ { png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); - png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); + png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->data); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); for (i = 0; i < height; i++) row_pointers[i] = PNG_image + i*pitch; @@ -256,7 +256,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ fclose(png_FILE); *w = (int)width; *h = (int)height; - return GR_RGBA; + return GL_TEXFMT_RGBA; } #endif @@ -323,7 +323,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, pw = *w = header.xmax - header.xmin + 1; ph = *h = header.ymax - header.ymin + 1; - image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); + image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->data); if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) { @@ -357,7 +357,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, } } fclose(file); - return GR_RGBA; + return GL_TEXFMT_RGBA; } // -----------------+ @@ -371,7 +371,7 @@ static void md2_loadTexture(md2_t *model) if (model->grpatch) { grpatch = model->grpatch; - Z_Free(grpatch->mipmap->grInfo.data); + Z_Free(grpatch->mipmap->data); } else { @@ -380,15 +380,15 @@ static void md2_loadTexture(md2_t *model) grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); } - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) + if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->grInfo.format == 0) + grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->format == 0) #endif - grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->grInfo.format == 0) + grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->format == 0) { grpatch->notfound = true;// mark it so its not searched for again repeatedly return; @@ -401,11 +401,6 @@ static void md2_loadTexture(md2_t *model) grpatch->height = (INT16)h; grpatch->mipmap->width = (UINT16)w; grpatch->mipmap->height = (UINT16)h; - - // not correct! - grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; } HWD.pfnSetTexture(grpatch->mipmap); HWR_UnlockCachedPatch(grpatch); @@ -425,7 +420,7 @@ static void md2_loadBlendTexture(md2_t *model) if (model->blendgrpatch) { grpatch = model->blendgrpatch; - Z_Free(grpatch->mipmap->grInfo.data); + Z_Free(grpatch->mipmap->data); } else { @@ -434,15 +429,15 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); } - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) + if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->grInfo.format == 0) + grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->format == 0) #endif - grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->grInfo.format == 0) + grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->format == 0) { grpatch->notfound = true;// mark it so its not searched for again repeatedly Z_Free(filename); @@ -456,11 +451,6 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->height = (INT16)h; grpatch->mipmap->width = (UINT16)w; grpatch->mipmap->height = (UINT16)h; - - // not correct! - grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; } HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary HWR_UnlockCachedPatch(grpatch); @@ -697,20 +687,20 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // no wrap around, no chroma key grmip->flags = 0; // setup the texture info - grmip->grInfo.format = GR_RGBA; + grmip->format = GL_TEXFMT_RGBA; } - if (grmip->grInfo.data) + if (grmip->data) { - Z_Free(grmip->grInfo.data); - grmip->grInfo.data = NULL; + Z_Free(grmip->data); + grmip->data = NULL; } - cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); + cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->data); memset(cur, 0x00, size*4); - image = gpatch->mipmap->grInfo.data; - blendimage = blendgpatch->mipmap->grInfo.data; + image = gpatch->mipmap->data; + blendimage = blendgpatch->mipmap->data; // TC_METALSONIC includes an actual skincolor translation, on top of its flashing. if (skinnum == TC_METALSONIC) @@ -1053,10 +1043,10 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT grmip = grmip->nextcolormap; if (grmip->colormap == colormap) { - if (grmip->downloaded && grmip->grInfo.data) + if (grmip->downloaded && grmip->data) { HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture - Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); return; } } @@ -1078,7 +1068,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); HWD.pfnSetTexture(newmip); - Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(newmip->data, PU_HWRCACHE_UNLOCKED); } @@ -1238,20 +1228,20 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; - if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !gpatch->notfound)) + if (!gpatch || ((!gpatch->mipmap->format || !gpatch->mipmap->downloaded) && !gpatch->notfound)) md2_loadTexture(md2); gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... - if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available + if ((gpatch && gpatch->mipmap->format) // don't load the blend texture if the base texture isn't available && (!md2->blendgrpatch - || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) + || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) && !((GLPatch_t *)md2->blendgrpatch)->notfound))) md2_loadBlendTexture(md2); - if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture + if (gpatch && gpatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && - md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format + md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { INT32 skinnum = TC_DEFAULT; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 59a119ee5..f137a7cc8 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -81,6 +81,9 @@ static FBITFIELD CurrentPolyFlags; static FTextureInfo *gr_cachetail = NULL; static FTextureInfo *gr_cachehead = NULL; +static RGBA_t *textureBuffer = NULL; +static size_t textureBufferSize = 0; + // Linked list of all lighttables. static LTListItem *LightTablesTail = NULL; static LTListItem *LightTablesHead = NULL; @@ -1013,6 +1016,10 @@ void Flush(void) gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL tex_downloaded = 0; + + free(textureBuffer); + textureBuffer = NULL; + textureBufferSize = 0; } @@ -1353,42 +1360,48 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) CurrentPolyFlags = PolyFlags; } +static void AllocTextureBuffer(GLMipmap_t *pTexInfo) +{ + size_t size = pTexInfo->width * pTexInfo->height; + if (size > textureBufferSize) + { + textureBuffer = realloc(textureBuffer, size * sizeof(RGBA_t)); + if (textureBuffer == NULL) + I_Error("AllocTextureBuffer: out of memory allocating %s bytes", sizeu1(size * sizeof(RGBA_t))); + textureBufferSize = size; + } +} // -----------------+ -// UpdateTexture : Updates the texture data. +// UpdateTexture : Updates texture data. // -----------------+ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) { - // Download a mipmap - boolean updatemipmap = true; - static RGBA_t tex[2048*2048]; - const GLvoid *ptex = tex; - INT32 w, h; - GLuint texnum = 0; + // Upload a texture + GLuint num = pTexInfo->downloaded; + boolean update = true; + + INT32 w = pTexInfo->width, h = pTexInfo->height; + INT32 i, j; + + const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; + const GLvoid *ptex = NULL; + RGBA_t *tex = NULL; - - if (!pTexInfo->downloaded) + // Generate a new texture name. + if (!num) { - pglGenTextures(1, &texnum); - pTexInfo->downloaded = texnum; - updatemipmap = false; + pglGenTextures(1, &num); + pTexInfo->downloaded = num; + update = false; } - else - texnum = pTexInfo->downloaded; - //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data); + //GL_DBG_Printf("UpdateTexture %d %x\n", (INT32)num, pImgData); - w = pTexInfo->width; - h = pTexInfo->height; - - if (w*h > 2048*2048 && pTexInfo->grInfo.format != GL_RGBA) - I_Error("Tried to convert too big texture: %dx%d", w, h); - - if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || - (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) + if ((pTexInfo->format == GL_TEXFMT_P_8) || (pTexInfo->format == GL_TEXFMT_AP_88)) { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1413,7 +1426,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) pImgData++; - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) + if (pTexInfo->format == GL_TEXFMT_AP_88) { if (!(pTexInfo->flags & TF_CHROMAKEYED)) tex[w*j+i].s.alpha = *pImgData; @@ -1423,16 +1436,15 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } } } - else if (pTexInfo->grInfo.format == GR_RGBA) + else if (pTexInfo->format == GL_TEXFMT_RGBA) { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - ptex = pTexInfo->grInfo.data; + // Directly upload the texture data without any kind of conversion. + ptex = pImgData; } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) + else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1447,10 +1459,10 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } } } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks + else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1465,12 +1477,10 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } } else - GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); + GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format); - - // the texture number was already generated by pglGenTextures - pglBindTexture(GL_TEXTURE_2D, texnum); - tex_downloaded = texnum; + pglBindTexture(GL_TEXTURE_2D, num); + tex_downloaded = num; // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues if (pTexInfo->flags & TF_TRANSPARENT) @@ -1484,7 +1494,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } - if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) + if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) @@ -1510,13 +1520,13 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); } } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) + else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) @@ -1542,7 +1552,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1573,7 +1583,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -2836,14 +2846,10 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) // I don't know which one the game actually _uses_ but this // follows format2bpp in hw_cache.c int bpp = 1; - int format = tmp->grInfo.format; - if (format == GR_RGBA) + int format = tmp->format; + if (format == GL_TEXFMT_RGBA) bpp = 4; - else if (format == GR_TEXFMT_RGB_565 - || format == GR_TEXFMT_ARGB_1555 - || format == GR_TEXFMT_ARGB_4444 - || format == GR_TEXFMT_ALPHA_INTENSITY_88 - || format == GR_TEXFMT_AP_88) + else if (format == GL_TEXFMT_ALPHA_INTENSITY_88 || format == GL_TEXFMT_AP_88) bpp = 2; // Add it up! diff --git a/src/p_setup.c b/src/p_setup.c index 0ad4844b9..a81ae3226 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3145,16 +3145,8 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { - // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); - - if (HWR_ShouldUsePaletteRendering()) //unsure if this is the right place, but seems to work since we dont have HWR_LoadLevel like srb2 - HWR_SetMapPalette(); - } - + if (rendermode == render_opengl) + HWR_LoadLevel(); #endif // oh god I hope this helps @@ -3361,14 +3353,6 @@ boolean P_SetupLevel(boolean skipprecip) // clear special respawning que iquehead = iquetail = 0; - // preload graphics -#ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { - HWR_PrepLevelCache(numtextures); - } -#endif - P_MapEnd(); // Remove the loading shit from the screen @@ -3426,6 +3410,19 @@ boolean P_SetupLevel(boolean skipprecip) return true; } +#ifdef HWRENDER +void HWR_LoadLevel(void) +{ + HWR_FreeMipmapCache(); + // Correct missing sidedefs & deep water trick + HWR_CorrectSWTricks(); + HWR_CreatePlanePolygons((INT32)numnodes - 1); + + if (HWR_ShouldUsePaletteRendering()) + HWR_SetMapPalette(); +} +#endif + // // P_RunSOC // diff --git a/src/p_setup.h b/src/p_setup.h index 728549943..42c8cb773 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -60,6 +60,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); +#ifdef HWRENDER +void HWR_LoadLevel(void); +#endif boolean P_AddWadFile(const char *wadfilename, boolean local); boolean P_AddWadFileLocal(const char *wadfilename); #ifdef DELFILE diff --git a/src/r_data.c b/src/r_data.c index 7c6697298..772d76925 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -533,6 +533,11 @@ void R_LoadTextures(void) i++; } } + +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_LoadTextures(numtextures); +#endif } static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) diff --git a/src/w_wad.c b/src/w_wad.c index 76c622999..44bb71ee9 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1736,11 +1736,11 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) grPatch = HWR_GetCachedGLPatchPwad(wad, lump); - if (grPatch->mipmap->grInfo.data) + if (grPatch->mipmap->data) { if (tag == PU_CACHE) tag = PU_HWRCACHE; - Z_ChangeTag(grPatch->mipmap->grInfo.data, tag); + Z_ChangeTag(grPatch->mipmap->data, tag); } else {