Example #1
0
/**
 * @sa R_ModLoadSurfaces
 */
void R_CreateSurfaceLightmap (mBspSurface_t * surf)
{
	int smax, tmax;
	byte *samples, *directions;

	if (!(surf->flags & MSURF_LIGHTMAP))
		return;

	smax = (surf->stextents[0] / surf->lightmap_scale) + 1;
	tmax = (surf->stextents[1] / surf->lightmap_scale) + 1;

	if (!R_AllocLightmapBlock(smax, tmax, &surf->light_s, &surf->light_t)) {
		/* upload the last block */
		R_UploadLightmapBlock();
		if (!R_AllocLightmapBlock(smax, tmax, &surf->light_s, &surf->light_t))
			Com_Error(ERR_DROP, "R_CreateSurfaceLightmap: Consecutive calls to R_AllocLightmapBlock(%d,%d) failed (lightmap_scale: %i, stextends: %f %f)\n",
					smax, tmax, surf->lightmap_scale, surf->stextents[0], surf->stextents[1]);
	}

	surf->lightmap_texnum = r_lightmaps.lightmap_texnums[r_lightmaps.lightmap_count];
	surf->deluxemap_texnum = r_lightmaps.deluxemap_texnums[r_lightmaps.deluxemap_count];

	samples = r_lightmaps.sample_buffer;
	samples += (surf->light_t * r_lightmaps.size + surf->light_s) * LIGHTMAP_BLOCK_BYTES;

	directions = r_lightmaps.direction_buffer;
	directions += (surf->light_t * r_lightmaps.size + surf->light_s) * DELUXEMAP_BLOCK_BYTES;

	if (!surf->samples)  /* make it fullbright */
		R_BuildDefaultLightmap(surf, samples, directions, r_lightmaps.size * LIGHTMAP_BLOCK_BYTES);
	else  /* or light it properly */
		R_BuildLightmap(surf, samples, directions, r_lightmaps.size * LIGHTMAP_BLOCK_BYTES);
}
Example #2
0
/**
 * @brief Uploads sorted lightmaps from start to (end - 1) and
 * puts them in the new maps sized to width/height
 */
static void R_UploadPackedLightmaps(uint32_t width, uint32_t height, r_bsp_model_t *bsp, GSList *start, GSList *end) {

	// edge case, no blocks left
	if (!width || !height || !start) {
		return;
	}

	// allocate the image
	r_image_t *lightmap = R_AllocLightmap(width, height);
	r_image_t *deluxemap = R_AllocDeluxemap(width, height);
	r_image_t *stainmap = NULL;

	if (r_stainmap->integer) {
		stainmap = R_AllocStainmap(width, height);
	}

	// temp buffers
	byte *sample_buffer = Mem_Malloc(width * height * 3);
	byte *direction_buffer = Mem_Malloc(width * height * 3);

	do {
		r_bsp_surface_t *surf = (r_bsp_surface_t *) start->data;

		const size_t stride = width * 3;
		const size_t lightmap_offset = (surf->lightmap_t *width + surf->lightmap_s) * 3;

		byte *sout = sample_buffer + lightmap_offset;
		byte *dout = direction_buffer + lightmap_offset;

		if (surf->lightmap_input) {
			byte *stout = NULL;

			if (r_stainmap->integer) {
				surf->stainmap = stainmap;
				stout = surf->stainmap_buffer = Mem_LinkMalloc(surf->lightmap_size[0] * surf->lightmap_size[1] * 3, bsp);
			}

			R_BuildLightmap(bsp, surf, surf->lightmap_input, sout, dout, stout, stride);
		} else {
			R_BuildDefaultLightmap(bsp, surf, sout, dout, stride);
		}

		surf->lightmap = lightmap;
		surf->deluxemap = deluxemap;

		start = start->next;
	} while (start != end);

	// upload!
	R_UploadImage(lightmap, GL_RGB, sample_buffer);
	R_UploadImage(deluxemap, GL_RGB, direction_buffer);

	// copy to the stainmap
	if (r_stainmap->integer) {
		R_UploadImage(stainmap, GL_RGB, sample_buffer);
	}

	Mem_Free(sample_buffer);
	Mem_Free(direction_buffer);
}
Example #3
0
/*
* R_PackLightmaps
*/
static int R_PackLightmaps( int num, int w, int h, int size, int stride, qboolean deluxe, const char *name, const qbyte *data, mlightmapRect_t *rects )
{
	int i, x, y, root;
	qbyte *block;
	int lightmapNum;
	int rectX, rectY, rectSize;
	int maxX, maxY, max, xStride;
	double tw, th, tx, ty;
	mlightmapRect_t *rect;

	maxX = r_maxLightmapBlockSize / w;
	maxY = r_maxLightmapBlockSize / h;
	max = min( maxX, maxY );

	ri.Com_DPrintf( "Packing %i lightmap(s) -> ", num );

	if( !max || num == 1 || !mapConfig.lightmapsPacking /* || !r_lighting_packlightmaps->integer*/ )
	{
		// process as it is
		R_BuildLightmap( w, h, deluxe, data, r_lightmapBuffer, w * LIGHTMAP_BYTES );

		lightmapNum = R_UploadLightmap( name, r_lightmapBuffer, w, h );
		if( rects )
		{
			rects[0].texNum = lightmapNum;

			// this is not a real texture matrix, but who cares?
			rects[0].texMatrix[0][0] = 1; rects[0].texMatrix[0][1] = 0;
			rects[0].texMatrix[1][0] = 1; rects[0].texMatrix[1][1] = 0;
		}

		ri.Com_DPrintf( "\n" );

		return 1;
	}

	// find the nearest square block size
	root = ( int )sqrt( (float)num );
	if( root > max )
		root = max;

	// keep row size a power of two
	for( i = 1; i < root; i <<= 1 ) ;
	if( i > root )
		i >>= 1;
	root = i;

	num -= root * root;
	rectX = rectY = root;

	if( maxY > maxX )
	{
		for(; ( num >= root ) && ( rectY < maxY ); rectY++, num -= root ) ;

		//if( !glConfig.ext.texture_non_power_of_two )
		{
			// sample down if not a power of two
			for( y = 1; y < rectY; y <<= 1 ) ;
			if( y > rectY )
				y >>= 1;
			rectY = y;
		}
	}
	else
	{
		for(; ( num >= root ) && ( rectX < maxX ); rectX++, num -= root ) ;