Beispiel #1
0
void CreateMapFogs( void ){
	int i;
	entity_t    *entity;
	brush_t     *brush;
	fog_t       *fog;
	vec3_t invFogDir;
	const char  *globalFog;


	/* skip? */
	if ( nofog ) {
		return;
	}

	/* note it */
	Sys_FPrintf( SYS_VRB, "--- CreateMapFogs ---\n" );

	/* walk entities */
	for ( i = 0; i < numEntities; i++ )
	{
		/* get entity */
		entity = &entities[ i ];

		/* walk entity brushes */
		for ( brush = entity->brushes; brush != NULL; brush = brush->next )
		{
			/* ignore non-fog brushes */
			if ( brush->contentShader->fogParms == qfalse ) {
				continue;
			}

			/* test limit */
			if ( numMapFogs >= MAX_MAP_FOGS ) {
				Error( "Exceeded MAX_MAP_FOGS (%d)", MAX_MAP_FOGS );
			}

			/* set up fog */
			fog = &mapFogs[ numMapFogs++ ];
			fog->si = brush->contentShader;
			fog->brush = brush;
			fog->visibleSide = -1;

			/* if shader specifies an explicit direction, then find a matching brush side with an opposed normal */
			if ( VectorLength( fog->si->fogDir ) ) {
				/* flip it */
				VectorScale( fog->si->fogDir, -1.0f, invFogDir );

				/* find the brush side */
				for ( i = 0; i < brush->numsides; i++ )
				{
					if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ i ].planenum ].normal ) ) {
						fog->visibleSide = i;
						//%	Sys_Printf( "Brush num: %d Side num: %d\n", fog->brushNum, fog->visibleSide );
						break;
					}
				}
			}
		}
	}

	/* ydnar: global fog */
	globalFog = ValueForKey( &entities[ 0 ], "_fog" );
	if ( globalFog[ 0 ] == '\0' ) {
		globalFog = ValueForKey( &entities[ 0 ], "fog" );
	}
	if ( globalFog[ 0 ] != '\0' ) {
		/* test limit */
		if ( numMapFogs >= MAX_MAP_FOGS ) {
			Error( "Exceeded MAX_MAP_FOGS (%d) trying to add global fog", MAX_MAP_FOGS );
		}

		/* note it */
		Sys_FPrintf( SYS_VRB, "Map has global fog shader %s\n", globalFog );

		/* set up fog */
		fog = &mapFogs[ numMapFogs++ ];
		fog->si = ShaderInfoForShaderNull( globalFog );
		if ( fog->si == NULL ) {
			Error( "Invalid shader \"%s\" referenced trying to add global fog", globalFog );
		}
		fog->brush = NULL;
		fog->visibleSide = -1;

		/* set as default fog */
		defaultFogNum = numMapFogs - 1;

		/* mark all worldspawn brushes as fogged */
		for ( brush = entities[ 0 ].brushes; brush != NULL; brush = brush->next )
			ApplySurfaceParm( "fog", &brush->contentFlags, NULL, &brush->compileFlags );
	}

	/* emit some stats */
	Sys_FPrintf( SYS_VRB, "%9d fogs\n", numMapFogs );
}
Beispiel #2
0
void SetupTraceNodes(void)
{
	/* note it */
	Sys_FPrintf(SYS_VRB, "--- SetupTraceNodes ---\n");

	/* find nodraw bit */
	noDrawContentFlags = noDrawSurfaceFlags = noDrawCompileFlags = 0;
	ApplySurfaceParm("nodraw", &noDrawContentFlags, &noDrawSurfaceFlags, &noDrawCompileFlags);

	/* create the baseline raytracing tree from the bsp tree */
	headNodeNum = SetupTraceNodes_r(0);

	/* create outside node for skybox surfaces */
	skyboxNodeNum = AllocTraceNode();

	/* populate the tree with triangles from the world and shadow casting entities */
	PopulateTraceNodes();

	/* create the raytracing bsp */
#if 1
	// Tr3B: this requires ridiculous much memory
	if(loMem == qfalse)
	{
		SubdivideTraceNode_r(headNodeNum, 0);
		SubdivideTraceNode_r(skyboxNodeNum, 0);
	}
#endif

	/* create triangles from the trace windings */
	TriangulateTraceNode_r(headNodeNum);
	TriangulateTraceNode_r(skyboxNodeNum);

	/* emit some stats */
	//% Sys_FPrintf( SYS_VRB, "%9d original triangles\n", numOriginalTriangles );
	Sys_FPrintf(SYS_VRB, "%9d trace windings (%.2fMB)\n", numTraceWindings,
				(float)(numTraceWindings * sizeof(*traceWindings)) / (1024.0f * 1024.0f));
	Sys_FPrintf(SYS_VRB, "%9d trace triangles (%.2fMB)\n", numTraceTriangles,
				(float)(numTraceTriangles * sizeof(*traceTriangles)) / (1024.0f * 1024.0f));
	Sys_FPrintf(SYS_VRB, "%9d trace nodes (%.2fMB)\n", numTraceNodes,
				(float)(numTraceNodes * sizeof(*traceNodes)) / (1024.0f * 1024.0f));
	Sys_FPrintf(SYS_VRB, "%9d leaf nodes (%.2fMB)\n", numTraceLeafNodes,
				(float)(numTraceLeafNodes * sizeof(*traceNodes)) / (1024.0f * 1024.0f));
	//% Sys_FPrintf( SYS_VRB, "%9d average triangles per leaf node\n", numTraceTriangles / numTraceLeafNodes );
	Sys_FPrintf(SYS_VRB, "%9d average windings per leaf node\n", numTraceWindings / (numTraceLeafNodes + 1));
	Sys_FPrintf(SYS_VRB, "%9d max trace depth\n", maxTraceDepth);

	/* free trace windings */
	free(traceWindings);
	numTraceWindings = 0;
	maxTraceWindings = 0;
	deadWinding = -1;

	/* debug code: write out trace triangles to an alias obj file */
#if 0
	{
		int             i, j;
		FILE           *file;
		char            filename[1024];
		traceWinding_t *tw;


		/* open the file */
		strcpy(filename, source);
		StripExtension(filename);
		strcat(filename, ".lin");
		Sys_Printf("Opening light trace file %s...\n", filename);
		file = fopen(filename, "w");
		if(file == NULL)
			Error("Error opening %s for writing", filename);

		/* walk node list */
		for(i = 0; i < numTraceWindings; i++)
		{
			tw = &traceWindings[i];
			for(j = 0; j < tw->numVerts + 1; j++)
				fprintf(file, "%f %f %f\n",
						tw->v[j % tw->numVerts].xyz[0], tw->v[j % tw->numVerts].xyz[1], tw->v[j % tw->numVerts].xyz[2]);
		}

		/* close it */
		fclose(file);
	}
#endif
}
Beispiel #3
0
void RadLight( int num )
{
    int                    lightmapNum;
    float                scale, subdivide;
    int                    contentFlags, surfaceFlags, compileFlags;
    bspDrawSurface_t    *ds;
    surfaceInfo_t        *info;
    rawLightmap_t        *lm;
    shaderInfo_t        *si;
    clipWork_t            cw;
    
    
    /* get drawsurface, lightmap, and shader info */
    ds = &bspDrawSurfaces[ num ];
    info = &surfaceInfos[ num ];
    lm = info->lm;
    si = info->si;
    scale = si->bounceScale;
    
    /* find nodraw bit */
    contentFlags = surfaceFlags = compileFlags = 0;
    ApplySurfaceParm( "nodraw", &contentFlags, &surfaceFlags, &compileFlags );
    
    /* early outs? */
    if( scale <= 0.0f || (si->compileFlags & C_SKY) || si->autosprite ||
        (bspShaders[ ds->shaderNum ].contentFlags & contentFlags) || (bspShaders[ ds->shaderNum ].surfaceFlags & surfaceFlags) ||
        (si->compileFlags & compileFlags) )
        return;
    
    /* determine how much we need to chop up the surface */
    if( si->lightSubdivide )
        subdivide = si->lightSubdivide;
    else
        subdivide = diffuseSubdivide;
    
    /* inc counts */
    numDiffuseSurfaces++;
    
    /* iterate through styles (this could be more efficient, yes) */
    for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
    {
        /* switch on type */
        if( ds->lightmapStyles[ lightmapNum ] != LS_NONE && ds->lightmapStyles[ lightmapNum ] != LS_UNUSED )
        {
            switch( ds->surfaceType )
            {
                case MST_PLANAR:
                case MST_TRIANGLE_SOUP:
                    RadLightForTriangles( num, lightmapNum, lm, si, scale, subdivide, &cw );
                    break;
                
                case MST_PATCH:
                    RadLightForPatch( num, lightmapNum, lm, si, scale, subdivide, &cw );
                    break;
                
                default:
                    break;
            }
        }
    }
}