/* ================= Mod_LoadSpriteFrame ================= */ void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) { dspriteframe_t *pinframe; mspriteframe_t *pspriteframe; int i, width, height, size, origin[2]; unsigned short *ppixout; byte *ppixin; char name[64]; pinframe = (dspriteframe_t *)pin; width = LittleLong (pinframe->width); height = LittleLong (pinframe->height); size = width * height; pspriteframe = (mspriteframe_t*) Hunk_AllocName (sizeof (mspriteframe_t),loadname); Q_memset (pspriteframe, 0, sizeof (mspriteframe_t)); *ppframe = pspriteframe; pspriteframe->width = width; pspriteframe->height = height; origin[0] = LittleLong (pinframe->origin[0]); origin[1] = LittleLong (pinframe->origin[1]); pspriteframe->up = origin[1]; pspriteframe->down = origin[1] - height; pspriteframe->left = origin[0]; pspriteframe->right = width + origin[0]; sprintf (name, "%s_%i", loadmodel->name, framenum); pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true); return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); }
// ================= // R_Bloom_InitEffectTexture // ================= void R_Bloom_InitEffectTexture (void) { unsigned char *data; float bloomsizecheck; if (r_bloom_sample_size.value < 32) Cvar_SetValue (&r_bloom_sample_size, 32); // Make sure bloom size is a power of 2. BLOOM_SIZE = r_bloom_sample_size.value; bloomsizecheck = (float) BLOOM_SIZE; while (bloomsizecheck > 1.0f) bloomsizecheck /= 2.0f; if (bloomsizecheck != 1.0f) { BLOOM_SIZE = 32; while (BLOOM_SIZE < r_bloom_sample_size.value) BLOOM_SIZE *= 2; } // Make sure bloom size doesn't have stupid values. if (BLOOM_SIZE > screen_texture_width || BLOOM_SIZE > screen_texture_height) BLOOM_SIZE = min( screen_texture_width, screen_texture_height ); if (BLOOM_SIZE != r_bloom_sample_size.value) Cvar_SetValue (&r_bloom_sample_size, BLOOM_SIZE); data = (unsigned char *) Q_calloc (BLOOM_SIZE * BLOOM_SIZE, sizeof (int)); r_bloomeffecttexture = GL_LoadTexture ("***r_bloomeffecttexture***", BLOOM_SIZE, BLOOM_SIZE, data, 0, 4); Q_free (data); }
/* ================= Mod_LoadTextures ================= */ void Mod_LoadTextures (lump_t *l) { int i, j, pixels, num, max, altmax; miptex_t *mt; texture_t *tx, *tx2; texture_t *anims[10]; texture_t *altanims[10]; dmiptexlump_t *m; if (!l->filelen) { loadmodel->textures = NULL; return; } m = (dmiptexlump_t *)(mod_base + l->fileofs); m->nummiptex = LittleLong (m->nummiptex); loadmodel->numtextures = m->nummiptex; loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); for (i=0 ; i<m->nummiptex ; i++) { m->dataofs[i] = LittleLong(m->dataofs[i]); if (m->dataofs[i] == -1) continue; mt = (miptex_t *)((byte *)m + m->dataofs[i]); mt->width = LittleLong (mt->width); mt->height = LittleLong (mt->height); for (j=0 ; j<MIPLEVELS ; j++) mt->offsets[j] = LittleLong (mt->offsets[j]); if ( (mt->width & 15) || (mt->height & 15) ) Sys_Error ("Texture %s is not 16 aligned", mt->name); pixels = mt->width*mt->height/64*85; tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); loadmodel->textures[i] = tx; memcpy (tx->name, mt->name, sizeof(tx->name)); tx->width = mt->width; tx->height = mt->height; for (j=0 ; j<MIPLEVELS ; j++) tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); // the pixels immediately follow the structures memcpy ( tx+1, mt+1, pixels); if (!Q_strncmp(mt->name,"sky",3)) R_InitSky (tx); else { texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false); texture_mode = GL_LINEAR; } } // // sequence the animations // for (i=0 ; i<m->nummiptex ; i++) { tx = loadmodel->textures[i]; if (!tx || tx->name[0] != '+') continue; if (tx->anim_next) continue; // allready sequenced // find the number of frames in the animation memset (anims, 0, sizeof(anims)); memset (altanims, 0, sizeof(altanims)); max = tx->name[1]; altmax = 0; if (max >= 'a' && max <= 'z') max -= 'a' - 'A'; if (max >= '0' && max <= '9') { max -= '0'; altmax = 0; anims[max] = tx; max++; } else if (max >= 'A' && max <= 'J') { altmax = max - 'A'; max = 0; altanims[altmax] = tx; altmax++; } else Sys_Error ("Bad animating texture %s", tx->name); for (j=i+1 ; j<m->nummiptex ; j++) { tx2 = loadmodel->textures[j]; if (!tx2 || tx2->name[0] != '+') continue; if (strcmp (tx2->name+2, tx->name+2)) continue; num = tx2->name[1]; if (num >= 'a' && num <= 'z') num -= 'a' - 'A'; if (num >= '0' && num <= '9') { num -= '0'; anims[num] = tx2; if (num+1 > max) max = num + 1; } else if (num >= 'A' && num <= 'J') { num = num - 'A'; altanims[num] = tx2; if (num+1 > altmax) altmax = num+1; } else Sys_Error ("Bad animating texture %s", tx->name); } #define ANIM_CYCLE 2 // link them all together for (j=0 ; j<max ; j++) { tx2 = anims[j]; if (!tx2) Sys_Error ("Missing frame %i of %s",j, tx->name); tx2->anim_total = max * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = anims[ (j+1)%max ]; if (altmax) tx2->alternate_anims = altanims[0]; } for (j=0 ; j<altmax ; j++) { tx2 = altanims[j]; if (!tx2) Sys_Error ("Missing frame %i of %s",j, tx->name); tx2->anim_total = altmax * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = altanims[ (j+1)%altmax ]; if (max) tx2->alternate_anims = anims[0]; } } }
/* =============== Mod_LoadAllSkins =============== */ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) { int i, j, k; char name[32]; int s; byte *copy; byte *skin; byte *texels; daliasskingroup_t *pinskingroup; int groupskins; daliasskininterval_t *pinskinintervals; skin = (byte *)(pskintype + 1); if (numskins < 1 || numskins > MAX_SKINS) Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); s = pheader->skinwidth * pheader->skinheight; for (i=0 ; i<numskins ; i++) { if (pskintype->type == ALIAS_SKIN_SINGLE) { Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); // save 8 bit texels for the player model to remap // if (!strcmp(loadmodel->name,"progs/player.mdl")) { texels = Hunk_AllocName(s, loadname); pheader->texels[i] = texels - (byte *)pheader; memcpy (texels, (byte *)(pskintype + 1), s); // } sprintf (name, "%s_%i", loadmodel->name, i); pheader->gl_texturenum[i][0] = pheader->gl_texturenum[i][1] = pheader->gl_texturenum[i][2] = pheader->gl_texturenum[i][3] = GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype + 1), true, false); pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); } else { // animating skin group. yuck. pskintype++; pinskingroup = (daliasskingroup_t *)pskintype; groupskins = LittleLong (pinskingroup->numskins); pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); pskintype = (void *)(pinskinintervals + groupskins); for (j=0 ; j<groupskins ; j++) { Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); if (j == 0) { texels = Hunk_AllocName(s, loadname); pheader->texels[i] = texels - (byte *)pheader; memcpy (texels, (byte *)(pskintype), s); } sprintf (name, "%s_%i_%i", loadmodel->name, i,j); pheader->gl_texturenum[i][j&3] = GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype), true, false); pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); } k = j; for (/* */; j < 4; j++) pheader->gl_texturenum[i][j&3] = pheader->gl_texturenum[i][j - k]; } } return (void *)pskintype; }
static int GL_LoadTextureNoFilter( const char *name, const byte *buf, size_t size, int flags ) { return GL_LoadTexture( name, buf, size, flags, NULL ); }
void R_Bloom_InitTextures( void ) { unsigned char *data; int maxtexsize, glinternalfmt; size_t size; // Find closer power of 2 to screen size. for (screen_texture_width = 1; screen_texture_width < glwidth; screen_texture_width *= 2); for (screen_texture_height = 1; screen_texture_height < glheight; screen_texture_height *= 2); // Disable blooms if we can't handle a texture of that size. glGetIntegerv (GL_MAX_TEXTURE_SIZE, &maxtexsize); if (screen_texture_width > maxtexsize || screen_texture_height > maxtexsize) { screen_texture_width = screen_texture_height = 0; Cvar_SetValue (&r_bloom, 0); Com_Printf ("WARNING: 'R_InitBloomScreenTexture' too high resolution for Light Bloom. Effect disabled\n"); return; } // Init the screen texture. size = screen_texture_width * screen_texture_height * sizeof (int); data = Q_malloc (size); memset (data, 255, size); //r_bloomscreentexture = GL_LoadTexture ( "***r_screenbackuptexture***", screen_texture_width, screen_texture_height, data, 0, 4); // false, false, 4); if (!r_bloomscreentexture) r_bloomscreentexture = texture_extension_number++; if(gl_gammacorrection.integer) { glinternalfmt = GL_SRGB8; } else { glinternalfmt = gl_solid_format; } GL_Bind (r_bloomscreentexture); glTexImage2D (GL_TEXTURE_2D, 0, glinternalfmt, screen_texture_width, screen_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); Q_free (data); // Validate bloom size and init the bloom effect texture. R_Bloom_InitEffectTexture(); // If screensize is more than 2x the bloom effect texture, set up for stepped downsampling. r_bloomdownsamplingtexture = 0; r_screendownsamplingtexture_size = 0; if( glwidth > (BLOOM_SIZE * 2) && !r_bloom_fast_sample.value ) { r_screendownsamplingtexture_size = (int)(BLOOM_SIZE * 2); data = Q_calloc (r_screendownsamplingtexture_size * r_screendownsamplingtexture_size, sizeof (int)); r_bloomdownsamplingtexture = GL_LoadTexture ( "***r_bloomdownsamplingtexture***", r_screendownsamplingtexture_size, r_screendownsamplingtexture_size, data, 0, 4); Q_free (data); } // Init the screen backup texture. if (r_screendownsamplingtexture_size) R_Bloom_InitBackUpTexture (r_screendownsamplingtexture_size, r_screendownsamplingtexture_size); else R_Bloom_InitBackUpTexture (BLOOM_SIZE, BLOOM_SIZE); }
void R_ParseDetailTextures( const char *filename ) { char *afile, *pfile; string token, texname, detail_texname; float xScale, yScale; texture_t *tex; int i; if( r_detailtextures->integer >= 2 && !FS_FileExists( filename, false )) { // use built-in generator for detail textures R_CreateDetailTexturesList( filename ); } afile = FS_LoadFile( filename, NULL, false ); if( !afile ) return; pfile = afile; // format: 'texturename' 'detailtexture' 'xScale' 'yScale' while(( pfile = COM_ParseFile( pfile, token )) != NULL ) { texname[0] = '\0'; // read texname if( token[0] == '{' ) { // NOTE: COM_ParseFile handled some symbols seperately // this code will be fix it pfile = COM_ParseFile( pfile, token ); Q_strncat( texname, "{", sizeof( texname )); Q_strncat( texname, token, sizeof( texname )); } else Q_strncpy( texname, token, sizeof( texname )); // read detailtexture name pfile = COM_ParseFile( pfile, token ); Q_snprintf( detail_texname, sizeof( detail_texname ), "gfx/%s.tga", token ); // read scales pfile = COM_ParseFile( pfile, token ); xScale = Q_atof( token ); pfile = COM_ParseFile( pfile, token ); yScale = Q_atof( token ); if( xScale <= 0.0f || yScale <= 0.0f ) continue; // search for existing texture and uploading detail texture for( i = 0; i < cl.worldmodel->numtextures; i++ ) { tex = cl.worldmodel->textures[i]; if( Q_stricmp( tex->name, texname )) continue; tex->dt_texturenum = GL_LoadTexture( detail_texname, NULL, 0, TF_FORCE_COLOR ); // texture is loaded if( tex->dt_texturenum ) { gltexture_t *glt; GL_SetTextureType( tex->dt_texturenum, TEX_DETAIL ); glt = R_GetTexture( tex->gl_texturenum ); glt->xscale = xScale; glt->yscale = yScale; } break; } } Mem_Free( afile ); }
/* ================= Mod_LoadTextures ================= */ void Mod_LoadTextures (lump_t *l) { // 1999-12-28 OpenGL fullbright fix by Neal White III start // Neal White III - 12-28-1999 - OpenGL fullbright bugfix // [email protected] // http://home.telefragged.com/wally/ // // Problem: // // There was a problem in the original glquake with fullbright texels. // In the software renderer, fullbrights glow brightly in the dark. // Essentially, the fullbrights were ignored. I've fixed it by // adding another rendering pass and creating a new glowmap texture. // // Fix: // // When a texture with fullbright (FB) texels is loaded, a copy is made, // then the FB pixels are cleared to black in the original texture. In // the copy, all normal colors are cleared and only the FBs remain. When // it comes time to render the polygons, I do an additional pass and ADD // the glowmap on top of the current polygon. byte *ptexel; qboolean hasfullbrights; // qboolean noglow = COM_CheckParm("-noglow"); // int i, j, pixels, num, max, altmax; int i, num, max, altmax; unsigned long j, pixels; // 1999-12-28 OpenGL fullbright fix by Neal White III end miptex_t *mt; texture_t *tx, *tx2; texture_t *anims[10]; texture_t *altanims[10]; dmiptexlump_t *m; if (!l->filelen) { loadmodel->textures = NULL; return; } m = (dmiptexlump_t *)(mod_base + l->fileofs); m->nummiptex = LittleLong (m->nummiptex); loadmodel->numtextures = m->nummiptex; loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); for (i=0 ; i<m->nummiptex ; i++) { m->dataofs[i] = LittleLong(m->dataofs[i]); if (m->dataofs[i] == -1) continue; mt = (miptex_t *)((byte *)m + m->dataofs[i]); mt->width = LittleLong (mt->width); mt->height = LittleLong (mt->height); for (j=0 ; j<MIPLEVELS ; j++) mt->offsets[j] = LittleLong (mt->offsets[j]); if ( (mt->width & 15) || (mt->height & 15) ) Sys_Error ("Texture %s is not 16 aligned", mt->name); pixels = mt->width*mt->height/64*85; // 1999-12-28 OpenGL fullbright fix by Neal White III start hasfullbrights = false; if ((!strncmp(mt->name,"sky",3)) || (!strncmp(mt->name,"*",1)) || // turbulent (liquid) (!gl_glowmap->value) || (! gl_mtexable) ) { // sky has no lightmap, nor do liquids (so never needs a glowmap), // -noglow command line parameter, or no multi-texture support // // hasfullbrights is already false } else // check this texture for fullbright texels { ptexel = (byte *)(mt+1); for (j=0 ; j<pixels ; j++) { if (ptexel[j] >= 256-32) // 32 fullbright colors { hasfullbrights = true; break; } } } if (hasfullbrights) { tx = Hunk_AllocName (sizeof(texture_t) +pixels*2, loadname ); } else { // 1999-12-28 OpenGL fullbright fix by Neal White III end tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); } // 1999-12-28 OpenGL fullbright fix by Neal White III loadmodel->textures[i] = tx; memcpy (tx->name, mt->name, sizeof(tx->name)); tx->width = mt->width; tx->height = mt->height; for (j=0 ; j<MIPLEVELS ; j++) { // 1999-12-28 OpenGL fullbright fix by Neal White III tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); // 1999-12-28 OpenGL fullbright fix by Neal White III start if (hasfullbrights) { tx->glowoffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t) + pixels; } else { tx->glowoffsets[j] = 0; } } // 1999-12-28 OpenGL fullbright fix by Neal White III end // the pixels immediately follow the structures memcpy ( tx+1, mt+1, pixels); // 1999-12-28 OpenGL fullbright fix by Neal White III start if (hasfullbrights) { ptexel = (byte *)(tx+1); memcpy ( ptexel+pixels, mt+1, pixels); } tx->flags = 0; // 1999-12-28 OpenGL fullbright fix by Neal White III end if (!strncmp(mt->name,"sky",3)) // 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline start { if (cls.state != ca_dedicated) { // 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline end R_InitSky (tx); // 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline start } } // 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline end else { texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; // 1999-12-28 OpenGL fullbright fix by Neal White III start // remove glowing fullbright colors from base texture (make black) if (hasfullbrights) { #ifdef _DEBUG qboolean bColorUsed[256]; Con_DPrintf ("*** Fullbright Texture: \"%s\", %dx%d, %d pixels\n", mt->name, mt->width, mt->height, pixels); for (j=0 ; j<256 ; j++) bColorUsed[j] = false; #endif ptexel = (byte *)(tx+1); for (j=0 ; j<pixels ; j++) { #ifdef _DEBUG bColorUsed[ptexel[j]] = true; #endif if (ptexel[j] >= 256-32) // 32 fullbright colors { ptexel[j] = 0; // make fullbrights black } } #ifdef _DEBUG Con_DPrintf ("*** Normal colors: "); for (j=0 ; j<256-32 ; j++) { if (bColorUsed[j]) Con_DPrintf ("%d ", j); } Con_DPrintf ("\n"); Con_DPrintf ("*** Fullbrights: "); for (j=256-32 ; j<256 ; j++) { if (bColorUsed[j]) Con_DPrintf ("%d ", j); } Con_DPrintf ("\n"); #endif } #ifdef _DEBUG else { Con_DPrintf ("*** Normal Texture: \"%s\", %dx%d\n", mt->name, mt->width, mt->height); } #endif // 1999-12-28 OpenGL fullbright fix by Neal White III end tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false); // 1999-12-28 OpenGL fullbright fix by Neal White III start // create glowmap texture (all black except for glowing fullbright colors) if (hasfullbrights) { #ifdef _DEBUG qboolean bGlowDoubleCheck = false; #endif char glowname[32]; memcpy (glowname, mt->name, sizeof(mt->name)); glowname[16] = '\0'; for (j=0 ; glowname[j] != '\0'; j++) ; glowname[j++] = '<'; glowname[j++] = 'G'; glowname[j++] = 'L'; glowname[j++] = 'O'; glowname[j++] = 'W'; glowname[j++] = '>'; glowname[j++] = '\0'; ptexel = (byte *)(tx+1) + pixels; for (j=0 ; j<pixels ; j++) { if (ptexel[j] < 256-32) // build glowmap { ptexel[j] = 0; // make non-fullbrights black } #ifdef _DEBUG else { bGlowDoubleCheck = true; } #endif } tx->gl_glowtexnum = GL_LoadTexture (glowname, tx->width, tx->height, ptexel, true, false); tx->flags |= FLAG_HAS_GLOWMAP; #ifdef _DEBUG if (! bGlowDoubleCheck) Con_DPrintf ("INTERNAL ERROR: Mod_LoadTextures - FullBright texture \"%s\" has no FullBright colors!\n", glowname); #endif } // 1999-12-28 OpenGL fullbright fix by Neal White III end texture_mode = GL_LINEAR; } } // // sequence the animations // for (i=0 ; i<m->nummiptex ; i++) { tx = loadmodel->textures[i]; if (!tx || tx->name[0] != '+') continue; if (tx->anim_next) continue; // already sequenced // find the number of frames in the animation memset (anims, 0, sizeof(anims)); memset (altanims, 0, sizeof(altanims)); max = tx->name[1]; altmax = 0; if (max >= 'a' && max <= 'z') max -= 'a' - 'A'; if (max >= '0' && max <= '9') { max -= '0'; altmax = 0; anims[max] = tx; max++; } else if (max >= 'A' && max <= 'J') { altmax = max - 'A'; max = 0; altanims[altmax] = tx; altmax++; } else Sys_Error ("Bad animating texture %s", tx->name); for (j=i+1 ; j<m->nummiptex ; j++) { tx2 = loadmodel->textures[j]; if (!tx2 || tx2->name[0] != '+') continue; if (strcmp (tx2->name+2, tx->name+2)) continue; num = tx2->name[1]; if (num >= 'a' && num <= 'z') num -= 'a' - 'A'; if (num >= '0' && num <= '9') { num -= '0'; anims[num] = tx2; if (num+1 > max) max = num + 1; } else if (num >= 'A' && num <= 'J') { num = num - 'A'; altanims[num] = tx2; if (num+1 > altmax) altmax = num+1; } else Sys_Error ("Bad animating texture %s", tx->name); } #define ANIM_CYCLE 2 // link them all together for (j=0 ; j<max ; j++) { tx2 = anims[j]; if (!tx2) Sys_Error ("Missing frame %i of %s",j, tx->name); tx2->anim_total = max * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = anims[ (j+1)%max ]; if (altmax) tx2->alternate_anims = altanims[0]; } for (j=0 ; j<altmax ; j++) { tx2 = altanims[j]; if (!tx2) Sys_Error ("Missing frame %i of %s",j, tx->name); tx2->anim_total = altmax * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = altanims[ (j+1)%altmax ]; if (max) tx2->alternate_anims = anims[0]; } } }
/* ================= Mod_LoadTextures ================= */ void Mod_LoadTextures (lump_t *l) { int i, j, num, max, altmax, texture_flag, brighten_flag; miptex_t *mt; texture_t *tx, *tx2, *txblock, *anims[10], *altanims[10]; dmiptexlump_t *m; #ifndef RQM_SV_ONLY byte *data; #endif if (!l->filelen) { loadmodel->textures = NULL; return; } m = (dmiptexlump_t *)(mod_base + l->fileofs); m->nummiptex = LittleLong (m->nummiptex); loadmodel->numtextures = m->nummiptex; loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures), mod_loadname); txblock = Hunk_AllocName (m->nummiptex * sizeof(**loadmodel->textures), mod_loadname); #ifndef RQM_SV_ONLY #ifdef HEXEN2_SUPPORT if (hexen2) brighten_flag = 0; else #endif // brighten_flag = (gl_lightmode.value == 1) ? TEX_BRIGHTEN : 0; brighten_flag = 0; texture_flag = (gl_picmip_all.value || loadmodel->isworldmodel) ? TEX_MIPMAP : 0; #else brighten_flag = texture_flag = 0; #endif for (i = 0 ; i < m->nummiptex ; i++) { m->dataofs[i] = LittleLong (m->dataofs[i]); if (m->dataofs[i] == -1) continue; mt = (miptex_t *)((byte *)m + m->dataofs[i]); loadmodel->textures[i] = tx = txblock + i; memcpy (tx->name, mt->name, sizeof(tx->name)); if (!tx->name[0]) { Q_snprintfz (tx->name, sizeof(tx->name), "unnamed%d", i); Con_DPrintf ("Warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name); } tx->width = mt->width = LittleLong (mt->width); tx->height = mt->height = LittleLong (mt->height); // if ((mt->width & 15) || (mt->height & 15)) // Host_Error ("Mod_LoadTextures: Texture %s is not 16 aligned", mt->name); // was Sys_Error for (j=0 ; j<MIPLEVELS ; j++) mt->offsets[j] = LittleLong (mt->offsets[j]); // HACK HACK HACK if (!strcmp(mt->name, "shot1sid") && mt->width == 32 && mt->height == 32 && CRC_Block((byte*)(mt+1), mt->width*mt->height) == 65393) { // This texture in b_shell1.bsp has some of the first 32 pixels painted white. // They are invisible in software, but look really ugly in GL. So we just copy // 32 pixels from the bottom to make it look nice. memcpy (mt+1, (byte *)(mt+1) + 32*31, 32); } #ifndef RQM_SV_ONLY if (loadmodel->isworldmodel && ISSKYTEX(tx->name)) { R_InitSky (mt); continue; } if (Mod_LoadBrushModelTexture(tx, texture_flag)) continue; if (mt->offsets[0]) { data = (byte *)mt + mt->offsets[0]; tx2 = tx; } else { data = (byte *)tx2 + tx2->offsets[0]; // JDH: what is tx2 equal to at this point ??? tx2 = r_notexture_mip; } #ifdef _DEBUG // for (j = tx2->width*tx2->height; j >= 0; j--) // if (data[j] == 255) // break; #endif // tx->gl_texturenum = GL_LoadTexture (tx2->name, tx2->width, tx2->height, data, texture_flag | brighten_flag, 1); tx->gl_texturenum = GL_LoadTexture (tx2->name, tx2->width, tx2->height, data, texture_flag | TEX_BMODEL, 1); if (!ISTURBTEX(tx->name) && Img_HasFullbrights(data, tx2->width * tx2->height)) tx->fb_texturenum = GL_LoadTexture (va("@fb_%s", tx2->name), tx2->width, tx2->height, data, texture_flag | TEX_FULLBRIGHT, 1); /************** JDH ***************/ else tx->fb_texturenum = 0; /************** JDH ***************/ #endif } // sequence the animations for (i=0 ; i<m->nummiptex ; i++) { tx = loadmodel->textures[i]; if (!tx || tx->name[0] != '+') continue; if (tx->anim_next) continue; // already sequenced // find the number of frames in the animation memset (anims, 0, sizeof(anims)); memset (altanims, 0, sizeof(altanims)); max = tx->name[1]; altmax = 0; if (max >= 'a' && max <= 'z') max -= 'a' - 'A'; if (max >= '0' && max <= '9') { max -= '0'; altmax = 0; anims[max] = tx; max++; } else if (max >= 'A' && max <= 'J') { altmax = max - 'A'; max = 0; altanims[altmax] = tx; altmax++; } else { Host_Error ("Bad animating texture %s", tx->name); // was Sys_Error } for (j=i+1 ; j<m->nummiptex ; j++) { tx2 = loadmodel->textures[j]; if (!tx2 || tx2->name[0] != '+') continue; if (strcmp(tx2->name+2, tx->name+2)) continue; num = tx2->name[1]; if (num >= 'a' && num <= 'z') num -= 'a' - 'A'; if (num >= '0' && num <= '9') { num -= '0'; anims[num] = tx2; if (num+1 > max) max = num + 1; } else if (num >= 'A' && num <= 'J') { num = num - 'A'; altanims[num] = tx2; if (num+1 > altmax) altmax = num+1; } else { Host_Error ("Bad animating texture %s", tx->name); // was Sys_Error } } #define ANIM_CYCLE 2 // link them all together for (j=0 ; j<max ; j++) { tx2 = anims[j]; if (!tx2) Host_Error ("Mod_LoadTextures: Missing frame %i of %s", j, tx->name); // was Sys_Error tx2->anim_total = max * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = anims[(j+1)%max]; if (altmax) tx2->alternate_anims = altanims[0]; } for (j=0 ; j<altmax ; j++) { tx2 = altanims[j]; if (!tx2) Host_Error ("Mod_LoadTextures: Missing frame %i of %s", j, tx->name); // was Sys_Error tx2->anim_total = altmax * ANIM_CYCLE; tx2->anim_min = j * ANIM_CYCLE; tx2->anim_max = (j+1) * ANIM_CYCLE; tx2->anim_next = altanims[(j+1)%altmax]; if (max) tx2->alternate_anims = anims[0]; } } }