Ok, so for the past week ive been working on a Quake 3 bsp veiwer this is what I have finished already
//standard librarys
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include "sys_mem.h"
using namespace std;
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32
#define MAX_FACES 10000
#define MAX_VERTS 100000
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[1]; // The face's lightmap corner in the image
int lMapSize[1]; // The size of the lightmap section
float lMapPos[2]; // The 3D origin of lightmap.
float lMapBitsets[1][2]; // The 3D space for s and t unit vectors.
float vNormal[2]; // The face normal.
int size[1]; // The bezier patch dimensions.
};
//
struct bspvertex
{
float position[2]; //x y z
float texturecoord[1]; //u, v texture coordinate
float lightmapcoord[1]; //u, v lightmap coordinate
float normal[2]; //x, y, z normalized vector
char color[3]; //RGBA color for the vertex //char = byte?
};
struct bsplump
{
int offset;
int length;
};
struct bsp
{
bsplump lumps[16];
bspvertex vertices[MAX_VERTS];
bspface faces[MAX_FACES];
};
bsp bspbuffer;
bool running = true; //if renderer is running
bool lightmaps;
void loadbsp(string); //prototype
void init()
{
glClearColor(0.0,0.0,0.0,1.0); //Background color
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //Reset
gluPerspective(45,640.0/480.0,1.0,500.0); //Perspective
glMatrixMode(GL_MODELVIEW);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable( GL_BLEND );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_COLOR_MATERIAL);
float light_0_amb[] = {0.2f, 0.2, 0.2};
glLightfv(GL_LIGHT0,GL_AMBIENT, light_0_amb);
float light_0_pos[] = {1.0,3.0,1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_0_pos);
float light_0_dif[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_0_dif);
float light_0_spec[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, light_0_spec);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glFlush();
glLoadIdentity();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //OpenGL's texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//RENDERLOOP
SDL_GL_SwapBuffers();
}
int main(int argc, char *argv[])
{
if(argv[1] == NULL)
cout << "ERROR: No bsp file used as an argument example \"./bsploader.x86 -map.bsp\"" << endl;
else
{
/*tolkenize argument*/
istringstream namebuffer(argv[1]); //zero is ./bsploader
while (!namebuffer.eof())
{
string tolken; //tolken buffer
getline(namebuffer, tolken, '-' ); //split and store in tolken buffer
if(tolken != "")
{
loadbsp(tolken);
}
}
do
{
SDL_Surface* screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE|SDL_OPENGL);
//Window //Tab
SDL_WM_SetCaption( "BSPloader","BSPloader");
Uint32 start;
init();
display();
SDL_Delay(1000/30);
}while(running);
}
return 0;
}
void loadbsp(string name)
{
cout << "Loading BSP \"" << name << "\"" << endl;
ifstream bspfile;
bspfile.open (name.c_str(),ios::in|ios::binary);//Load BSP file into memory
if(bspfile == NULL)
cout << "ERROR: No file named \""<< name <<"\" found" << endl;
else
{
char magic[64]; //Number used in BSP header
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;
version = readInt(bspfile);
if(version != 46)//46 = 0x2e in hexidecimal
cout << "ERROR: Unknown version of Quake 3 BSP" << endl;
else
{
for (int i = 0; i <= 16; i++)
{
bspbuffer.lumps[i].offset = readInt(bspfile);
bspbuffer.lumps[i].length = readInt(bspfile);
cout << "Lump " << i << " offset is " << bspbuffer.lumps[i].offset << endl
<< "Lump " << i << " length is " << bspbuffer.lumps[i].length << endl << endl;
}
//Load vertices
bspfile.seekg (bspbuffer.lumps[10].offset, ios::beg); //Load vertex data from vertex lump (10)
long readmemory = 0;
cout << "Loading";
for (int j = 0; readmemory <= bspbuffer.lumps[10].length; j++)//Read until end of lump
{
//Actual vertexes
bspbuffer.vertices[j].position[0] = readFloat(bspfile);
bspbuffer.vertices[j].position[1] = readFloat(bspfile);
bspbuffer.vertices[j].position[2] = readFloat(bspfile);
//U,V coordinates
bspbuffer.vertices[j].texturecoord[0] = readFloat(bspfile);
bspbuffer.vertices[j].texturecoord[1] = readFloat(bspfile);
//Lightmap U,V coordinates
bspbuffer.vertices[j].lightmapcoord[0] = readFloat(bspfile);
bspbuffer.vertices[j].lightmapcoord[1] = readFloat(bspfile);
//Normalized vertex coordinates
bspbuffer.vertices[j].position[0] = readFloat(bspfile);
bspbuffer.vertices[j].position[1] = readFloat(bspfile);
bspbuffer.vertices[j].position[2] = readFloat(bspfile);
char buffer[64];
bspfile.read(buffer, 4); //Read RGBA color index
bspbuffer.vertices[j].color[0] = buffer[0];
bspbuffer.vertices[j].color[1] = buffer[1];
bspbuffer.vertices[j].color[2] = buffer[2];
bspbuffer.vertices[j].color[3] = buffer[3];
//10 floats 4 char so 10(4) + 4(1)
readmemory = readmemory + 44;
cout << ".";
}
bspfile.seekg (bspbuffer.lumps[13].offset, ios::beg); //Load face data from vertex lump (13)
long readmemory2 = 0;
cout << "Loading";
for (int b = 0; readmemory2 <= bspbuffer.lumps[13].length; b++)//Read until end of lump
{
bspbuffer.faces[b].textureID = readInt(bspfile); // The index into the texture array
bspbuffer.faces[b].effect = readInt(bspfile); // The index for the effects (or -1 = n/a)
bspbuffer.faces[b].type = readInt(bspfile); // 1=polygon, 2=patch, 3=mesh, 4=billboard
bspbuffer.faces[b].vertexIndex = readInt(bspfile); // The index into this face's first vertex
cout << bspbuffer.faces[b].vertexIndex << endl;
bspbuffer.faces[b].numOfVerts = readInt(bspfile); // The number of vertices for this face
bspbuffer.faces[b].meshVertIndex = readInt(bspfile); // The index into the first meshvertex
bspbuffer.faces[b].numMeshVerts = readInt(bspfile); // The number of mesh vertices
bspbuffer.faces[b].lightmapID = readInt(bspfile); // The texture index for the lightmap
bspbuffer.faces[b].lMapCorner[0] = readInt(bspfile); // The face's lightmap corner in the image
bspbuffer.faces[b].lMapCorner[1] = readInt(bspfile); // The face's lightmap corner in the image
bspbuffer.faces[b].lMapSize[0] = readInt(bspfile); // The size of the lightmap section
bspbuffer.faces[b].lMapSize[1] = readInt(bspfile); // The size of the lightmap section
bspbuffer.faces[b].lMapPos[0] = readFloat(bspfile); // The 3D origin of lightmap.
bspbuffer.faces[b].lMapPos[1] = readFloat(bspfile); // The 3D origin of lightmap.
bspbuffer.faces[b].lMapPos[2] = readFloat(bspfile); // The 3D origin of lightmap.
bspbuffer.faces[b].lMapBitsets[0][0] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].lMapBitsets[0][1] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].lMapBitsets[0][2] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].lMapBitsets[1][0] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].lMapBitsets[1][1] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].lMapBitsets[1][2] = readFloat(bspfile); // The 3D space for s and t unit vectors.
bspbuffer.faces[b].vNormal[0] = readFloat(bspfile); // The face normal.
bspbuffer.faces[b].vNormal[1] = readFloat(bspfile); // The face normal.
bspbuffer.faces[b].vNormal[2] = readFloat(bspfile); // The face normal.
bspbuffer.faces[b].size[0] = readInt(bspfile); // The bezier patch dimensions.
bspbuffer.faces[b].size[1] = readInt(bspfile); // The bezier patch dimensions.
//26(4)
readmemory2 = readmemory2 + 104;
}
cout << "Loaded" << endl;
}
}
}
}
the vertex information is mostly gibberish (as that two of the values are zero) Im aware that you have to use vertexIndex for the first vertex and put them into a triangle fan, but how?