Save openGL objects to file

Started by
22 comments, last by swiftcoder 11 years, 6 months ago
first thing do not use constructor in structure you want to save(ermove it) sec problem is you are not saving any vertices at all you haven't defined them glutSolidCube(2); will not define the vertices you want to save , last thing you are not saving verts in a function!!!! dude create a function that save verts, place structures in a header so it should be like this:

void saveverts()
{

FILE* f = fopen("vertices.txt","wb+");

fwrite(&header,sizeof(THeader),1,f);
rest of code

}
i am not a fairy please write an error you get
and you have
#include
#include
#include incldue what????


maybe you should start learn how to write programs, as far i can see you have no idea what you are doing
Advertisement
Sorry about not reporting the errors.
About the missing #includes that is a problem when pasting
but the three libraries iam using are:
#include <GL/freeglut.h>
#include <iostream>
#include <stdio>
Here is the full error list i will try implement your suggestions. Cheers

[source lang="cpp"]shapes.cpp:168: error: expected constructor, destructor, or type conversion before '*' token

shapes.cpp:168: error: expected `,' or `;' before '*' token
shapes.cpp:170: error: expected constructor, destructor, or type conversion before '(' token
shapes.cpp:170: error: expected `,' or `;' before '(' token
shapes.cpp:174: error: expected unqualified-id before "for"
shapes.cpp:174: error: expected `,' or `;' before "for"
shapes.cpp:174: error: expected constructor, destructor, or type conversion before '<' token
shapes.cpp:174: error: expected `,' or `;' before '<' token
shapes.cpp:174: error: expected constructor, destructor, or type conversion before '++' token
shapes.cpp:174: error: expected `,' or `;' before '++' token
shapes.cpp:175: error: expected constructor, destructor, or type conversion before '(' token
shapes.cpp:175: error: expected `,' or `;' before '(' token

make.exe: *** [shapes.o] Error 1

Execution terminated[/source]

Here is the source code cube with vertices defined(without the changes reccomended)

[source lang="cpp"]

#include <GL/freeglut.h>
#include <iostream>
#include <stdio>

bool fullscreen = false;
bool mouseDown = false;

float xrot = 0.0f;
float yrot = 0.0f;

float xdiff = 0.0f;
float ydiff = 0.0f;

void drawBox()
{
glBegin(GL_QUADS);

glColor3f(1.0f, 0.0f, 0.0f);
// FRONT
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
// BACK
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glVertex3f( 0.5f, -0.5f, -0.5f);

glColor3f(0.0f, 1.0f, 0.0f);
// LEFT
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
// RIGHT
glVertex3f( 0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, -0.5f, 0.5f);

glColor3f(0.0f, 0.0f, 1.0f);
// TOP
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
// BOTTOM
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glEnd();
}

bool init()
{
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0f);

return true;
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

gluLookAt(
0.0f, 0.0f, 3.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);

glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);

drawBox();

glFlush();
glutSwapBuffers();
}

void resize(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glViewport(0, 0, w, h);

gluPerspective(45.0f, 1.0f * w / h, 1.0f, 100.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void idle()
{
if (!mouseDown)
{
xrot += 0.3f;
yrot += 0.4f;
}

glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 27 :
exit(1); break;
}
}

void specialKeyboard(int key, int x, int y)
{
if (key == GLUT_KEY_F1)
{
fullscreen = !fullscreen;

if (fullscreen)
glutFullScreen();
else
{
glutReshapeWindow(500, 500);
glutPositionWindow(50, 50);
}
}
}

void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouseDown = true;

xdiff = x - yrot;
ydiff = -y + xrot;
}
else
mouseDown = false;
}

void mouseMotion(int x, int y)
{
if (mouseDown)
{
yrot = x - xdiff;
xrot = y + ydiff;

glutPostRedisplay();
}
}

//*
///save vertices
struct THeader{
int vertlen; //amount of vertices you want to save
};

struct t3dpoint {
float x;
float y;
float z;
};
FILE* f = fopen(filename,"wb+");

fwrite(&header,sizeof(THeader),1,f);

//now you can save them
//through all vertices in array
for (j=0; j < header.vertlen ; j++) fwrite(&verts[j],sizeof(verts[j]),1,f); //or sizeof t3dpoint (whatever)
fclose(f);
//*/

int main(int argc, char *argv[])
{
glutInit(&argc, argv);

glutInitWindowPosition(50, 50);
glutInitWindowSize(500, 500);

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);

glutCreateWindow("13 - Solid Shapes");

glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialKeyboard);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutReshapeFunc(resize);
glutIdleFunc(idle);

if (!init())
return 1;

glutMainLoop();

return 0;
}

[/source]

pls tell me what sort of errors, where compiler sees the error? or the progarm breaks when loading saving, pls also give code what you use, cheers
and almost forgot add #include "iostream.h"

'iostream.h' is an extremely old and deprecated header which might not even be there depending on the compiler. You should never ever use it. The header in the C++ standard library is called 'iostream' without any .h.

first thing do not use constructor in structure you want to save(ermove it)

That is plain wrong. A constructor is fine since it does not change the memory layout. A virtual function does though. That said, the point is moot anyway because in general it is not a good idea to serialize whole structures (padding happens and will not always be the same between compilers or platforms). A better habit is to serialize the individual members.
wabbz111, are the error lines actually correct? I cannot make immediate sense of the error message in line 168.

That aside, why did you change your initial plan to output as a readable text format? Writing to a text file will be much easier to debug and a simple Wavefront obj file (containing only vertices and indices, maybe normals) is not that difficult to achieve (the corresponding Wikipedia entry contains all relevant information for that task).
Being able to check the validity of a file using a verified 3rd party program is priceless during development. If something does not work you know your writer is at fault instead of having to develop a reader as well and then trying to figure out which is wrong when it does not work (it never works the first time).

A very simple Wavefront obj exporter would be:

#include <vector>
#include <string>
#include <fstream>

void writeObject(const std::string& fileName, const std::vector<point>& points, const std::vector<int>& indices)
{
std::ofstream os(fileName.c_str());
for (std::size_t i = 0; i < points.size(); ++i)
os << "v " << points.x << " " points.y << " " << points.z << "\n";
for (std::size_t i = 0; i < indices.size(); i += 3)
os << "f " << (indices + 1) << " " << (indices[i + 1] + 1) << " " << (indices[i + 2] + 1) << "\n";
}

Not tested, but should work out of the box or with minimal cleanup. The only important caveat is that Wavefront obj files use one-based indices. If you account for that, writing or reading them is pretty straight forward. Of course, if you want reading non-trivial obj files or even different file formats I would still suggest using a library like Assimp.

Edit: <fstream> is needed, not <iostream>. Sorry for the inconvenience.
if he can't handle my code how he is supposed to split strings? when loading :)
The first important step is verifying the writer works. Being able to do that with an external, already verified tool, will (as I already said) save a lot of headache.

Once that is done, reading the same Wavefronts as generated again is pretty trivial using iostreams (I would not implement a full loader, that is what Assimp and co is for). String splitting via streams is pretty trivial.

Third, nothing in the OPs post says he has to implement a loader as well. And if he does, here is one that can loads the files generated by the writer above:

#include <vector>
#include <string>
#include <sstream>
#include <fstream>

void readObject(const std::string& fileName, std::vector<point>& points, std::vector<int>& indices)
{
points.clear();
indices.clear();

std::string line;
std::ifstream is(fileName.c_str());
while (std::getline(is, line))
{
std::string prefix;
std::istringstream iss(line);
iss >> prefix;
if (prefix == "v")
{
point pt;
iss >> pt.x >> pt.y >> pt.z;
points.push_back(pt);
}
if (prefix == "f")
{
int idx[3];
iss >> idx[0] >> idx[1] >> idx[2];
indices.push_back(idx[0] - 1);
indices.push_back(idx[1] - 1);
indices.push_back(idx[2] - 1);
}
}
}

It's not pretty and really does not work with more complicated Wavefronts or faulty files (production code must be able to deal with invalid files) but it gets the job done for the moment. Again, for loading I would strongly advise using a full fledged loader library since developing a full and error prone loader is a rather tedious and boring exercise.

Edit: <fstream> is needed, not <iostream>. Sorry for the inconvenience.
Edit2: istrstream was the old deprecated string stream. istringstream is what should be used.
I have changed your code :


I have changed your code :


#include "iostream.h" //sometimes need '#include "#stdio.h" ' or stdlib ;]

struct THeader{
int vertlen; //amount of vertices you want to save
};
struct t3dpoint {
float x;
float y;
float z;
};

THeader header;
t3dpoint * verts;


bool fullscreen = false;
bool mouseDown = false;
float xrot = 0.0f;
float yrot = 0.0f;
float xdiff = 0.0f;
float ydiff = 0.0f;
t3dpoint vertin(float x, float y, float z)
{
t3dpoint k;
k.x = x;
k.y = y;
k.z = z;
return k;
}
void CreateModelArray()
{
verts = new t3dpoint[24];

header.vertlen = 24;
verts[0] = vertin(-0.5f, -0.5f, 0.5f);
verts[1] = vertin( 0.5f, -0.5f, 0.5f);
verts[2] = vertin( 0.5f, 0.5f, 0.5f);
verts[3] = vertin(-0.5f, 0.5f, 0.5f);
// BACK
verts[4] = vertin(-0.5f, -0.5f, -0.5f);
verts[5] = vertin(-0.5f, 0.5f, -0.5f);
verts[6] = vertin( 0.5f, 0.5f, -0.5f);
verts[7] = vertin( 0.5f, -0.5f, -0.5f);

// LEFT
verts[8] = vertin(-0.5f, -0.5f, 0.5f);
verts[9] = vertin(-0.5f, 0.5f, 0.5f);
verts[10] = vertin(-0.5f, 0.5f, -0.5f);
verts[11] = vertin(-0.5f, -0.5f, -0.5f);
// RIGHT
verts[12] = vertin( 0.5f, -0.5f, -0.5f);
verts[13] = vertin( 0.5f, 0.5f, -0.5f);
verts[14] = vertin( 0.5f, 0.5f, 0.5f);
verts[15] = vertin( 0.5f, -0.5f, 0.5f);

// TOP
verts[16] = vertin(-0.5f, 0.5f, 0.5f);
verts[17] = vertin( 0.5f, 0.5f, 0.5f);
verts[18] = vertin( 0.5f, 0.5f, -0.5f);
verts[19] = vertin(-0.5f, 0.5f, -0.5f);
// BOTTOM
verts[20] = vertin(-0.5f, -0.5f, 0.5f);
verts[21] = vertin(-0.5f, -0.5f, -0.5f);
verts[22] = vertin( 0.5f, -0.5f, -0.5f);
verts[23] = vertin( 0.5f, -0.5f, 0.5f);
}
void drawBox()
{
int i;
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
for (i=0; i<24;i++)
glVertex3f(verts.x,verts.y,verts.z);


glEnd();
}
bool init()
{
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0f);
return true;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(
0.0f, 0.0f, 3.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
drawBox();
glFlush();
glutSwapBuffers();
}
void resize(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45.0f, 1.0f * w / h, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void idle()
{
if (!mouseDown)
{
xrot += 0.3f;
yrot += 0.4f;
}
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 27 :
exit(1); break;
}
}
void specialKeyboard(int key, int x, int y)
{
if (key == GLUT_KEY_F1)
{
fullscreen = !fullscreen;
if (fullscreen)
glutFullScreen();
else
{
glutReshapeWindow(500, 500);
glutPositionWindow(50, 50);
}
}
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouseDown = true;
xdiff = x - yrot;
ydiff = -y + xrot;
}
else
mouseDown = false;
}
void mouseMotion(int x, int y)
{
if (mouseDown)
{
yrot = x - xdiff;
xrot = y + ydiff;
glutPostRedisplay();
}
}

void savemodel(char *filename)
{
FILE* f = fopen(filename,"wb+");
fwrite(&header,sizeof(THeader),1,f);

for (j=0; j < header.vertlen ; j++) fwrite(&verts[j],sizeof(verts[j]),1,f);
fclose(f);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition(50, 50);
glutInitWindowSize(500, 500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);

glutCreateWindow("13 - Solid Shapes");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialKeyboard);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutReshapeFunc(resize);
glutIdleFunc(idle);
CreateModelArray();
if (!init())
return 1;
glutMainLoop();
return 0;
}
Again, 'iostream.h' is an old and deprecated header. The header you are looking for is 'iostream'. And if you need the C header 'stdio.h' then you should include 'cstdio' (note the missing .h and leading c). Same goes for 'stdlib.h'. That is a C header and when using it in C++ you should include 'cstdlib' instead.
Okay, let me sum this up. First, you present the OP with a solution that does not do what he wants (he wants to write text files, you offer him binary files). Then you make several mistakes (like using headers that don't exist) and when corrected (repeatedly) you go on an indiscriminate crusade of downvoting? Was anything I said actually factually incorrect (if so, I'm happy to be corrected) or are you just petty?

This topic is closed to new replies.

Advertisement