Sign in to follow this  
Ozwald

BSP30 rendering

Recommended Posts

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[i];
	
	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~

Share this post


Link to post
Share on other sites
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 lumps
enum
{
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[i];

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~

Share this post


Link to post
Share on other sites
I've just gotten word that triangle strips might be helpful....any good places that I could learn about them?

Oz~

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this