Exemple #1
0
/*
================
R_LoadLightGrid

================
*/
void R_LoadLightGrid( lump_t *l ) {
    int		i, j;
    vec3_t	maxs;
    world_t	*w;
    float	*wMins, *wMaxs;

    w = &s_worldData;

    w->lightGridInverseSize[0] = 1.0 / w->lightGridSize[0];
    w->lightGridInverseSize[1] = 1.0 / w->lightGridSize[1];
    w->lightGridInverseSize[2] = 1.0 / w->lightGridSize[2];

    wMins = w->bmodels[0].bounds[0];
    wMaxs = w->bmodels[0].bounds[1];

    for ( i = 0 ; i < 3 ; i++ ) {
        w->lightGridOrigin[i] = w->lightGridSize[i] * ceil( wMins[i] / w->lightGridSize[i] );
        maxs[i] = w->lightGridSize[i] * floor( wMaxs[i] / w->lightGridSize[i] );
        w->lightGridBounds[i] = (maxs[i] - w->lightGridOrigin[i])/w->lightGridSize[i] + 1;
    }

    int numGridDataElements = l->filelen / sizeof(*w->lightGridData);

    w->lightGridData = (mgrid_t *)ri.Hunk_Alloc( l->filelen, qfalse );
    memcpy( w->lightGridData, (void *)(fileBase + l->fileofs), l->filelen );

    // deal with overbright bits
    for ( i = 0 ; i < numGridDataElements ; i++ ) {
        for(j=0; j<MAXLIGHTMAPS; j++)
        {
            R_ColorShiftLightingBytes(w->lightGridData[i].ambientLight[j]);
            R_ColorShiftLightingBytes(w->lightGridData[i].directLight[j]);
        }
    }
}
Exemple #2
0
/*
===============
ParseTriSurf
===============
*/
static void ParseTriSurf( dsurface_t *ds, mapVert_t *verts, msurface_t *surf, int *indexes ) {
    srfTriangles_t	*tri;
    int				i, j, k;
    int				numVerts, numIndexes;

    // get fog volume
    surf->fogIndex = LittleLong( ds->fogNum ) + 1;

    // get shader
    surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapsVertex, ds->lightmapStyles, ds->vertexStyles );
    if ( r_singleShader->integer && !surf->shader->isSky ) {
        surf->shader = tr.defaultShader;
    }

    numVerts = LittleLong( ds->numVerts );
    numIndexes = LittleLong( ds->numIndexes );

    tri = (srfTriangles_t *) ri.Hunk_Alloc( sizeof( *tri ) + numVerts * sizeof( tri->verts[0] )
                                            + numIndexes * sizeof( tri->indexes[0] ), qtrue );
    tri->surfaceType = SF_TRIANGLES;
    tri->numVerts = numVerts;
    tri->numIndexes = numIndexes;
    tri->verts = (drawVert_t *)(tri + 1);
    tri->indexes = (int *)(tri->verts + tri->numVerts );

    surf->data = (surfaceType_t *)tri;

    // copy vertexes
    verts += LittleLong( ds->firstVert );
    ClearBounds( tri->bounds[0], tri->bounds[1] );
    for ( i = 0 ; i < numVerts ; i++ ) {
        for ( j = 0 ; j < 3 ; j++ ) {
            tri->verts[i].xyz[j] = LittleFloat( verts[i].xyz[j] );
            tri->verts[i].normal[j] = LittleFloat( verts[i].normal[j] );
        }
        AddPointToBounds( tri->verts[i].xyz, tri->bounds[0], tri->bounds[1] );
        for ( j = 0 ; j < 2 ; j++ ) {
            tri->verts[i].st[j] = LittleFloat( verts[i].st[j] );
            for(k=0; k<MAXLIGHTMAPS; k++)
            {
                tri->verts[i].lightmap[k][j] = LittleFloat( verts[i].lightmap[k][j] );
            }
        }
        for(k=0; k<MAXLIGHTMAPS; k++)
        {
            R_ColorShiftLightingBytes( verts[i].color[k], tri->verts[i].color[k] );
        }
    }

    // copy indexes
    indexes += LittleLong( ds->firstIndex );
    for ( i = 0 ; i < numIndexes ; i++ ) {
        tri->indexes[i] = LittleLong( indexes[i] );
        if ( tri->indexes[i] < 0 || tri->indexes[i] >= numVerts ) {
            ri.Error( ERR_DROP, "Bad index in triangle surface" );
        }
    }
}
Exemple #3
0
/*
===============
ParseMesh
===============
*/
static void ParseMesh ( dsurface_t *ds, mapVert_t *verts, msurface_t *surf) {
    srfGridMesh_t	*grid;
    int				i, j, k;
    int				width, height, numPoints;
    MAC_STATIC drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE];
    int				lightmapNum[MAXLIGHTMAPS];
    vec3_t			bounds[2];
    vec3_t			tmpVec;
    static surfaceType_t	skipData = SF_SKIP;

    for(i=0; i<MAXLIGHTMAPS; i++)
    {
        lightmapNum[i] = LittleLong( ds->lightmapNum[i] );
    }

    // get fog volume
    surf->fogIndex = LittleLong( ds->fogNum ) + 1;

    // get shader value
    surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum, ds->lightmapStyles, ds->vertexStyles );
    if ( r_singleShader->integer && !surf->shader->isSky ) {
        surf->shader = tr.defaultShader;
    }

    // we may have a nodraw surface, because they might still need to
    // be around for movement clipping
    if ( s_worldData.shaders[ LittleLong( ds->shaderNum ) ].surfaceFlags & SURF_NODRAW ) {
        surf->data = &skipData;
        return;
    }

    width = LittleLong( ds->patchWidth );
    height = LittleLong( ds->patchHeight );

    verts += LittleLong( ds->firstVert );
    numPoints = width * height;
    for ( i = 0 ; i < numPoints ; i++ ) {
        for ( j = 0 ; j < 3 ; j++ ) {
            points[i].xyz[j] = LittleFloat( verts[i].xyz[j] );
            points[i].normal[j] = LittleFloat( verts[i].normal[j] );
        }
        for ( j = 0 ; j < 2 ; j++ ) {
            points[i].st[j] = LittleFloat( verts[i].st[j] );
            for(k=0; k<MAXLIGHTMAPS; k++)
            {
                points[i].lightmap[k][j] = LittleFloat( verts[i].lightmap[k][j] );
            }
        }
        for(k=0; k<MAXLIGHTMAPS; k++)
        {
            R_ColorShiftLightingBytes( verts[i].color[k], points[i].color[k] );
        }
    }

    // pre-tesseleate
    grid = R_SubdividePatchToGrid( width, height, points );
    surf->data = (surfaceType_t *)grid;

    // copy the level of detail origin, which is the center
    // of the group of all curves that must subdivide the same
    // to avoid cracking
    for ( i = 0 ; i < 3 ; i++ ) {
        bounds[0][i] = LittleFloat( ds->lightmapVecs[0][i] );
        bounds[1][i] = LittleFloat( ds->lightmapVecs[1][i] );
    }
    VectorAdd( bounds[0], bounds[1], bounds[1] );
    VectorScale( bounds[1], 0.5f, grid->lodOrigin );
    VectorSubtract( bounds[0], grid->lodOrigin, tmpVec );
    grid->lodRadius = VectorLength( tmpVec );
}
Exemple #4
0
/*
===============
ParseFace
===============
*/
static void ParseFace( dsurface_t *ds, mapVert_t *verts, msurface_t *surf, int *indexes, byte *&pFaceDataBuffer)
{
    int			i, j, k;
    srfSurfaceFace_t	*cv;
    int			numPoints, numIndexes;
    int			lightmapNum[MAXLIGHTMAPS];
    int			sfaceSize, ofsIndexes;

    for(i=0; i<MAXLIGHTMAPS; i++)
    {
        lightmapNum[i] = LittleLong( ds->lightmapNum[i] );
    }

    // get fog volume
    surf->fogIndex = LittleLong( ds->fogNum ) + 1;

    // get shader value
    surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum, ds->lightmapStyles, ds->vertexStyles );
    if ( r_singleShader->integer && !surf->shader->isSky ) {
        surf->shader = tr.defaultShader;
    }

    numPoints = LittleLong( ds->numVerts );
    if (numPoints > MAX_FACE_POINTS) {
        ri.Printf( PRINT_DEVELOPER, "MAX_FACE_POINTS exceeded: %i\n", numPoints);
    }

    numIndexes = LittleLong( ds->numIndexes );

    // create the srfSurfaceFace_t
    sfaceSize = ( int ) &((srfSurfaceFace_t *)0)->points[numPoints];
    ofsIndexes = sfaceSize;
    sfaceSize += sizeof( int ) * numIndexes;

    cv = (srfSurfaceFace_t *) pFaceDataBuffer;//ri.Hunk_Alloc( sfaceSize );
    pFaceDataBuffer += sfaceSize;	// :-)

    cv->surfaceType = SF_FACE;
    cv->numPoints = numPoints;
    cv->numIndices = numIndexes;
    cv->ofsIndices = ofsIndexes;

    verts += LittleLong( ds->firstVert );
    for ( i = 0 ; i < numPoints ; i++ ) {
        for ( j = 0 ; j < 3 ; j++ ) {
            cv->points[i][j] = LittleFloat( verts[i].xyz[j] );
        }
        for ( j = 0 ; j < 2 ; j++ ) {
            cv->points[i][3+j] = LittleFloat( verts[i].st[j] );
            for(k=0; k<MAXLIGHTMAPS; k++)
            {
                cv->points[i][VERTEX_LM+j+(k*2)] = LittleFloat( verts[i].lightmap[k][j] );
            }
        }
        for(k=0; k<MAXLIGHTMAPS; k++)
        {
            R_ColorShiftLightingBytes( verts[i].color[k], (byte *)&cv->points[i][VERTEX_COLOR+k] );
        }
    }

    indexes += LittleLong( ds->firstIndex );
    for ( i = 0 ; i < numIndexes ; i++ ) {
        ((int *)((byte *)cv + cv->ofsIndices ))[i] = LittleLong( indexes[ i ] );
    }

    // take the plane information from the lightmap vector
    for ( i = 0 ; i < 3 ; i++ ) {
        cv->plane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
    }
    cv->plane.dist = DotProduct( cv->points[0], cv->plane.normal );
    SetPlaneSignbits( &cv->plane );
    cv->plane.type = PlaneTypeForNormal( cv->plane.normal );

    surf->data = (surfaceType_t *)cv;
}
Exemple #5
0
static	void R_LoadLightmaps( lump_t *l, const char *psMapName ) {
    byte		*buf, *buf_p;
    int			len;
    MAC_STATIC byte		image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4];
    int			i, j;
    float maxIntensity = 0;
    double sumIntensity = 0;

    len = l->filelen;
    if ( !len ) {
        return;
    }
    buf = fileBase + l->fileofs;

    // we are about to upload textures
    R_SyncRenderThread();

    // create all the lightmaps
    tr.numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);

    // if we are in r_vertexLight mode, we don't need the lightmaps at all
    if ( r_vertexLight->integer ) {
        return;
    }

    char sMapName[MAX_QPATH];
    COM_StripExtension(psMapName,sMapName);	// will already by MAX_QPATH legal, so no length check

    for ( i = 0 ; i < tr.numLightmaps ; i++ ) {
        // expand the 24 bit on-disk to 32 bit
        buf_p = buf + i * LIGHTMAP_SIZE*LIGHTMAP_SIZE * 3;

        if ( r_lightmap->integer == 2 )
        {   // color code by intensity as development tool	(FIXME: check range)
            for ( j = 0; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ )
            {
                float r = buf_p[j*3+0];
                float g = buf_p[j*3+1];
                float b = buf_p[j*3+2];
                float intensity;
                float out[3];

                intensity = 0.33f * r + 0.685 * g + 0.063f * b;

                if ( intensity > 255 )
                    intensity = 1.0f;
                else
                    intensity /= 255.0f;

                if ( intensity > maxIntensity )
                    maxIntensity = intensity;

                HSVtoRGB( intensity, 1.00, 0.50, out );

                image[j*4+0] = out[0] * 255;
                image[j*4+1] = out[1] * 255;
                image[j*4+2] = out[2] * 255;
                image[j*4+3] = 255;

                sumIntensity += intensity;
            }
        } else {
            for ( j = 0 ; j < LIGHTMAP_SIZE*LIGHTMAP_SIZE ; j++ ) {
                R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] );
                image[j*4+3] = 255;
            }
        }
        tr.lightmaps[i] = R_CreateImage( va("*%s/lightmap%d",sMapName,i), image,
                                         LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, r_ext_compressed_lightmaps->integer, GL_CLAMP);
    }

    if ( r_lightmap->integer == 2 )	{
        ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
    }
}
Exemple #6
0
void R_RMGInit(void)
{
	char			newSky[MAX_QPATH];
	char			newFog[MAX_QPATH];
	shader_t		*fog;
	fog_t			*gfog;
	mgrid_t			*grid;
	char			temp[MAX_QPATH];
	int				i;
	unsigned short	*pos;

	ri.Cvar_VariableStringBuffer("RMG_sky", newSky, MAX_QPATH);
	// Get sunlight - this should set up all the sunlight data
	R_FindShader( newSky, lightmapsNone, stylesDefault, qfalse );

	// Remap sky
	R_RemapShader("textures/tools/_sky", newSky, NULL);

	// Fill in the lightgrid with sunlight
	if(tr.world->lightGridData)
	{
		grid = tr.world->lightGridData;
		grid->ambientLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunAmbient[0] * 255.0f);
		grid->ambientLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunAmbient[1] * 255.0f);
		grid->ambientLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunAmbient[2] * 255.0f);
		R_ColorShiftLightingBytes(grid->ambientLight[0], grid->ambientLight[0]);

		grid->directLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunLight[0]);
		grid->directLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunLight[1]);
		grid->directLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunLight[2]);
		R_ColorShiftLightingBytes(grid->directLight[0], grid->directLight[0]);

		NormalToLatLong(tr.sunDirection, grid->latLong);

		pos = tr.world->lightGridArray;
		for(i=0;i<tr.world->numGridArrayElements;i++)
		{
			*pos = 0;
			pos++;
		}
	}

	// Override the global fog with the defined one
	if(tr.world->globalFog != -1)
	{
		ri.Cvar_VariableStringBuffer("RMG_fog", newFog, MAX_QPATH);
		fog = R_FindShader( newFog, lightmapsNone, stylesDefault, qfalse);
		if (fog != tr.defaultShader)
		{
			gfog = tr.world->fogs + tr.world->globalFog;
			gfog->parms = *fog->fogParms;
			if (gfog->parms.depthForOpaque)
			{
				gfog->tcScale = 1.0f / ( gfog->parms.depthForOpaque * 8.0f );
				tr.distanceCull = gfog->parms.depthForOpaque;
				tr.distanceCullSquared = tr.distanceCull * tr.distanceCull;
				ri.Cvar_Set("RMG_distancecull", va("%f", tr.distanceCull));
			}
			else
			{
				gfog->tcScale = 1.0f;
			}
			gfog->colorInt = ColorBytes4 ( gfog->parms.color[0], 
										  gfog->parms.color[1], 
										  gfog->parms.color[2], 1.0f );
		}
	}

	ri.Cvar_VariableStringBuffer("RMG_weather", temp, MAX_QPATH);

	// Set up any weather effects
	switch(atol(temp))
	{
	case 0:
		break;
	case 1:
		RE_WorldEffectCommand("rain init 1000");
		RE_WorldEffectCommand("rain outside");
		break;
	case 2:
		RE_WorldEffectCommand("snow init 1000 outside");
		RE_WorldEffectCommand("snow outside");
		break;
	}
}
Exemple #7
0
/*
===============
ParseTriSurf
===============
*/
static void ParseTriSurf( dsurface_t *ds, mapVert_t *verts, msurface_t *surf, int *indexes, world_t &worldData, int index ) {
	srfTriangles_t	*tri;
	int				i, j, k;
	int				numVerts, numIndexes;

	// get fog volume
	surf->fogIndex = LittleLong( ds->fogNum ) + 1;
	if (index && !surf->fogIndex && tr.world && tr.world->globalFog != -1)
	{
		surf->fogIndex = worldData.globalFog;
	}

	// get shader
	surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapsVertex, ds->lightmapStyles, ds->vertexStyles, worldData );
	if ( r_singleShader->integer && !surf->shader->sky ) {
		surf->shader = tr.defaultShader;
	}

	numVerts = LittleLong( ds->numVerts );
	numIndexes = LittleLong( ds->numIndexes );

	if ( numVerts >= SHADER_MAX_VERTEXES ) {
		Com_Error(ERR_DROP, "ParseTriSurf: verts > MAX (%d > %d) on misc_model %s", numVerts, SHADER_MAX_VERTEXES, surf->shader->name );
	}
	if ( numIndexes >= SHADER_MAX_INDEXES ) {
		Com_Error(ERR_DROP, "ParseTriSurf: indices > MAX (%d > %d) on misc_model %s", numIndexes, SHADER_MAX_INDEXES, surf->shader->name );
	}

	tri = (srfTriangles_t *) R_Malloc( sizeof( *tri ) + numVerts * sizeof( tri->verts[0] ) + numIndexes * sizeof( tri->indexes[0] ), TAG_HUNKMISCMODELS, qfalse );
	tri->dlightBits = 0; //JIC
	tri->surfaceType = SF_TRIANGLES;
	tri->numVerts = numVerts;
	tri->numIndexes = numIndexes;
	tri->verts = (drawVert_t *)(tri + 1);
	tri->indexes = (int *)(tri->verts + tri->numVerts );

	surf->data = (surfaceType_t *)tri;

	// copy vertexes
	verts += LittleLong( ds->firstVert );
	ClearBounds( tri->bounds[0], tri->bounds[1] );
	for ( i = 0 ; i < numVerts ; i++ ) {
		for ( j = 0 ; j < 3 ; j++ ) {
			tri->verts[i].xyz[j] = LittleFloat( verts[i].xyz[j] );
			tri->verts[i].normal[j] = LittleFloat( verts[i].normal[j] );
		}
		AddPointToBounds( tri->verts[i].xyz, tri->bounds[0], tri->bounds[1] );
		for ( j = 0 ; j < 2 ; j++ ) {
			tri->verts[i].st[j] = LittleFloat( verts[i].st[j] );
			for(k=0;k<MAXLIGHTMAPS;k++)
			{
				tri->verts[i].lightmap[k][j] = LittleFloat( verts[i].lightmap[k][j] );
			}
		}
		for(k=0;k<MAXLIGHTMAPS;k++)
		{
			R_ColorShiftLightingBytes( verts[i].color[k], tri->verts[i].color[k] );
		}
	}

	// copy indexes
	indexes += LittleLong( ds->firstIndex );
	for ( i = 0 ; i < numIndexes ; i++ ) {
		tri->indexes[i] = LittleLong( indexes[i] );
		if ( tri->indexes[i] < 0 || tri->indexes[i] >= numVerts ) {
			Com_Error( ERR_DROP, "Bad index in triangle surface" );
		}
	}
}
Exemple #8
0
static	void R_LoadLightmaps( lump_t *l, const char *psMapName, world_t &worldData )
{
	byte				*buf, *buf_p;
	int					len;
	byte		image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4];
	int					i, j;
	float				maxIntensity = 0;
	double				sumIntensity = 0;
	int					count;

	if (&worldData == &s_worldData)
	{
		tr.numLightmaps = 0;
	}

    len = l->filelen;
	if ( !len ) {
		return;
	}
	buf = fileBase + l->fileofs;

	// we are about to upload textures
	R_IssuePendingRenderCommands(); //

	// create all the lightmaps
	worldData.startLightMapIndex = tr.numLightmaps;
	count = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
	tr.numLightmaps += count;

	// if we are in r_vertexLight mode, we don't need the lightmaps at all
	if ( r_vertexLight->integer ) {
		return;
	}

	char sMapName[MAX_QPATH];
	COM_StripExtension(psMapName,sMapName, sizeof(sMapName));

	for ( i = 0 ; i < count ; i++ ) {
		// expand the 24 bit on-disk to 32 bit
		buf_p = buf + i * LIGHTMAP_SIZE*LIGHTMAP_SIZE * 3;

		if ( r_lightmap->integer == 2 )
		{	// color code by intensity as development tool	(FIXME: check range)
			for ( j = 0; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ )
			{
				float r = buf_p[j*3+0];
				float g = buf_p[j*3+1];
				float b = buf_p[j*3+2];
				float intensity;
				float out[3] = {0.0f, 0.0f, 0.0f};

				intensity = 0.33f * r + 0.685f * g + 0.063f * b;

				if ( intensity > 255 )
					intensity = 1.0f;
				else
					intensity /= 255.0f;

				if ( intensity > maxIntensity )
					maxIntensity = intensity;

				HSVtoRGB( intensity, 1.00, 0.50, out );

				image[j*4+0] = out[0] * 255;
				image[j*4+1] = out[1] * 255;
				image[j*4+2] = out[2] * 255;
				image[j*4+3] = 255;

				sumIntensity += intensity;
			}
		} else {
			for ( j = 0 ; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) {
				R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] );
				image[j*4+3] = 255;
			}
		}
		tr.lightmaps[worldData.startLightMapIndex+i] = R_CreateImage(
			va("$%s/lightmap%d", sMapName, worldData.startLightMapIndex+i),
			image, LIGHTMAP_SIZE, LIGHTMAP_SIZE, GL_RGBA, qfalse, qfalse,
			(qboolean)(r_ext_compressed_lightmaps->integer != 0),
			GL_CLAMP);
	}

	if ( r_lightmap->integer == 2 )	{
		ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
	}
}