/** * @brief General surface drawing function, that draw the surface chains * @note The needed states for the surfaces must be set before you call this * @sa R_DrawSurface * @sa R_SetSurfaceState */ void R_DrawSurfaces (const mBspSurfaces_t *surfs) { int numSurfaces = surfs->count; mBspSurface_t **surfPtrList = surfs->surfaces; const int frame = r_locals.frame; int lastLightMap = 0, lastDeluxeMap = 0; image_t *lastTexture = NULL; uint32_t lastFlags = ~0; while (numSurfaces--) { const mBspSurface_t *surf = *surfPtrList++; mBspTexInfo_t *texInfo; int texFlags; if (surf->frame != frame) continue; /** @todo integrate it better with R_SetSurfaceState - maybe cache somewhere in the mBspSurface_t ? */ texInfo = surf->texinfo; texFlags = texInfo->flags & (SURF_BLEND33 | SURF_BLEND66 | MSURF_LIGHTMAP); /* should match flags that affect R_SetSurfaceState behavior */ if (texInfo->image != lastTexture || surf->lightmap_texnum != lastLightMap || surf->deluxemap_texnum != lastDeluxeMap || texFlags != lastFlags) { lastTexture = texInfo->image; lastLightMap = surf->lightmap_texnum; lastDeluxeMap = surf->deluxemap_texnum; lastFlags = texFlags; R_SetSurfaceState(surf); } R_DrawSurface(surf); } /* reset state */ if (r_state.active_normalmap) R_EnableBumpmap(NULL); R_EnableGlowMap(NULL); R_Color(NULL); }
/* ================ D_CacheSurface ================ */ surfcache_t * D_CacheSurface(const entity_t *e, msurface_t *surface, int miplevel) { surfcache_t *cache; // // if the surface is animating or flashing, flush the cache // r_drawsurf.texture = R_TextureAnimation(e, surface->texinfo->texture); r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]]; r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]]; r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]]; r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]]; // // see if the cache holds apropriate data // cache = surface->cachespots[miplevel]; if (cache && !cache->dlight && surface->dlightframe != r_framecount && cache->texture == r_drawsurf.texture && cache->lightadj[0] == r_drawsurf.lightadj[0] && cache->lightadj[1] == r_drawsurf.lightadj[1] && cache->lightadj[2] == r_drawsurf.lightadj[2] && cache->lightadj[3] == r_drawsurf.lightadj[3]) return cache; // // determine shape of surface // surfscale = 1.0 / (1 << miplevel); r_drawsurf.surfmip = miplevel; r_drawsurf.surfwidth = surface->extents[0] >> miplevel; r_drawsurf.rowbytes = r_drawsurf.surfwidth; r_drawsurf.surfheight = surface->extents[1] >> miplevel; // // allocate memory if needed // if (!cache) // if a texture just animated, don't reallocate it { cache = D_SCAlloc(r_drawsurf.surfwidth, r_drawsurf.surfwidth * r_drawsurf.surfheight); surface->cachespots[miplevel] = cache; cache->owner = &surface->cachespots[miplevel]; cache->mipscale = surfscale; } if (surface->dlightframe == r_framecount) cache->dlight = 1; else cache->dlight = 0; r_drawsurf.surfdat = (pixel_t *)cache->data; cache->texture = r_drawsurf.texture; cache->lightadj[0] = r_drawsurf.lightadj[0]; cache->lightadj[1] = r_drawsurf.lightadj[1]; cache->lightadj[2] = r_drawsurf.lightadj[2]; cache->lightadj[3] = r_drawsurf.lightadj[3]; // // draw and light the surface texture // r_drawsurf.surf = surface; c_surf++; R_DrawSurface(); return surface->cachespots[miplevel]; }