• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# rendering Quake 3 bsp geometry

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

No replies to this topic

### #1Noah2033  Members

Posted 13 April 2013 - 05:43 PM

I have been working on rendering Quake 3 bsp maps for awhile but I cant get the faces to render correctly

http://postimg.org/image/o2lf8vlp9/ Here are the vertices for a map

and here's what happens when I render faces on a map

http://postimg.org/image/6hmoht7ep/

here's the code

#include <stdio.h>
#include <cstdio>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <GL/GL.h>
#include <SDL/SDL.h>
#include <assert.h>

using namespace std;

int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;
int SCREEN_BPP = 24;
bool running = true;
bool lightmaps;
SDL_Event event;

#define MAX_BRUSHES     10000
#define MAX_FACES       10000
#define MAX_VERTS       10000000
#define MAX_TEXTURES    1000
#define MAX_LEAFFACES   65536

struct pos
{
float x;
float y;
float z;
};

struct bspface
{
int   textureid;        // The index into the texture array
int   effect;           // The index for the effects (or -1 = n/a)
int   type;             // 1=polygon, 2=patch, 3=mesh, 4=billboard
int   vertexindex;      // The index into this face's first vertex
int   numofverts;       // The number of vertices for this face
int   meshvertindex;    // The index into the first meshvertex
int   nummeshverts;     // The number of mesh vertices
int   lightmapid;       // The texture index for the lightmap
int   lmapcorner[2];    // The face's lightmap corner in the image
int   lmapsize[2];      // The size of the lightmap section
float lmappos[3];     // The 3D origin of lightmap.
float lmapbitsets[2][3]; // The 3D space for s and t unit vectors.
float vnormal[3];     // The face normal.
int   size[2];          // The bezier patch dimensions.
};

struct bspvertex
{
pos position;      //x y z
float texturecoord[2];  //u, v texture coordinate
float lightmapcoord[2]; //u, v lightmap coordinate
float normal[3];        //x, y, z normalized vector
char  color[4];         //RGBA color for the vertex
};

struct bsptexture
{
char name[64];      // The name of the texture w/o the extension
int flags;          // The surface flags (unknown)
int contents;       // The content flags (unknown)
};

struct bspbrush
{
int brushSide;           // The starting brush side for the brush
int numofbrushsides;     // Number of brush sides for the brush
int textureid;           // The texture index for the brush
};

struct bsplump
{
int offset;
int length;
};

class bsp
{
public:
ifstream    bspfile;
bsplump     lumps[16];
char        entities[10000];
bspvertex   vertices[MAX_VERTS];
bspface     faces[MAX_FACES];
bsptexture  textures[MAX_TEXTURES];
bspbrush    brushs[MAX_BRUSHES];
int         faceindex[MAX_LEAFFACES];
void render();
};

{
bsp::bspfile.open (name.c_str(), istream::binary);
if(bsp::bspfile == NULL)
cout << "ERROR: No file named \""<< name <<"\" found" << endl;
else
{
char magic[64];                 //Number used in Quake 3 BSP header
bsp::bspfile.read(magic, 4);    //Read the magic number in the header of the BSP file it should be "IBSP"
if((magic[0] != 'I')||(magic[1] != 'B')||(magic[2] != 'S')||(magic[3] != 'P'))
{
cout << "ERROR: Not a valid Quake 3 BSP file" << endl;
}
else
{
int version;
char vbuffer[4];
for (int k = 0; k <= 3; k++)
{
((char*)&version)[k] = vbuffer[k];
}

if(version != 46)//46 = 0x2e in hexidecimal
cout << "ERROR: Unknown version of Quake 3 BSP" << endl;
else
{
for (int i = 0; i <= 16; i++)
{
char lumpoffset[4];
char lumplength[4];

for (int k = 0; k <= 3; k++)
{
((char*)&bsp::lumps[i].offset)[k] = lumpoffset[k];
}

for (int k = 0; k <= 3; k++)
{
((char*)&bsp::lumps[i].length)[k] = lumplength[k];
}

cout << "Lump " << i << " offset is " << bsp::lumps[i].offset << endl
<< "Lump " << i << " length is " << bsp::lumps[i].length << endl << endl;
}

bsp::bspfile.seekg (bsp::lumps[0].offset, ios::beg);

bsp::bspfile.seekg (bsp::lumps[1].offset, ios::beg);
for (int j = 0; j <= bsp::lumps[1].length/sizeof(bsptexture); j++) //Read until end of lump
{
char buffer[72];

for (int k = 0; k <= 71; k++)//Read until end of lump
{
((char*)&bsp::textures[j])[k] = buffer[k];
}
}

bsp::bspfile.seekg (bsp::lumps[5].offset, ios::beg);
for (int j = 0; j <= bsp::lumps[5].length/sizeof(bspvertex); j++) //Read until end of lump
{
char buffer[4];                 //create buffer for Leaffaces
for (int k = 0; k <= 3; k++)    //Read until end of lump
{
((char*)&bsp::faceindex[j])[k] = buffer[k];
}
}

bsp::bspfile.seekg (bsp::lumps[10].offset, ios::beg); //Load vertex data from vertex lump (10)
for (int j = 0; j <= bsp::lumps[10].length/sizeof(bspvertex); j++)//Read until end of lump
{
char buffer[44];           //create buffer for verts
for (int k = 0; k <= 43; k++)//Read until end of lump
{
((char*)&bsp::vertices[j])[k] = buffer[k];
}
}

bsp::bspfile.seekg (bsp::lumps[13].offset, ios::beg); //Load face data from face lump (13)
for (int j = 0; j <= bsp::lumps[13].length/sizeof(bspface); j++)//Read until end of lump
{
char buffer[104];                 //create buffer for faces
for (int k = 0; k <= 103; k++)    //Read until end of lump
{
((char*)&bsp::faces[j])[k] = buffer[k];
}
}
}
}

}
}
void bsp::render()
{
for (int j = 0; j <= bsp::lumps[13].length/sizeof(bspface); j++)//Read until end of lump
{
if ((bsp::faces[j].type == 1)||(bsp::faces[j].type == 3))       // 1=polygon, 2=patch, 3=mesh, 4=billboard
{
glFrontFace(GL_CW);
glBegin(GL_TRIANGLE_STRIP);
for (int k = 0; k <=  bsp::faces[j].numofverts - 1; k++)//Read until end of lump
{
glVertex3f(bsp::vertices[bsp::faces[j].vertexindex+k].position.x, bsp::vertices[bsp::faces[j].vertexindex+k].position.y, bsp::vertices[bsp::faces[j].vertexindex+k].position.z);
}
glEnd();
}
}
}

bsp bspbuffer;

bool initGL()
{
//Initialize Projection Matrix
glMatrixMode( GL_PROJECTION );
//Initialize Modelview Matrix
glMatrixMode( GL_MODELVIEW );
//Initialize clear color
glClearColor( 0.f, 0.f, 0.f, 1.f );
//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
return true;
}

float angle;

void render()
{
angle = angle + 1;
glPushMatrix();
//Clear color buffer
glClear( GL_COLOR_BUFFER_BIT );
glPointSize(5.0);
glRotatef(angle,1,1,1);
glScalef(.002,.002,.002);
bspbuffer.render();
//Update screen
glPopMatrix();
SDL_GL_SwapBuffers();

//While there are events to handle
while( SDL_PollEvent( &event ) )
{
if(event.type == SDL_QUIT)
{
running = false;
exit(0);
}
}
SDL_Delay( 1000 / 30 );
}

bool init()
{
//Initialize SDL
if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
{
return false;
}
//Create Window
if( SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL ) == NULL )
{
return false;
}
//Initialize OpenGL
if( initGL() == false )
{
return false;
}
//Set caption
SDL_WM_SetCaption( "OpenGL BSP", NULL );
return true;
}

#undef main

int main()
{
init();
do
{
render();
}while(running);
return 0;
}


any help would be appreciated

Edited by industrialgrok, 13 April 2013 - 09:21 PM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.