⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrain.c

📁 quake3工具源码。包括生成bsp文件
💻 C
📖 第 1 页 / 共 2 页
字号:

	newsurf->miscModel		= qtrue;
	newsurf->shaderInfo		= shader;
	newsurf->lightmapNum	= -1;
	newsurf->fogNum			= -1;
	newsurf->numIndexes		= surf->numIndexes;
	newsurf->numVerts		= surf->numVerts;

	// copy the indices
	newsurf->indexes = malloc( surf->numIndexes * sizeof( *newsurf->indexes ) );
	memcpy( newsurf->indexes, surf->indexes, surf->numIndexes * sizeof( *newsurf->indexes ) );

	// allocate the vertices
	newsurf->verts = malloc( surf->numVerts * sizeof( *newsurf->verts ) );
	memset( newsurf->verts, 0, surf->numVerts * sizeof( *newsurf->verts ) );

	// calculate the surface verts
	out = newsurf->verts;
	for( i = 0; i < newsurf->numVerts; i++, out++ ) {
		VectorCopy( surf->verts[ i ].xyz, out->xyz );

		// set the texture coordinates
		out->st[ 0 ] = surf->verts[ i ].st[ 0 ];
		out->st[ 1 ] = surf->verts[ i ].st[ 1 ];

		// the colors will be set by the lighting pass
		out->color[0] = 255;
		out->color[1] = 255;
		out->color[2] = 255;
		out->color[3] = surf->verts[ i ].color[ 3 ];

		// calculate the vertex normal
		VectorClear( out->normal );
		for( j = 0; j < numsurfaces; j++ ) {
			in = surfaces[ j ].verts;
			for( k = 0; k < surfaces[ j ].numVerts; k++, in++ ) {
				if ( CompareVert( out, in, qfalse ) ) {
					VectorAdd( out->normal, in->normal, out->normal );
				}
			}
		}

		VectorNormalize( out->normal, out->normal );
	}
}

/*
================
EmitTerrainVerts
================
*/
void EmitTerrainVerts( side_t *side, terrainSurf_t *surf, int maxlayer, int alpha[ MAX_POINTS_ON_WINDING ], qboolean projecttexture ) {
	int			i;
	int			j;
	drawVert_t	*vert;
	int			*indices;
	int			numindices;
	int			maxindices;
	int			xyplane;
	vec3_t		xynorm = { 0, 0, 1 };
	vec_t		shift[ 2 ] = { 0, 0 };
	vec_t		scale[ 2 ] = { 0.5, 0.5 };
	float		vecs[ 2 ][ 4 ];

	if ( !surf->verts ) {
		surf->numVerts		= 0;
		surf->maxVerts		= GROW_VERTS;
		surf->verts			= malloc( surf->maxVerts * sizeof( *surf->verts ) );

		surf->numIndexes	= 0;
		surf->maxIndexes	= GROW_INDICES;
		surf->indexes		= malloc( surf->maxIndexes * sizeof( *surf->indexes ) );
	}

	// calculate the texture coordinate vectors
	xyplane = FindFloatPlane( xynorm, 0 );
	QuakeTextureVecs( &mapplanes[ xyplane ], shift, 0, scale, vecs );

	// emit the vertexes
	numindices = 0;
	maxindices = surf->maxIndexes;
	indices = malloc ( maxindices * sizeof( *indices ) );

	for ( i = 0; i < side->winding->numpoints; i++ ) {
		vert = &surf->verts[ surf->numVerts ];

		// set the final alpha value--0 for texture 1, 255 for texture 2
		if ( alpha[ i ] < maxlayer ) {
			vert->color[3] = 0;
		} else {
			vert->color[3] = 255;
		}

		vert->xyz[ 0 ] = floor( side->winding->p[ i ][ 0 ] + 0.1f );
		vert->xyz[ 1 ] = floor( side->winding->p[ i ][ 1 ] + 0.1f );
		vert->xyz[ 2 ] = floor( side->winding->p[ i ][ 2 ] + 0.1f );

		// set the texture coordinates
		if ( projecttexture ) {
			vert->st[0] = ( vecs[0][3] + DotProduct( vecs[ 0 ], vert->xyz ) ) / surf->shader->width;
			vert->st[1] = ( vecs[1][3] + DotProduct( vecs[ 1 ], vert->xyz ) ) / surf->shader->height;
		} else {
			vert->st[0] = ( side->vecs[0][3] + DotProduct( side->vecs[ 0 ], vert->xyz ) ) / surf->shader->width;
			vert->st[1] = ( side->vecs[1][3] + DotProduct( side->vecs[ 1 ], vert->xyz ) ) / surf->shader->height;
		}

		VectorCopy( mapplanes[ side->planenum ].normal, vert->normal );

		for( j = 0; j < surf->numVerts; j++ ) {
			if ( CompareVert( vert, &surf->verts[ j ], qtrue ) ) {
				break;
			}
		}
		
		if ( numindices >= maxindices ) {
			maxindices += GROW_INDICES;
			indices = realloc( indices, maxindices * sizeof( *indices ) );
		}

		if ( j != surf->numVerts ) {
			indices[ numindices++ ] = j;
		} else {
			if ( surf->numVerts >= surf->maxVerts ) {
				surf->maxVerts += GROW_VERTS;
				surf->verts = realloc( surf->verts, surf->maxVerts * sizeof( *surf->verts ) );
			}

			indices[ numindices++ ] = surf->numVerts;
			surf->numVerts++;
		}
	}

	SideAsTristrip( surf, indices, numindices );

	free( indices );
}

/*
================
SurfaceForShader
================
*/
terrainSurf_t *SurfaceForShader( shaderInfo_t *shader, int x, int y ) {
	int i;

	if ( lastSurface && ( lastSurface->shader == shader ) && ( lastSurface->x == x ) && ( lastSurface->y == y ) ) {
		return lastSurface;
	}

	lastSurface = surfaces;
	for( i = 0; i < numsurfaces; i++, lastSurface++ ) {
		if ( ( lastSurface->shader == shader ) && ( lastSurface->x == x ) && ( lastSurface->y == y ) ) {
			return lastSurface;
		}
	}

	if ( numsurfaces >= maxsurfaces ) {
		maxsurfaces += GROW_SURFACES;
		surfaces = realloc( surfaces, maxsurfaces * sizeof( *surfaces ) );
		memset( surfaces + numsurfaces + 1, 0, ( maxsurfaces - numsurfaces - 1 ) * sizeof( *surfaces ) );
	}

	lastSurface= &surfaces[ numsurfaces++ ];
	lastSurface->shader = shader;
	lastSurface->x = x;
	lastSurface->y = y;

	return lastSurface;
}

/*
================
SetTerrainTextures
================
*/
void SetTerrainTextures( void ) {
	int				i;
	int				x, y;
	int				layer;
	int				minlayer, maxlayer;
	float			s, t;
	float			min_s, min_t;
	int				alpha[ MAX_POINTS_ON_WINDING ];
	shaderInfo_t	*si, *terrainShader;
	bspbrush_t		*brush;
	side_t			*side;
	const char		*shadername;
	vec3_t			mins, maxs;
	vec3_t			size;
	int				surfwidth, surfheight, surfsize;
	terrainSurf_t	*surf;
	byte			*alphamap;
	int				alphawidth, alphaheight;
	int				num_layers;
	extern qboolean	onlyents;

	if ( onlyents ) {
		return;
	}

	shadername = ValueForKey( mapent, "shader" );
	if ( !shadername[ 0 ] ) {
		Error ("SetTerrainTextures: shader not specified" );
	}

	alphamap = LoadAlphaMap( &num_layers, &alphawidth, &alphaheight );
	num_layers = 3;

	mapent->firstDrawSurf = numMapDrawSurfs;

	// calculate the size of the terrain
	CalcTerrainSize( mins, maxs, size );

	surfwidth	= ( size[ 0 ] + SURF_WIDTH - 1 ) / SURF_WIDTH;
	surfheight	= ( size[ 1 ] + SURF_HEIGHT - 1 ) / SURF_HEIGHT;
	surfsize = surfwidth * surfheight;

	lastSurface = NULL;
	numsurfaces = 0;
	maxsurfaces = 0;
	for( i = num_layers; i > 0; i-- ) {
		maxsurfaces += i * surfsize;
	}
	surfaces = malloc( maxsurfaces * sizeof( *surfaces ) );
	memset( surfaces, 0, maxsurfaces * sizeof( *surfaces ) );

	terrainShader = ShaderInfoForShader( "textures/common/terrain" );

	for( brush = mapent->brushes; brush != NULL; brush = brush->next ) {
		// only create surfaces for sides marked as terrain
		for( side = brush->sides; side < &brush->sides[ brush->numsides ]; side++ ) {
			if ( !side->shaderInfo ) {
				continue;
			}

			if ( ( ( side->surfaceFlags | side->shaderInfo->surfaceFlags ) & SURF_NODRAW ) && !strstr( side->shaderInfo->shader, "terrain" ) ) {
				continue;
			}

			minlayer = num_layers;
			maxlayer = 0;

			// project each point of the winding onto the alphamap to determine which
			// textures to blend
			min_s = 1.0;
			min_t = 1.0;
			for( i = 0; i < side->winding->numpoints; i++ ) {
				s = floor( side->winding->p[ i ][ 0 ] + 0.1f - mins[ 0 ] ) / size[ 0 ];
				t = floor( maxs[ 1 ] - side->winding->p[ i ][ 1 ] + 0.1f ) / size[ 1 ];

				if ( s < 0 ) {
					s = 0;
				}
				
				if ( t < 0 ) {
					t = 0;
				}

				if ( s >= 1.0 ) {
					s = 1.0;
				}

				if ( t >= 1.0 ) {
					t = 1.0;
				}

				if ( s < min_s ) {
					min_s = s;
				}

				if ( t < min_t ) {
					min_t = t;
				}

				x = ( alphawidth - 1 ) * s;
				y = ( alphaheight - 1 ) * t;

				layer = alphamap[ x + y * alphawidth ];
				if ( layer < minlayer ) {
					minlayer = layer;
				}

				if ( layer > maxlayer ) {
					maxlayer = layer;
				}

				alpha[ i ] = layer;
			}

			x = min_s * surfwidth;
			if ( x >= surfwidth ) {
				x = surfwidth - 1;
			}

			y = min_t * surfheight;
			if ( y >= surfheight ) {
				y = surfheight - 1;
			}

			if ( strstr( side->shaderInfo->shader, "terrain" ) ) {
				si = ShaderForLayer( minlayer, maxlayer, shadername );
				if ( showseams ) {
					for( i = 0; i < side->winding->numpoints; i++ ) {
						if ( ( alpha[ i ] != minlayer ) && ( alpha[ i ] != maxlayer ) ) {
							si = ShaderInfoForShader( "textures/common/white" );
							break;
						}
					}
				}
				surf = SurfaceForShader( si, x, y );
				EmitTerrainVerts( side, surf, maxlayer, alpha, qtrue );
			} else {
				si = side->shaderInfo;
				side->shaderInfo = terrainShader;
				surf = SurfaceForShader( si, x, y );
				EmitTerrainVerts( side, surf, maxlayer, alpha, qfalse );
			}
		}
	}

	// create the final surfaces
	for( surf = surfaces, i = 0; i < numsurfaces; i++, surf++ ) {
		if ( surf->numVerts ) {
			CreateTerrainSurface( surf, surf->shader );
		}
	}

	//
	// clean up any allocated memory
	//
	for( surf = surfaces, i = 0; i < numsurfaces; i++, surf++ ) {
		if ( surf->verts ) {
			free( surf->verts );
			free( surf->indexes );
		}
	}
	free( alphamap );
	free( surfaces );

	surfaces = NULL;
	lastSurface = NULL;
	numsurfaces = 0;
	maxsurfaces = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -