Jump to content
  • Advertisement
Sign in to follow this  
crippeli

Quake 3 BSP problem

This topic is 4799 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello chaps. I'm having trouble loading a quake 3 bsp file. The Meshvertex index-values are "weird", or at least the first 50 or so. Anyway this causes my application to segfault. This is how I read in the indices: fseek(bspFile, Lumps[MESHVERTS].Offset, SEEK_SET); fread(MeshVertices, sizeof(int), NumMeshVertices, bspFile); MeshVertices is an array of ints. My program crashes when it's time to render using these indices, so i thought i'd write them to my logfile and see what's up. It turns out the first 48 of the values are either 1098907648 or 0. The rest is useable index-data. (Tried to render a couple of faces into the face-array, and it looked as it should). So, any ideas? I've tried with several different bsp files with the same result. /Crippeli

Share this post


Link to post
Share on other sites
Advertisement
Are you rendering the meshverts array directly? You shouldn't do that, instead use the first model in the Models array. Go through the faces starting with the first face in the model. In the face is an index into the meshverts array. Also note that the meshverts are not indices into the vertex array, but offsets from the first vertex in the face. So, to get the correct vertex do something like


for( int32 i = face.index; i < face.index + face.index_count; ++i ) {
int32 index = face.vertex + MeshVerts;
Vertex v = Vertices[index];
}



Sorry if you already know all this [smile]

Share this post


Link to post
Share on other sites
Yeah, i've already got that covered. :)

I'm using vertex arrays with glDrawElements to draw the faces.

Example:


glVertexPointer(3, GL_FLOAT, sizeof(BspVertex_t),&(Vertices[Faces.VertexIndex].Point));

glDrawElements(GL_TRIANGLES, Faces.NumMeshVerts, GL_UNSIGNED_INT, &MeshVertices[Faces.MeshVertIndex]);




But i'm still curious about these faulty values. The lump's offset is relative to the beginning of the file right? Not the beginning of file + header-size + directory entries (lump info)?

It seems to me that my problem has something to do with reading the index data from file.

/Crippeli

Share this post


Link to post
Share on other sites
Hmm, I tried looking at the meshverts values I read (from q3dm18.bsp) and I don't get the values you describe.

I use the following code to read all lumps:


template<typename T>
void read( const DirEntries& dir_entry, std::vector<T>& list ) {
uint32 count = Header_.dir[dir_entry].length / sizeof( T );
T* ptr = new T[count];
assert( ptr );

seek( Header_.dir[dir_entry] );
read( ptr, sizeof( T ) * count );
fill( list, ptr, count );

SUCL::safe_delete_array( ptr );
}

template<typename T>
void fill( std::vector<T>& list, T* src, uint32 count ) const {
list.clear();
for( uint32 i = 0; i < count; ++i )
list.push_back( src );
}

void read( void* ptr, std::streamsize size ) { Input_.read( (char*)ptr, size ); }
void seek( const BSP::DirEntry& dir_entry ) { Input_.seekg( dir_entry.offset, std::ios_base::beg ); }

std::ifstream Input_;



I can't comment on the rendering code, I use DirectX.

Share this post


Link to post
Share on other sites
Hmm, you seem to read the data from the same place as I do. Only with other methods.

As for my rendering code, it works if I skip the first 20 faces, since they use indices in the beginning of the meshvert indices-array (which are bad for some reason).

Share this post


Link to post
Share on other sites
Are you sure your value in Lumps[MESHVERTS].Offset is correct?

i'm assuming you have MESHVERTS set to 11 and have a couple of structures something like this

typedef struct {

char acMagic[4]; /* always "IBSP" */
int iVersion; /* always 0x2E for Quake 3 BSP files */

} __attribute__((packed)) BSPHeader;

typedef struct {

int iOffset; /* offset to start of lump, relative to beginning of
* file
*/
int iLength; /* length of lump.*/

} __attribute__((packed)) BSPLump;

and reading from the BSP something like this?

/* read the header information from the file, to make sure this is a
* BSP file */
fread( &header, sizeof( BSPHeader ),1, pFile );

/* check this is a BSP file by comparing the magic in the header to what
* we expect */
if( memcmp( header.acMagic, "IBSP", 4 ) != 0 ) {
fclose( pFile );
return false;
}

/* read lump information from the file */
fread( &lumps, sizeof( BSPLump ),17, pFile );


you could be experiencing padding problems?

my 2c :)

Share this post


Link to post
Share on other sites
Yes, that's basically how i've set it up. :)

I got it to work now, i had forgotten to check the face type before rendering.
Now rendering is only performed if the face type is 1 or 3 (polygon or mesh).

But this working might only be a coincidence. I doubt that the beginning of the meshvertex index-array is stuffed with unusable index values just because they aren't supposed to be used by any faces.

What do you mean by padding problems? :)

/Crippeli

Share this post


Link to post
Share on other sites
padding problems, alignment problems?

sometimes the compiler adds extra bytes into structures to
keep the data aligned on say the 32bit boundry (depends on processor).

if you use sizeof then you may get values higher than expected
and as a result read in too many bytes from the file.

typedef struct {

unsigned short int a;
unsigned int b;
unsigned short int c;
unsigned short int d;
unsigned int e;

} Tfoo;

i.e this structure will be 14 but may return 16 as a result from a sizeof :)

just one of the nasty gotyah's :)

Share this post


Link to post
Share on other sites
Yes, that's how I do it.

About this alignment-problem. This is an optimization feature right? Good data-alignment = fewer cycles for read/write?

Can I turn it off by setting the optimization level to none? Or is there a flag I can pass to gcc? Just to see if this is what's causing my problem.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!