scanf/fscanf problem with an OBJ reader
I'm writing a model loader for my 3D OpenGL written in C, but I can't get it to work.
The OBJ is listed as
Here's the code:
After I run, I get the gdb. It tells me this line is faulty, but I can't see why. scanf (and fscanf) return integers (1), the number of strings matching the layout in the format string, this way I can tell if the line is a comment (just a string) or a proper line (char, then three decimals (floats?). )
Thanks
The OBJ is listed as
Code:
# comment
v 1.0345 2.434 0.342
v 0.4435 0.234 1.240Code:
if ( fscanf(objfile,"%s %f %f" , &fchar) != 1 )After I run, I get the gdb. It tells me this line is faulty, but I can't see why. scanf (and fscanf) return integers (1), the number of strings matching the layout in the format string, this way I can tell if the line is a comment (just a string) or a proper line (char, then three decimals (floats?). )
Thanks
~ Bring a Pen ~
You need to pass a corresponding pointer in the fscanf parameter list for each conversion specified in your format string. In your case, you're matching char *, float *, float *, but only providing one of those. If you compile with -Wall in your compiler warning flags, it'll tell you about these errors at compile time.
Ohh, so I have to supply more parameters...
Is this right?
?
Is this right?
Code:
if ( fscanf(objfile,"%s %f %f %f" , &fchar, &xvar, &yvar , &zvar) != 1 )?
~ Bring a Pen ~
mikey Wrote:Ohh, so I have to supply more parameters...
Is this right?
Code:
if ( fscanf(objfile,"%s %f %f %f" , &fchar, &xvar, &yvar , &zvar) != 1 )
?
You can double check against the manual page. Open Terminal.app and type man scanf
Sir, e^iπ + 1 = 0, hence God exists; reply!
So, that's a ... yes?
~ Bring a Pen ~
No, wait...
It still doesn't work. I can't see why not!?!
(I am not using OBJ-style commenting, so I felt it'd be proper to give the model it's own file format.)
This code doesn't return comments, but only returns the first (x) coordinate in each line.
Please help.
It still doesn't work. I can't see why not!?!
(I am not using OBJ-style commenting, so I felt it'd be proper to give the model it's own file format.)
Code:
FILE * objfile;
objfile = fopen("Laser Carbine.eobj" , "r");
while ( fscanf(objfile," %s ", &line ) != EOF) { // while we've not reached End of File
float xc; // x vertex coordinate (I'm going to put all 3 (x,y,z) in an array?
float yc; // y vertex coordinate
float zc; // z vertex coordinate
if ( fscanf(objfile,"%s %f %f" , &fchar, &xc, &yc, &zc ) != 1 ) // if the line follows a pattern of string decimal decimal decimal (It's not a comment )
{
printf("( %s )", &fchar); // prints the 'thing' , whether it's a '#' or a 'v' or a 'f'.
}
}This code doesn't return comments, but only returns the first (x) coordinate in each line.
Please help.
~ Bring a Pen ~
how about: while(!feof(objfile))
Sir, e^iπ + 1 = 0, hence God exists; reply!
OK thanks unknown, I've got that part of the OBJ Loader working, so how do I actuallly draw the vertices? Should I (or could I) store them as 3 arrays:
...Then? Wouldn't 3 arrays of 1000+ be overkill? Is there an easier way?
EDIT: Could I use one 3*dynamic array for the whole model?
Code:
int x[];
int y[];
int z[];...Then? Wouldn't 3 arrays of 1000+ be overkill? Is there an easier way?

EDIT: Could I use one 3*dynamic array for the whole model?
~ Bring a Pen ~
You can use malloc to create the arrays and read the vertices into them, then make a display list by drawing the triangles with opengl and then free the arrays (so the memory can be reused for something else).
Sir, e^iπ + 1 = 0, hence God exists; reply!
What's a display list? Because I need to redraw the model every frame, I'd need to store the arrays somehow?
~ Bring a Pen ~
You *can* use display lists, but I wouldn't recommend it since VBOs are preferred now, and display lists will be going away in future versions of OpenGL. Instead, what you should do is learn how to use glDrawArrays first. Once you learn how to use glDrawArrays it'll be much easier to see how you need to organize the data you're loading from your obj file. Don't try to learn glDrawArrays at the same time as figuring out how to load .obj though, since that'll just complicate matters.
mikey Wrote:What's a display list? Because I need to redraw the model every frame, I'd need to store the arrays somehow?
opengl.org has various infos, http://www.opengl.org/resources/faq/tech...aylist.htm
AnotherJake Wrote:display lists will be going away in future versions
Yikes! That sucks.
Sir, e^iπ + 1 = 0, hence God exists; reply!
OK then, I won't use display lists, I'll use glDrawArrays. How would I do this?
I think I've mastered file I/O for now.
PS. I'm using GLUT.
I think I've mastered file I/O for now.
PS. I'm using GLUT.
~ Bring a Pen ~
You really should read the Red Book or some other authoritative source for learning how to use glDrawArrays. Getting answers only from forum folks such as us isn't ideal 
That said, here are the "Cliff's Notes" on how to use glDrawArrays:
To set up your data, you just need some arrays, like here are two arrays initialized on the spot, one for texture coordinates and one for vertices. There are enough in each to make up a quad:
You could just as well make up your arrays by loading them from a file.
To actually make use of them, you must first enable all the required client states you will be using to draw your object. You will always want to use vertices, and you might want to use normals, texture coordinates, or even vertex colors. So always call:
glEnableClientState(GL_VERTEX_ARRAY);
Then you might also want to call these, depending on your needs:
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Then you need to set the pointer for each type of array, like so:
glVertexPointer(3, GL_FLOAT, 0, myVerts);
and also others as needed:
glNormalPointer(GL_FLOAT, 0, myNormals);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, myColors);
glTexCoordPointer(2, GL_SHORT, 0, myTexCoords);
Then, when you're ready to draw you simply call glDrawArrays, perhaps like so for the equivalent of a quad using a triangle strip instead of GL_QUADS:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
For an actual example this in use, see that old example I gave you for drawing a cube a while back: here's the post

That said, here are the "Cliff's Notes" on how to use glDrawArrays:
To set up your data, you just need some arrays, like here are two arrays initialized on the spot, one for texture coordinates and one for vertices. There are enough in each to make up a quad:
Code:
GLushort myTexCoords[] = { 0, 0,
1, 0,
0, 1,
1, 1 };
GLfloat myVerts[] = { -0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f };You could just as well make up your arrays by loading them from a file.
To actually make use of them, you must first enable all the required client states you will be using to draw your object. You will always want to use vertices, and you might want to use normals, texture coordinates, or even vertex colors. So always call:
glEnableClientState(GL_VERTEX_ARRAY);
Then you might also want to call these, depending on your needs:
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Then you need to set the pointer for each type of array, like so:
glVertexPointer(3, GL_FLOAT, 0, myVerts);
and also others as needed:
glNormalPointer(GL_FLOAT, 0, myNormals);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, myColors);
glTexCoordPointer(2, GL_SHORT, 0, myTexCoords);
Then, when you're ready to draw you simply call glDrawArrays, perhaps like so for the equivalent of a quad using a triangle strip instead of GL_QUADS:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
For an actual example this in use, see that old example I gave you for drawing a cube a while back: here's the post
OK, does it matter if I call
and don't use them all?
And I should call everything bar drawArrays in init()? (Once in a program)?
Thanks much.
PS.
Code:
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);And I should call everything bar drawArrays in init()? (Once in a program)?
Thanks much.
PS.
Quote:Cliff's Notes. Don't remind me of that time my english teacher caught me out...

~ Bring a Pen ~

