Ejemplo n.º 1
0
/**
 * @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);
}
Ejemplo n.º 2
0
/*
================
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];
}