void gld_BindTexture(GLTexture *gltexture, unsigned int flags) { const rpatch_t *patch; unsigned char *buffer; int w, h; if (!gltexture || gltexture->textype != GLDT_TEXTURE) { qglBindTexture(GL_TEXTURE_2D, 0); last_glTexID = NULL; return; } #ifdef HAVE_LIBSDL_IMAGE if (gld_LoadHiresTex(gltexture, CR_DEFAULT)) { gld_SetTexClamp(gltexture, flags); last_glTexID = gltexture->texid_p; return; } #endif gld_GetTextureTexID(gltexture, CR_DEFAULT); if (last_glTexID == gltexture->texid_p) { gld_SetTexClamp(gltexture, flags); return; } last_glTexID = gltexture->texid_p; if (*gltexture->texid_p != 0) { qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p); gld_SetTexClamp(gltexture, flags); return; } buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0); if (!(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture) memset(buffer,transparent_pal_index,gltexture->buffer_size); else memset(buffer,0,gltexture->buffer_size); patch=R_CacheTextureCompositePatchNum(gltexture->index); gld_AddPatchToTexture(gltexture, buffer, patch, 0, 0, CR_DEFAULT, !(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture); R_UnlockTextureCompositePatchNum(gltexture->index); if (*gltexture->texid_p == 0) qglGenTextures(1, gltexture->texid_p); qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p); if (gltexture->flags & GLTEXTURE_HASHOLES) { SmoothEdges(buffer, gltexture->buffer_width, gltexture->buffer_height); } buffer = gld_HQResize(gltexture, buffer, gltexture->buffer_width, gltexture->buffer_height, &w, &h); gld_BuildTexture(gltexture, buffer, false, w, h); gld_SetTexClamp(gltexture, flags); }
static void R_InitTextures (void) { const maptexture_t *mtexture; texture_t *texture; const mappatch_t *mpatch; texpatch_t *patch; int i, j; int maptex_lump[2] = {-1, -1}; const int *maptex; const int *maptex1, *maptex2; char name[9]; int names_lump; // cph - new wad lump handling const char *names; // cph - const char *name_p;// const*'s int *patchlookup; int nummappatches; int offset; int maxoff, maxoff2; int numtextures1, numtextures2; const int *directory; int errors = 0; // Load the patch names from pnames.lmp. name[8] = 0; names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES")); nummappatches = LittleLong(*((const int *)names)); name_p = names+4; patchlookup = malloc(nummappatches*sizeof(*patchlookup)); // killough for (i=0 ; i<nummappatches ; i++) { strncpy (name,name_p+i*8, 8); patchlookup[i] = W_CheckNumForName(name); if (patchlookup[i] == -1) { // killough 4/17/98: // Some wads use sprites as wall patches, so repeat check and // look for sprites this time, but only if there were no wall // patches found. This is the same as allowing for both, except // that wall patches always win over sprites, even when they // appear first in a wad. This is a kludgy solution to the wad // lump namespace problem. patchlookup[i] = (W_CheckNumForName)(name, ns_sprites); if (patchlookup[i] == -1 && devparm) //jff 8/3/98 use logical output routine lprintf(LO_WARN,"\nWarning: patch %.8s, index %d does not exist",name,i); } } W_UnlockLumpNum(names_lump); // cph - release the lump // Load the map texture definitions from textures.lmp. // The data is contained in one or two lumps, // TEXTURE1 for shareware, plus TEXTURE2 for commercial. maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1")); numtextures1 = LittleLong(*maptex); maxoff = W_LumpLength(maptex_lump[0]); directory = maptex+1; if (W_CheckNumForName("TEXTURE2") != -1) { maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2")); numtextures2 = LittleLong(*maptex2); maxoff2 = W_LumpLength(maptex_lump[1]); } else { maptex2 = NULL; numtextures2 = 0; maxoff2 = 0; } numtextures = numtextures1 + numtextures2; // killough 4/9/98: make column offsets 32-bit; // clean up malloc-ing to use sizeof textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0); textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0); for (i=0 ; i<numtextures ; i++, directory++) { if (i == numtextures1) { // Start looking in second texture file. maptex = maptex2; maxoff = maxoff2; directory = maptex+1; } offset = LittleLong(*directory); if (offset > maxoff) I_Error("R_InitTextures: Bad texture directory"); mtexture = (const maptexture_t *) ( (const byte *)maptex + offset); texture = textures[i] = Z_Malloc(sizeof(texture_t) + sizeof(texpatch_t)*(LittleShort(mtexture->patchcount)-1), PU_STATIC, 0); texture->width = LittleShort(mtexture->width); texture->height = LittleShort(mtexture->height); texture->patchcount = LittleShort(mtexture->patchcount); /* Mattias Engdegård emailed me of the following explenation of * why memcpy doesnt work on some systems: * "I suppose it is the mad unaligned allocation * going on (and which gcc in some way manages to cope with * through the __attribute__ ((packed))), and which it forgets * when optimizing memcpy (to a single word move) since it appears * to be aligned. Technically a gcc bug, but I can't blame it when * it's stressed with that amount of * non-standard nonsense." * So in short the unaligned struct confuses gcc's optimizer so * i took the memcpy out alltogether to avoid future problems-Jess */ /* The above was #ifndef SPARC, but i got a mail from * Putera Joseph F NPRI <*****@*****.**> containing: * I had to use the memcpy function on a sparc machine. The * other one would give me a core dump. * cph - I find it hard to believe that sparc memcpy is broken, * but I don't believe the pointers to memcpy have to be aligned * either. Use fast memcpy on other machines anyway. */ /* proff - I took this out, because Oli Kraus ([email protected]) told me the memcpy produced a buserror. Since this function isn't time- critical I'm using the for loop now. */ /* #ifndef GCC memcpy(texture->name, mtexture->name, sizeof(texture->name)); #else */ { size_t j; for(j=0;j<sizeof(texture->name);j++) texture->name[j]=mtexture->name[j]; } /* #endif */ mpatch = mtexture->patches; patch = texture->patches; for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++) { patch->originx = LittleShort(mpatch->originx); patch->originy = LittleShort(mpatch->originy); patch->patch = patchlookup[LittleShort(mpatch->patch)]; if (patch->patch == -1) { //jff 8/3/98 use logical output routine lprintf(LO_ERROR,"\nR_InitTextures: Missing patch %d in texture %.8s", LittleShort(mpatch->patch), texture->name); // killough 4/17/98 ++errors; } } for (j=1; j*2 <= texture->width; j<<=1) ; texture->widthmask = j-1; textureheight[i] = texture->height<<FRACBITS; } free(patchlookup); // killough for (i=0; i<2; i++) // cph - release the TEXTUREx lumps if (maptex_lump[i] != -1) W_UnlockLumpNum(maptex_lump[i]); if (errors) { const lumpinfo_t* info = W_GetLumpInfoByNum(names_lump); wadfile_info_t *wf = M_CBufGet(&resource_files_buf, info->wadfile); if (wf == NULL) { I_Error( "R_InitTextures: Bad wadfile for %s (%d)\n", info->name, info->wadfile ); } lprintf(LO_INFO, "\nR_InitTextures: The file %s seems to be incompatible with \"%s\".\n", wf->name, (doomverstr ? doomverstr : "DOOM")); I_Error("R_InitTextures: %d errors", errors); } // Precalculate whatever possible. if (devparm) // cph - If in development mode, generate now so all errors are found at once { R_InitPatches(); //e6y for (i=0 ; i<numtextures ; i++) { // proff - This is for the new renderer now R_CacheTextureCompositePatchNum(i); R_UnlockTextureCompositePatchNum(i); } } if (errors) I_Error("R_InitTextures: %d errors", errors); // Create translation table for global animation. // killough 4/9/98: make column offsets 32-bit; // clean up malloc-ing to use sizeof texturetranslation = Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0); for (i=0 ; i<numtextures ; i++) texturetranslation[i] = i; // killough 1/31/98: Initialize texture hash table for (i = 0; i<numtextures; i++) textures[i]->index = -1; while (--i >= 0) { int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures; textures[i]->next = textures[j]->index; // Prepend to chain textures[j]->index = i; } }
//----------------------------------------------------------------------------- // // R_DrawPlanes // At the end of each frame. // void R_DrawPlanes(void) { int i; visplane_t *pl; #ifdef RANGECHECK if (ds_p > &drawsegs[MAXDRAWSEGS]) I_Error ("R_DrawPlanes: drawsegs overflow (%i)", ds_p - drawsegs); if (lastvisplane > &visplanes[MAXVISPLANES]) I_Error ("R_DrawPlanes: visplane overflow (%i)", lastvisplane - visplanes); if (lastopening > &openings[MAXOPENINGS]) I_Error ("R_DrawPlanes: opening overflow (%i)", lastopening - openings); #endif if (showrplanestats) { #ifdef __riscos extern void _kernel_oswrch (int); _kernel_oswrch (31); _kernel_oswrch (0); _kernel_oswrch (0); #endif printf ("Drawsegs = %u/%u, Visplanes = %u/%u, Openings = %u/%u\n", ds_p - drawsegs, MAXDRAWSEGS, lastvisplane - visplanes, MAXVISPLANES, lastopening - openings, MAXOPENINGS); } for (pl = visplanes ; pl < lastvisplane ; pl++) { if (pl->minx <= pl->maxx) { int picnum = pl->picnum; // sky flat if (picnum == skyflatnum || (picnum & PL_SKYFLAT)) { int x; int texture; int offset; angle_t an, flip; rpatch_t *tex_patch; // killough 10/98: allow skies to come from sidedefs. // Allows scrolling and/or animated skies, as well as // arbitrary multiple skies per level without having // to use info lumps. an = viewangle; if (picnum & PL_SKYFLAT) { // Sky Linedef const line_t *l = &lines[picnum & ~PL_SKYFLAT]; // Sky transferred from first sidedef const side_t *s = *l->sidenum + sides; // Texture comes from upper texture of reference sidedef texture = texturetranslation[s->toptexture]; // Horizontal offset is turned into an angle offset, // to allow sky rotation as well as careful positioning. // However, the offset is scaled very small, so that it // allows a long-period of sky rotation. an += s->textureoffset; // Vertical offset allows careful sky positioning. dc_texturemid = s->rowoffset - 28 * FRACUNIT; // We sometimes flip the picture horizontally. // // DOOM always flipped the picture, so we make it optional, // to make it easier to use the new feature, while to still // allow old sky textures to be used. flip = l->special==272 ? 0u : ~0u; } else // Normal DOOM sky, only one allowed per level { dc_texturemid = skytexturemid; // Default y-offset texture = skytexture; // Default texture flip = 0; // DOOM flips it } // Sky is always drawn full bright, // i.e. colormaps[0] is used. // Because of this hack, sky is not affected // by INVUL inverse mapping. dc_colormap = (fixedcolormap ? fixedcolormap : colormaps); dc_ylim = textureheight[texture]; dc_iscale = skyiscale; tex_patch = R_CacheTextureCompositePatchNum (texture); offset = skycolumnoffset >> FRACBITS; for (x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x+1]; dc_yh = pl->bottom[x+1]; if (dc_yl <= dc_yh) { dc_x = x; dc_source = R_GetTextureColumn(tex_patch, (((an + xtoviewangle[x]) ^ flip) >> ANGLETOSKYSHIFT) + offset); dc_texturefrac = R_CalcFrac (); colfunc(); } } R_UnlockTextureCompositePatchNum (texture); }
void gld_BindTexture(GLTexture *gltexture) { const rpatch_t *patch; int i; unsigned char *buffer; if (gltexture==last_gltexture) return; last_gltexture=gltexture; if (!gltexture) { glBindTexture(GL_TEXTURE_2D, 0); last_gltexture = NULL; last_cm = -1; return; } if (gltexture->textype!=GLDT_TEXTURE) { glBindTexture(GL_TEXTURE_2D, 0); last_gltexture = NULL; last_cm = -1; return; } if (gltexture->glTexID[CR_DEFAULT]!=0) { glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]); glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i); #ifdef _DEBUG if (i!=GL_TRUE) lprintf(LO_INFO, "glGetTexParam: %i\n", i); #endif if (i==GL_TRUE) return; } buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0); if (!(gltexture->mipmap & use_mipmapping) & gl_paletted_texture) memset(buffer,transparent_pal_index,gltexture->buffer_size); else memset(buffer,0,gltexture->buffer_size); patch=R_CacheTextureCompositePatchNum(gltexture->index); gld_AddPatchToTexture(gltexture, buffer, patch, 0, 0, CR_DEFAULT, !(gltexture->mipmap & use_mipmapping) & gl_paletted_texture); R_UnlockTextureCompositePatchNum(gltexture->index); if (gltexture->glTexID[CR_DEFAULT]==0) glGenTextures(1,&gltexture->glTexID[CR_DEFAULT]); glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]); #ifdef USE_GLU_MIPMAP if (gltexture->mipmap & use_mipmapping) { gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format, gltexture->buffer_width, gltexture->buffer_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_mipmap_filter); if (gl_texture_filter_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0); } else #endif /* USE_GLU_MIPMAP */ { #ifdef USE_GLU_IMAGESCALE if ((gltexture->buffer_width!=gltexture->tex_width) || (gltexture->buffer_height!=gltexture->tex_height) ) { unsigned char *scaledbuffer; scaledbuffer=(unsigned char*)Z_Malloc(gltexture->tex_width*gltexture->tex_height*4,PU_STATIC,0); if (scaledbuffer) { gluScaleImage(GL_RGBA, gltexture->buffer_width, gltexture->buffer_height, GL_UNSIGNED_BYTE,buffer, gltexture->tex_width, gltexture->tex_height, GL_UNSIGNED_BYTE,scaledbuffer); Z_Free(buffer); buffer=scaledbuffer; glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format, gltexture->tex_width, gltexture->tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } } else #endif /* USE_GLU_IMAGESCALE */ { if (gl_paletted_texture) { I_Error("Paletted textures not supported"); /* gld_SetTexturePalette(GL_TEXTURE_2D); glTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, gltexture->buffer_width, gltexture->buffer_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer); */ } else { glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format, gltexture->buffer_width, gltexture->buffer_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } } // Vladimir (i) -> (x) glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter); } Z_Free(buffer); }