Skip to main content
GameDev.net gamedev.net
🔒 Locked

BSP30 rendering

Started by Ozwald May 22, 2006 at 1:02 PM 1 replies 1.2k views
Original Post
Ozwald
Ozwald
Hi, I'm loading and using bsp version 30 files (same as half-life 1) and have successfully loaded the file into data, but I'm having trouble figuring out how I'm to render this data... Here is how the data is structured:
		// BSP Lumps
		struct tBSPLump {	unsigned int offset, length;	};
		
		// BSP header
		struct tBSPHeader {
			unsigned int version;
			tBSPLump dir[NUM_LUMPS];
		};
		
		// BSP Entity
		typedef unsigned char tBSPEntity;
		
		// BSP Planes
		struct tBSPPlane
		{
			float normal[3];
			float dist;						// Plane equation is: Normal * X = Dist
			enum
			{
				PLANE_X = 0,				// Plane is perpendicular to given axis
				PLANE_Y,
				PLANE_Z,
				PLANE_ANYX,					// Dominant axis (axis along which projection of normal has greatest magnitude)
				PLANE_ANYY,
				PLANE_ANYZ
			} type;
		};
		
		// BSP Mip-mapped Textures	...header
		struct tBSPTextureHeader {
			unsigned int numMiptex;
			unsigned int offset[4];
		};
		//							...body
		struct tBSPMiptex
		{
			char name[16];
			unsigned int width;
			unsigned int height;
			unsigned int offset[4];
		};		

		// BSP Vertices		
		struct tBSPVertices
		{
			float x, y, z;
		};
		
		// BSP Visibility
		typedef unsigned __int8 tBSPVisibility;
		
		// BSP Nodes
		struct tBSPNodes
		{
			unsigned short plane_idx;
			signed short children[2];
			signed short mins[3];
			signed short maxs[3];
			unsigned short firstface;
			unsigned short numfaces;
		};

		// BSP Texture Info
		struct tBSPTexinfo
		{
			float vecs[2][4]; // [s/t][x/y/z/offset]
			int miptex_idx;
			int flags;
		};
		
		// BSP Faces
		struct tBSPFaces
		{
			unsigned __int16 plane_idx;
			unsigned __int16 side;
			unsigned __int32 firstedge;
			unsigned __int16 numedges;
			unsigned __int16 texinfo;
			unsigned __int8 styles[4];
			unsigned __int32 light_offset;
		};

		// BSP Lightmaps
		struct tBSPLightmap {
			signed __int8 imageBits[128][128][3];
		};

		// BSP Leaves
		struct tBSPLeaf
		{
			signed int contents;
			signed int visofs;
			signed short mins[3];
			signed short maxs[3];
			unsigned short firstmarksurface;
			unsigned short nummarksurfaces;
			unsigned char ambient_level[4];
		};

		typedef unsigned short tBSPMarkedsurf;


		// BSP Clipping nodes
		struct tBSPClipnode
		{
			int plane_idx;
			short children[2];
		};
		
		// BSP Edges
		struct tBSPEdge
		{
			unsigned short v[2]; // indices numbers of the vertices bounding this edge
		};

		// BSP Surface Edges
		typedef signed int tBSPSurfedge;

		// BSP Models
		struct tBSPModels
		{
			float mins[3];
			float maxs[3];
			float origin[3];
			int headnode[4];
			int visleafs;
			int firstface;
			int numfaces;
		};
		
		// Header
		tBSPHeader head;
		
		// Entity List
		tBSPEntity *entity;
		
		//Planes
		unsigned int numPlanes;
		tBSPPlane *plane;
		
		//Texture
		tBSPTextureHeader textureheader;
		tBSPMiptex *miptex;
		
		//Vertices
		unsigned int numVertices;
		tBSPVertices *vertex;
		
		//Visibility
		unsigned int numClusters;
		tBSPVisibility *pvs;
		
		//Nodes
		unsigned int numNodes;
		tBSPNodes *node;
		
		//Leaves
		unsigned int numLeaves;
		tBSPLeaf *leaf;
		
		//Texinfo
		unsigned int numTextures;
		tBSPTexinfo *texture;
		
		//Faces
		unsigned int numFaces;
		tBSPFaces *face;
		
		//Lightmaps
		unsigned int numLightmaps;
		tBSPLightmap *lightmap;
		
		//Clipping nodes
		unsigned int numClipNodes;
		tBSPClipnode *clipnode;
		
		// Marked Surfaces
		unsigned int numMarkedsurfaces;
		tBSPMarkedsurf *markedsurf;
		
		//Edges
		unsigned int numEdges;
		tBSPEdge *edge;
		
		//Surface Edges
		unsigned int numSurfEdges;
		tBSPSurfedge *surfedge;
		
		//Models
		unsigned int numModels;
		tBSPModels *model;
This is what I have for rendering so far:
int BSPLeaf( bspFile info, glVector camera_pos )
{
	int index = 0;
	
	bspFile::tBSPNodes node;
	bspFile::tBSPPlane;
	
	float distance;
	
	while( index >= 0 ) {
	
		node = info.node[index];
		plane = info.plane[node.plane_idx];
		
		distance = dotproduct( glVector( plane.normal[0], plane.normal[1], plane.normal[2] ), camera_pos ) - plane.dist;
		
		if( distance >= 0 ) {
			index.node.children[0];
		} else {
			index.node.children[1];
		}
	}
	return -index - 1;
}

bool BSPClusterCompare( bspFile info, int visCluster, int testCluster )
{
	if( info.numClusters == NULL || visCluster < 0 ) return true;
	
	int i = (visCluster * 8) + (testcluster >> 3 );
	unsigned __int8 set = info.pvs;
	
	return (set & (1 << (testCluster & 7))) != 0;
}

void BSPRender( glPoint campos, bspFile info )
{
	std::set<int> alreadyvis;
	std::vector<int> visible;
	
	int camleaf = BSPLeaf( info, campos );
	int f;
	
	// Begin leaf iteration :)
	for( int l = 0; l < info.numLeaves; l++ ) {
		
		if( BSPClusterCompare( info, camleaf, info.leaf[l].visofs ) ) {
			
			for (int i = 0; i < leaf[l].numFaces; ++i) {
 				f = i + leaf[L].firstFace;
 				pair<iterator,bool> data = alreadyvis.insert( f );
    			if( data.second == true ) {
        			visible.append( f );
    			}
			}
		}
	}
	
	for( int v = 0; v < visible.size(); v++ ) {
		switch( info.face[ visible[v] ].type ) {
			case 1:		// Polygon
				break;
			case 2:		// Patch
				break;
			case 3:		// Meshes ???
				break;
			case 4:		// Billboard
				break;
		}
	}
}
Basically, I don't know how I would render any of them in any fashion - I'm fairly new to bsp trees and bsp30 files, so i'm not entirely sure. Any help would be appreciated Thanks, Oz~
Ozwald
Ozwald
I've found some bugs in my code, so i've recoded some of it

perhaps that would be more help

Data structures
#define _atosoft_bspfile_h_#include <cstdlib>#include <cstdio>#include <iostream>#include <vector>#include <fstream>// BSP-30 files contain these lumpsenum{	LUMP_ENTITIES = 0,	LUMP_PLANES,	LUMP_TEXTURES,	LUMP_VERTICES,	LUMP_VISIBILITY,	LUMP_NODES,	LUMP_TEXINFO,	LUMP_FACES,	LUMP_LIGHTING,	LUMP_CLIPNODES,	LUMP_LEAVES,	LUMP_MARKSURFACES,	LUMP_EDGES,	LUMP_SURFEDGES,	LUMP_MODELS,	NUM_LUMPS};namespace bsptype{		#pragma pack(4)		// BSP Lumps		struct tBSPLump {	unsigned int offset, length;	};				// BSP header		struct tBSPHeader {			unsigned int version;			tBSPLump dir[NUM_LUMPS];		};				// BSP Entity		typedef unsigned char tBSPEntity;				// BSP Planes		struct tBSPPlane		{			float normal[3];			float dist;						// Plane equation is: Normal * X = Dist			enum			{				PLANE_X = 0,				// Plane is perpendicular to given axis				PLANE_Y,				PLANE_Z,				PLANE_ANYX,					// Dominant axis (axis along which projection of normal has greatest magnitude)				PLANE_ANYY,				PLANE_ANYZ			} type;		};				// BSP Mip-mapped Textures	...header		struct tBSPTextureHeader {			unsigned int numMiptex;			unsigned int offset[1];		};		//							...body		struct tBSPMiptex		{			char name[16];			unsigned int width;			unsigned int height;			unsigned int offset[4];		};				// BSP Vertices				struct tBSPVertices		{			float x, y, z;		};				// BSP Visibility		typedef unsigned __int8 tBSPVisibility;				// BSP Nodes		struct tBSPNodes		{			unsigned short plane_idx;			signed short children[2];			signed short mins[3];			signed short maxs[3];			unsigned short firstface;			unsigned short numfaces;		};		// BSP Texture Info		struct tBSPTexinfo		{			float vecs[2][4]; // [s/t][x/y/z/offset]			int miptex_idx;			int flags;		};				// BSP Faces		struct tBSPFaces		{			unsigned __int16 plane_idx;			unsigned __int16 side;			unsigned __int32 firstedge;			unsigned __int16 numedges;			unsigned __int16 texinfo;			unsigned __int8 styles[4];			unsigned __int32 light_offset;		};		// BSP Lightmaps		struct tBSPLightmap {			signed __int8 imageBits[128][128][3];		};		// BSP Leaves		struct tBSPLeaf		{			signed int contents;			signed int visofs;			signed short mins[3];			signed short maxs[3];			unsigned short firstmarksurface;			unsigned short nummarksurfaces;			unsigned char ambient_level[4];		};		typedef unsigned short tBSPMarkedsurf;		// BSP Clipping nodes		struct tBSPClipnode		{			int plane_idx;			short children[2];		};				// BSP Edges		struct tBSPEdge		{			unsigned short v[2]; // indices numbers of the vertices bounding this edge		};		// BSP Surface Edges		typedef signed int tBSPSurfedge;		// BSP Models		struct tBSPModels		{			float mins[3];			float maxs[3];			float origin[3];			int headnode[4];			int visleafs;			int firstface;			int numfaces;		};				#pragma pack()};class bspFile{	public:		bspFile();		~bspFile();		FILE* bspfile;		bool bspLoad( const char* fname );				void *bspLump( bsptype::tBSPLump lump );		int bspElements( bsptype::tBSPLump lump, unsigned int typesize );				void bspUnload();		// Header		bsptype::tBSPHeader head;				// Entity List		bsptype::tBSPEntity *entity;				//Planes		unsigned int numPlanes;		bsptype::tBSPPlane *plane;				//Texture		bsptype::tBSPTextureHeader textureheader;		bsptype::tBSPMiptex *miptex;				//Vertices		unsigned int numVertices;		bsptype::tBSPVertices *vertex;				//Visibility		unsigned int numClusters;		bsptype::tBSPVisibility *pvs;				//Nodes		unsigned int numNodes;		bsptype::tBSPNodes *node;				//Leaves		unsigned int numLeaves;		bsptype::tBSPLeaf *leaf;				//Texinfo		unsigned int numTextures;		bsptype::tBSPTexinfo *texture;				//Faces		unsigned int numFaces;		bsptype::tBSPFaces *face;				//Lightmaps		unsigned int numLightmaps;		bsptype::tBSPLightmap *lightmap;				//Clipping nodes		unsigned int numClipNodes;		bsptype::tBSPClipnode *clipnode;				// Marked Surfaces		unsigned int numMarkedsurfaces;		bsptype::tBSPMarkedsurf *markedsurf;				//Edges		unsigned int numEdges;		bsptype::tBSPEdge *edge;				//Surface Edges		unsigned int numSurfEdges;		bsptype::tBSPSurfedge *surfedge;				//Models		unsigned int numModels;		bsptype::tBSPModels *model;		};#endif


And here is my fixed rendering code which still doesn't do much...

int BSPLeaf( bspFile info, glVector camera_pos ){	int index = 0;		bsptype::tBSPNodes node;	bsptype::tBSPPlane plane;		float distance;		while( index >= 0 ) {			node = info.node[index];		plane = info.plane[node.plane_idx];				distance = dotproduct( glVector( plane.normal[0], plane.normal[1], plane.normal[2] ), camera_pos ) - plane.dist;				if( distance >= 0 ) {			index = node.children[0];		} else {			index = node.children[1];		}	}	return -index - 1;}bool BSPClusterCompare( bspFile info, int visCluster, int testCluster ){	if( info.numClusters == 0 || visCluster < 0 ) return true;		int i = (visCluster * 8) + (testCluster >> 3 );	unsigned __int8 set = info.pvs;		return (set & (1 << (testCluster & 7))) != 0;}void BSPRender( glPoint campos, bspFile info ){	std::set<int> alreadyvis;	std::vector<int> visible;	bsptype::tBSPFaces *face;	int fid;	int vert;		int camleaf = BSPLeaf( info, glVector( campos.x, campos.y, campos.z ) );	int f;		// Begin leaf iteration :)	for( unsigned int l = 0; l < info.numLeaves; l++ ) {				if( BSPClusterCompare( info, camleaf, info.leaf[l].visofs ) ) {						for ( unsigned int i = 0; i < info.leaf[l].nummarksurfaces; i++ ) { 				f = i + info.leaf[l].firstmarksurface;    			if( alreadyvis.insert( f ).second == true ) {        			visible.push_back( f );    			}			}		}	}		for( unsigned int v = 0; v < visible.size(); v++ ) {		face = info.face;		fid = visible[v];		if( info.plane[ face[ fid ].plane_idx ] == 1) {						vert = face[ fid ].firstedge;			for( int edge = 0; edge < (face[ fid ].numedges / 3); edge+=3 ) {				glBegin( GL_TRIANGLES );					glVertex3f( info.vertex[ edge + vert + 0 ].x, info.vertex[ edge + vert + 0 ].y, info.vertex[ edge + vert + 0 ].z );					glVertex3f( info.vertex[ edge + vert + 1 ].x, info.vertex[ edge + vert + 1 ].y, info.vertex[ edge + vert + 1 ].z );					glVertex3f( info.vertex[ edge + vert + 2 ].x, info.vertex[ edge + vert + 2 ].y, info.vertex[ edge + vert + 2 ].z );				glEnd();			}					}	}}


Can anyone give me a hand at all?

Oz~
Ozwald
Ozwald
I've just gotten word that triangle strips might be helpful....any good places that I could learn about them?

Oz~

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.