📄 hw_cache.c
字号:
{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} }; int j,k; int max,min; // find a power of 2 width/height if (cv_grrounddown.value) { blockwidth = 256; while (originalwidth < blockwidth) blockwidth >>= 1; if (blockwidth<1) I_Error ("3D GenerateTexture : too small"); blockheight = 256; while (originalheight < blockheight) blockheight >>= 1; if (blockheight<1) I_Error ("3D GenerateTexture : too small"); } else { //size up to nearest power of 2 blockwidth = 1; while (blockwidth < originalwidth) blockwidth <<= 1; // scale down the original graphics to fit in 256 if (blockwidth>256) blockwidth = 256; //I_Error ("3D GenerateTexture : too big"); //size up to nearest power of 2 blockheight = 1; while (blockheight < originalheight) blockheight <<= 1; // scale down the original graphics to fit in 256 if (blockheight>256) blockheight = 255; //I_Error ("3D GenerateTexture : too big"); } // do the boring LOD stuff.. blech! if (blockwidth >= blockheight) { max = blockwidth; min = blockheight; }else{ max = blockheight; min = blockwidth; } for (k=256, j=0; k > max; 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_Printf ("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;}static const int 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 byte *MakeBlock( GlideMipmap_t *grMipmap ){ int bpp = format2bpp[grMipmap->grInfo.format]; byte *block; int i; block = Z_Malloc (blocksize*bpp, PU_STATIC, &(grMipmap->grInfo.data)); switch (bpp) { case 1: memset(block, HWR_PATCHES_CHROMAKEY_COLORINDEX, blocksize ); break; case 2: // fill background with chromakey, alpha=0 for( i=0; i<blocksize; i++ ) *((unsigned short*)block+i) = SHORT((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); break; case 4: memset(block,0,blocksize*4); break; } return block;}//// 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 (int texnum, GlideTexture_t* grtex){ byte* block; texture_t* texture; texpatch_t* patch; patch_t* realpatch; int i; boolean skyspecial = false; //poor hack for Legacy large skies.. texture = textures[texnum]; // hack the Legacy skies.. texture size is 256x128 but patch size is larger.. if ( texture->name[0] == 'S' && texture->name[1] == 'K' && texture->name[2] == 'Y' && texture->name[4] == 0 ) { skyspecial = true; grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky } else grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; HWR_ResizeBlock (texture->width, texture->height, &grtex->mipmap.grInfo); grtex->mipmap.width = blockwidth; grtex->mipmap.height = blockheight; grtex->mipmap.grInfo.format = textureformat; block = MakeBlock( &grtex->mipmap ); // Composite the columns together. for (i=0 , patch = texture->patches; i<texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNum (patch->patch, PU_CACHE); // correct texture size for Legacy's large skies if (skyspecial) { //CONS_Printf("sky %d, %d\n",texture->width,SHORT(realpatch->width)); //texture->width = SHORT(realpatch->width); texture->height = SHORT(realpatch->height); } HWR_DrawPatchInCache( &grtex->mipmap, blockwidth, blockheight, blockwidth*format2bpp[grtex->mipmap.grInfo.format], texture->width, texture->height, patch->originx, patch->originy, realpatch, format2bpp[grtex->mipmap.grInfo.format]); } // make it purgable from zone memory // use PU_PURGELEVEL so we can Z_FreeTags all at once Z_ChangeTag (block, PU_HWRCACHE); grtex->scaleX = crapmul / (float)texture->width; grtex->scaleY = crapmul / (float)texture->height;}// grTex : Hardware texture cache info// .data : address of converted patch in heap memory// user for Z_Malloc(), becomes NULL if it is purged from the cachevoid HWR_MakePatch (patch_t* patch, GlidePatch_t* grPatch, GlideMipmap_t *grMipmap){ byte* block; int newwidth,newheight; // don't do it twice (like a cache) if(grMipmap->width==0) { // save the original patch header so that the GlidePatch can be casted // into a standard patch_t struct and the existing code can get the // orginal patch dimensions and offsets. grPatch->width = SHORT(patch->width); grPatch->height = SHORT(patch->height); grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->topoffset = SHORT(patch->topoffset); // find the good 3dfx size (boring spec) HWR_ResizeBlock (SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); grMipmap->width = blockwidth; grMipmap->height = blockheight; // 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; } if( grMipmap->grInfo.data != NULL ) Z_Free(grMipmap->grInfo.data); block = MakeBlock(grMipmap); // if rounddown, rounddown patches as well as textures if (cv_grrounddown.value) { newwidth = blockwidth; newheight = blockheight; } else { // no rounddown, do not size up patches, so they don't look 'scaled' newwidth = min( SHORT(patch->width) , blockwidth ); newheight = min( SHORT(patch->height), blockheight); } HWR_DrawPatchInCache( grMipmap, newwidth, newheight, blockwidth*format2bpp[grMipmap->grInfo.format], SHORT(patch->width), SHORT(patch->height), 0, 0, patch, format2bpp[grMipmap->grInfo.format] ); grPatch->max_s = (float)newwidth / (float)blockwidth; grPatch->max_t = (float)newheight / (float)blockheight; // Now that the texture has been built in cache, it is purgable from zone memory. Z_ChangeTag (block, PU_HWRCACHE);}// =================================================// CACHING HANDLING// =================================================static int gr_numtextures;static GlideTexture_t* gr_textures; // for ALL Doom texturesvoid HWR_InitTextureCache (void){ gr_numtextures = 0; gr_textures = NULL;}void HWR_FreeTextureCache (void){ int i,j; // free references to the textures HWD.pfnClearMipMapCache (); // free all skin after each level: must be done after pfnClearMipMapCache! for (j=0; j<numwadfiles; j++) for (i=0; i<wadfiles[j]->numlumps; i++) { GlidePatch_t *grpatch = &(wadfiles[j]->hwrcache[i]); while (grpatch->mipmap.nextcolormap) { GlideMipmap_t *grmip = grpatch->mipmap.nextcolormap; grpatch->mipmap.nextcolormap = grmip->nextcolormap; free(grmip); } } // free all hardware-converted graphics cached in the heap // our gool is only the textures since user of the texture is the texture cache Z_FreeTags (PU_HWRCACHE, PU_HWRCACHE); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) free (gr_textures);}void HWR_PrepLevelCache (int numtextures){ // 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 = numtextures; gr_textures = malloc (sizeof(GlideTexture_t) * numtextures); if (!gr_textures) I_Error ("3D can't alloc gr_textures"); memset (gr_textures, 0, sizeof(GlideTexture_t) * numtextures);}void HWR_SetPalette( RGBA_t *palette ){ //Hudler: 16/10/99: added for OpenGL gamma correction RGBA_t gamma_correction = {0x7F7F7F7F};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -