It might help if you provide an example BSP file for someone to look at.
You'll need to figure out some way to test small bits of your process at a time so that you know you're heading in the right direction. Separate out loading the BSP from actually rendering it, since it's two different things. You'd want to make sure the data is at least mostly right before you attempt to render it.
The link you posted says that the first entry in the BSP file header is a long, but I don't know if that's Big Endian, Little Endian, or if it's a 4-byte long or an 8-byte long.
The Quake Wiki says that the version is 4 bytes long (0x1d, 0x00, 0x00, 0x00), which makes sense, so therefore I would use std::uint32 to store the version.
Furthermore, since the least-significant byte is at the beginning, that means it's little-endian.
https://quakewiki.org/wiki/Quake_BSP_Format
HOWEVER 0x1d is 29, not 17... so clearly the Quake Wiki is using a different version number.
Either way, you're going to want to open your BSP file in binary mode.
There's a short tutorial by Disch you can read here:
http://www.cplusplus.com/articles/DzywvCM9/
Since it's in little endian, you don't necessarily have to do the bit shifting yourself, but this
should be valid nonetheless:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
#include <cstdint>
#include <iostream>
#include <fstream>
using u32 = std::uint32_t;
using u8 = std::uint8_t;
typedef struct // A Directory entry
{ u32 offset; // Offset to entry, in bytes, from start of file
u32 size; // Size of entry in file, in bytes
} dentry_t;
typedef struct // The BSP file header
{ u32 version; // Model version, must be 0x17 (23).
dentry_t entities; // List of Entities.
dentry_t planes; // Map Planes.
// numplanes = size/sizeof(plane_t)
dentry_t miptex; // Wall Textures.
dentry_t vertices; // Map Vertices.
// numvertices = size/sizeof(vertex_t)
dentry_t visilist; // Leaves Visibility lists.
dentry_t nodes; // BSP Nodes.
// numnodes = size/sizeof(node_t)
dentry_t surfaces; // Map Surfaces.
// numsurfaces = size/sizeof(surface_t)
dentry_t lightmaps; // Wall Light Maps.
dentry_t boundnodes; // BSP bound nodes, for Hulls.
// numbounds = size/sizeof(hullbound_t)
dentry_t leaves; // BSP Leaves.
// numlaves = size/sizeof(leaf_t)
dentry_t lstsurf; // List of Surfaces.
dentry_t edges; // Original surface Edges.
// numedges = Size/sizeof(edge_t)
dentry_t lstedges; // List of surfaces Edges.
dentry_t hulls; // List of Hulls.
// numhulls = Size/sizeof(hull_t)
} dheader_t;
u32 read_u32_le(std::istream& file)
{
u32 val;
u8 bytes[4];
// read 4 bytes from the file
file.read((char*)bytes, 4);
// construct the 32-bit value from those bytes
val = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
return val;
}
int main()
{
std::ifstream fin("test.bsp");
dheader_t bsp_header;
bsp_header.version = read_u32_le(fin);
std::cout << bsp_header.version << '\n'; // Does this print 17 for you?
}
| |
Test it yourself to see if it prints 17. I don't have a file to test.