C++ BinaryReader?

Started by
17 comments, last by Ectara 11 years, 11 months ago
Ok ive just used your code, the result is different but still not correct, also it froze my laptop :D, here is the output i get with your code implemented


Bad Version or identifier

157955018
0

which still isnt correct :(
Advertisement
If you open the file in a hex editor, does it actually show the bytes you expect to see?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

k the first line in the lara_head.MD3 in hex is this
49 44 50 33 0F 00 00 00 00 00 00 00 00 00 00 00 00 = IDP3 which is correct
but in my program it comes up with nothing :D,

still just doesnt seem to read the file correctly, or my header isnt correct, but it matchs many other peoples headers out there,
Can you post your complete code as it stands now?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Before spending an endless amount of time debugging the read call:

Did you check your stream after opening it? If it fails to find/open the file in the first place, everything after that can't work.

Did you use gcount after read to see how much data you REALLY read into your struct?

Did you at any point consider to initialize your struct to all 0 to tell the difference between "reading wrong data" and "reading no data and having random uninitialized garbage in your struct"?
f@dzhttp://festini.device-zero.de
You should really learn some basic C++ before you continue. The mistakes you're making are all quite trivial ones, and demonstrate a notable lack of understanding of pointers and basic C++ good practices.

Below is a snippet of working code that should get you started. Do try and read up on the bits and pieces you don't understand, instead of just copying and pasting and hoping it works.



#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <iterator>

struct MD3Vec3 {
float x, y, z;
};

struct MD3Header {
int32_t ident;
int32_t version;
char name[64];
int32_t flags;
int32_t num_frames;
int32_t num_tags;
int32_t num_surfaces;
int32_t num_skins;
int32_t ofs_frames;
int32_t ofs_tags;
int32_t ofs_surfaces;
int32_t ofs_eof;
};

struct MD3Frame
{
MD3Vec3 min_bounds;
MD3Vec3 max_bounds;
MD3Vec3 local_origin;
float radius;
char name[16];
};

struct MD3Tag {
char name[64];
MD3Vec3 origin;
MD3Vec3 axis[3];
};

int main() {
std::ifstream fin("../test.md3", std::ios::binary | std::ios::in);
auto data = std::vector<char>(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());

MD3Header* header = reinterpret_cast<MD3Header*>(&data.front());

std::cout<<std::hex<<header->ident<<std::endl;

for(int32_t i = 0; i < header->num_frames; ++i) {
MD3Frame* frame = reinterpret_cast<MD3Frame*>(&data.front() + header->ofs_frames) + i;
std::cout<<frame->name<<std::endl;
}
}

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Cheers Washu, I have a lesson soon so i wont be able to check your code until 1english time smile.png, Sorry about the lack of knowledge, it does come in time tho smile.png

Also here is my header and cpp file before i edit it with washu's code

Md3Asset.cpp

#include "Md3Asset.h"
Md3Asset::Md3Asset(const string &filename) {
import_md3_asset(filename);
// make the objects to display
if(0 == make_resources()) {
cout << "Can't make the required OpenGL resources for Md2Asset." << endl;
// TODO: exit nicely here
}
}
Md3Asset::~Md3Asset() {
// TODO: clean up
}
void Md3Asset::update() {
}
void Md3Asset::import_md3_asset(const string &filename) {
/*ifstream md3file(filename, ios::in|ios::binary);
//md3file.open(filename.c_str(), ios::in|ios::binary|ios::ate|ios_base::binary);
// C stuff
md3_header * md3Header = (struct md3_header *)
malloc(sizeof(struct md3_header));//Malloc seems to read the data correctly
//new vector<int>(sizeof(struct md3_header));
// it involves evil casting.*/
//ifstream is input stream, ofstream is output stream
//fstream is input&output
fstream md3file;
//ios::in = open for input mode
//ios::binary = opens the file in binary mode
md3file.open(filename.c_str(), ios::in | ios::binary | ios::ate);
md3_header md3Header;
md3file.read(reinterpret_cast<char *>(&md3Header), sizeof(md3_header));
if((md3Header.ident != 860898377)||(md3Header.version !=15)
||((md3Header.fileID[0] != 'I')
||(md3Header.fileID[1] != 'D')
||(md3Header.fileID[2] != 'P')
||(md3Header.fileID[3] != '3')))
{
cout<<"Bad Version or identifier"<<endl;
cout << md3Header.fileID[0] << md3Header.fileID[1] <<
md3Header.fileID[2] << md3Header.fileID[3] << endl;
cout << md3Header.version << endl;
cout << md3Header.ident << endl;
}
md3file.close();
}


Md3Asset.h

#include <GL/glew.h>
#include <GL/gl.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "GameAsset.h"
using namespace std;
#ifndef MD3ASSET_H_
#define MD3ASSET_H_
class Md3Asset : public GameAsset {
public:
Md3Asset(const string &filename);
virtual ~Md3Asset();
virtual void update();
private:
void import_md3_asset(const string &filename);
//May need this
typedef float vec3[3];
struct md3_header
{
char fileID[4]; //Stores the file IDs
int ident; //Stores the identity
int version; //Stores the version, Must be 15
char name[64]; //Stores the name of the file
int flags; //Stores the flags
int num_frames; //Stores number of frames
int num_tags; //Stores number of tags
int num_surfaces; //Stores number of surfaces
int num_skins; //Stores number of skins
int ofs_frames; //Stores offset number of frames
int ofs_tags; //Stores offset number of tags
int ofs_surfaces; //Stores offset number of surfaces
int ofs_eof; //Stores offset end and finish???
};
struct md3_frame
{
float min_bounds[3]; //Min (x,y,z) value for the frame
float max_bounds[3]; //Max (x,y,a) value for the frame
float local_origin[3]; //Stores the frame position
float radius; //Scale/Radius of the frame
char name[16]; //Modeler used to create the loaded model
};
struct md3_tag
{
char name[64]; //Stores the name of the tag
Vector3 origin; //Stores the translation that should be performed
Vector3 axis[3][3]; //Stores the 3x3 rotation matrix for this frame
};
struct md3_surface
{
int ident; //Stores the identity
char name[64]; //Stores the surface name
int flags; //Stores the flags
int num_frames; //Stores the number of frames
int num_shaders; //Stores the number of shaders
int num_verts; //Stores the number of vertices
int num_triangles; //Stores the number of triangles
int ofs_triangles; //Stores the offset triangles
int ofs_shaders; //Stores the offset shaders
int ofs_ST; //Stores the offset starts
int ofs_xyzNormal; //Stores the offset starting positions
int ofs_end; //Stores the offset surface ends
};
struct md3_shader
{
char name[64]; //Stores the file name
int shader_index; //Stores the shader index number
};
struct md3_triangle
{
int indexes[3]; //Stores a list of offset values for Vertex
};
struct md3_texCoord
{
float st[3]; //Stores s & t texture coordinates
};
struct md3_vertex
{
short coord[3]; //x,y,z coordinates in right-handed 3-space
short normal; //Stores angles
};
md3_frame *md3Frame;
md3_tag *md3Tag;
md3_surface *md3Surface;
md3_shader *md3Shader;
md3_triangle *md3Triangle;
md3_texCoord *md3TexCords;
md3_vertex *md3Vertex;
};
#endif


Thats my code at the moment which will change soonish
Ok Washu i have added your code and im getting a error

Here is my Md3Asset.cpp file

#include "Md3Asset.h"
Md3Asset::Md3Asset(const string &filename) {
import_md3_asset(filename);
// make the objects to display
if(0 == make_resources()) {
cout << "Can't make the required OpenGL resources for Md3Asset." << endl;
// TODO: exit nicely here
}
}
Md3Asset::Md3Asset(){}
Md3Asset::~Md3Asset() {
// TODO: clean up
}
void Md3Asset::update() {
}
void Md3Asset::import_md3_asset(const string &filename) {
std::ifstream fin("../lara_head.MD3", std::ios::binary | std::ios::in);
auto data = std::vector<char>(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());
md3_header* header = reinterpret_cast<MD3Header*>(&data.front()); //LINE WONT COMPILE
std::cout<<std::hex<<header->ident<<std::endl;
for(int32_t i = 0; i < header->num_frames; ++i) {
md3_frame* frame = reinterpret_cast<md3_frame*>(&data.front() + header->ofs_frames) + i;
std::cout<<frame->name<<std::endl;
}

};


and this is my header
Md3Asset.h

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <iterator>
#include "GameAsset.h"
using namespace std;
#ifndef MD3ASSET_H_
#define MD3ASSET_H_
class Md3Asset : public GameAsset {
public :
Md3Asset();
Md3Asset(const string &filename);
virtual ~Md3Asset();
virtual void update();
private:
void import_md3_asset(const string &filename);
struct Vec3 {
float x, y, z;
};
struct md3_header {
int32_t ident;
int32_t version;
char name[64];
int32_t flags;
int32_t num_frames;
int32_t num_tags;
int32_t num_surfaces;
int32_t num_skins;
int32_t ofs_frames;
int32_t ofs_tags;
int32_t ofs_surfaces;
int32_t ofs_eof;
};
struct md3_frame
{
Vec3 min_bounds;
Vec3 max_bounds;
Vec3 local_origin;
float radius;
char name[16];
};
struct md3_tag {
char name[64];
Vec3 origin;
Vec3 axis[3][3];
};
struct md3_surface
{
int32_t ident; //Stores the identity
char name[64]; //Stores the surface name
int32_t flags; //Stores the flags
int32_t num_frames; //Stores the number of frames
int32_t num_shaders; //Stores the number of shaders
int32_t num_verts; //Stores the number of vertices
int32_t num_triangles; //Stores the number of triangles
int32_t ofs_triangles; //Stores the offset triangles
int32_t ofs_shaders; //Stores the offset shaders
int32_t ofs_ST; //Stores the offset starts
int32_t ofs_xyzNormal; //Stores the offset starting positions
int32_t ofs_end; //Stores the offset surface ends
};
struct md3_shader
{
char name[64]; //Stores the file name
int32_t shader_index; //Stores the shader index number
};
struct md3_triangle
{
int32_t indexes[3]; //Stores a list of offset values for Vertex
};
struct md3_texCoord
{
float st[3]; //Stores s & t texture coordinates
};
struct md3_vertex
{
short coord[3]; //x,y,z coordinates in right-handed 3-space
short normal; //Stores angles
};
};
#endif


Its ok i have changed the line and the code is compiling BUT, when i click build, it builds it then displays a box for a split second and then just dissappears... I now put the load line as this

std::ifstream fin("data/lara/lara_head.MD3", std::ios::binary | std::ios::in);

and i now get this but still closes
33504449
(from 3DSMax)
Just a quick check before we go further, the endianness of the file does match that of your machine, right?

This topic is closed to new replies.

Advertisement