Drawing an OBJ from structs
OK, I've been working on an .OBJ Loader for a while now for my game in C. I ended up using Kamran Paaji's code as a template. I can't see why It's not working.
weapon.c
func-declarations.h
main.c
There is no errors according to GDB or Xcode's debugger. Nothing is drawn.
weapon.c
Code:
int i;
glTranslatef(0.0f,0.0f,-1.0f);
glBegin(GL_TRIANGLES);
for (i = 0 ; i < LCTcount ; i++)
{
glVertex3f(v[t[i].vert1-1].x, v[t[i].vert1-1].y, v[t[i].vert1-1].z);
glVertex3f(v[t[i].vert2-1].x, v[t[i].vert2-1].y, v[t[i].vert2-1].z);
glVertex3f(v[t[i].vert3-1].x, v[t[i].vert3-1].y, v[t[i].vert3-1].z);
}
glEnd();func-declarations.h
Code:
extern struct LCtris {
int vert1;
int vert2;
int vert3;
};
extern struct LCverts {
float x;
float y;
float z;
} ;
struct LCverts v[50000];
struct LCtris t[50000];
int LCVcount ;
int LCTcount ;main.c
Code:
struct LCverts v[50000];
struct LCtris t[50000];
int LCVcount = 0;
int LCTcount = 0;
char line[100];
FILE * fp = fopen("cube.obj" , "r");
if ( fp != NULL)
{
while ( fgets(line , 75 , fp) != NULL )
{
if (line[0] == 'v')
{
sscanf(line, " %*c %f %f %f ", &v[LCVcount].x , &v[LCVcount].y , &v[LCVcount].z );
LCVcount++;
}
else if (line[0] == 'f')
{
sscanf(line, " %*c %d %d %d " , &t[LCTcount].vert1 , &t[LCTcount].vert2 , &t[LCTcount].vert3 );
LCTcount++;
}
}
}
fclose(fp);There is no errors according to GDB or Xcode's debugger. Nothing is drawn.
~ Bring a Pen ~
How is it not working? Is it not loading, not drawing, etc. Printing out the data structures after loading and other info can help point to the problem. Do that and share the info you get. This will allow us to understand what is happening, and help you in turn.
I remember that I used that example. I found that:
Worked better.
I remember that I used that example. I found that:
Code:
if(3==sscanf(line,"v %f %f %f",...//yada yada
You should not write:
Instead lets define:
and then we may write:
EDIT: I would also suggest that you may rather set the values vert1, vert2 and vert3 to be one less than read in, that lets you have:
Code:
glVertex3f(v[t[i].vert1-1].x, v[t[i].vert1-1].y, v[t[i].vert1-1].z);Instead lets define:
Code:
void vertex(LCverts xyz) { glVertex3f(xyz.x, xyz.y, xyz.z); }and then we may write:
Code:
vertex(v[t[i].vert1-1]);EDIT: I would also suggest that you may rather set the values vert1, vert2 and vert3 to be one less than read in, that lets you have:
Code:
vertex(v[t[i].vert1]);Sir, e^iπ + 1 = 0, hence God exists; reply!
Hello unknown and Oditty007.
If I change the code to:
It prints line is 0 ten times. This is strange. cube.obj goes like this:
So where does the ten come from? I think my problem is in loading the OBJ, but my code checks if it is NULL, so it's loaded something.
If I change the code to:
Code:
if (line[0] == 'v')
{
if ( sscanf(line , "%*c %f %f %f " , &v[LCVcount].x , &v[LCVcount].y , &v[LCVcount].z ) == 0 )
printf("line is 0");
sscanf(line, " %*c %f %f %f ", &v[LCVcount].x , &v[LCVcount].y , &v[LCVcount].z );
LCVcount++;
}
else if (line[0] == 'f')
{
sscanf(line, " %*c %d %d %d " , &t[LCTcount].vert1 , &t[LCTcount].vert2 , &t[LCTcount].vert3 );
LCTcount++;
}It prints line is 0 ten times. This is strange. cube.obj goes like this:
Code:
# Only 8 v's.
# 4 vt's
# 6 vn's
# 6 f's
# ( â‰* 10 )
v -0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 -1.000000
vn -1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
f 4/4/1 3/3/1 2/2/1 1/1/1
f 8/4/2 7/3/2 6/2/2 5/1/2
f 1/4/3 2/3/3 7/2/3 8/1/3
f 5/4/4 6/3/4 3/2/4 4/1/4
f 3/4/5 6/3/5 7/2/5 2/1/5
f 5/4/6 4/3/6 1/2/6 8/1/6So where does the ten come from? I think my problem is in loading the OBJ, but my code checks if it is NULL, so it's loaded something.
~ Bring a Pen ~
Its printing out "line is 0" because you have printf("line is 0");
It wont increment on itself!
As to the problem, your loader was made for triangulated obj's. Your cube is in quads.
Even if it did load, it wont draw correctly.
And, 'v' is the first char of "vt" "v" and "vn" all totaling 10 times. Then it gets to the sscanf, and after ignoring the first char it gets to the second, and exits with 0, not copying anything and acting as if it did, messing up the v counts, drawing blank. Thats why I said to use:
This guarrantees it to be only matching "v"
Then f %i %i %i is what your code is looking for, f %i/%*i/%*i %i/%*i/%*i %i/%*i/%*i is what you need, but make a way to find all 3 variations.
It wont increment on itself!
As to the problem, your loader was made for triangulated obj's. Your cube is in quads.
Even if it did load, it wont draw correctly.
And, 'v' is the first char of "vt" "v" and "vn" all totaling 10 times. Then it gets to the sscanf, and after ignoring the first char it gets to the second, and exits with 0, not copying anything and acting as if it did, messing up the v counts, drawing blank. Thats why I said to use:
Code:
if(3==sscanf(line,"v %f %f %f",...//yada yadaThen f %i %i %i is what your code is looking for, f %i/%*i/%*i %i/%*i/%*i %i/%*i/%*i is what you need, but make a way to find all 3 variations.
C (or at least scanf) is the wrong approach for this problem.
Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote:C (or at least scanf) is the wrong approach for this problem.
Better ideas? While you're thinkin' Ill crack on.
~ Bring a Pen ~
Anybody? Please?
~ Bring a Pen ~
C and scanf work fine for this. Oddity007 has some great input.
mikey, I deliberately posted that obj cube a while back with quad sides since that would help encourage you to think about how the faces are constructed, since you'll want to at least support quads (in addition to triangles). So in this case you'll have to split each quad into two triangles. Do note that with obj's you might also encounter faces with more than four sides. You can either attempt to detect those and return an error, or ignore them I suppose, but just keep in mind that obj files are notoriously inconsistent in terms of sides and other random issues.
You're getting closer to being able to load obj files (especially now that you can load textures too), so keep at it! Again, be sure to carefully read this page, since it pretty much has all the info you'll need right now, and it's short. Try to draw out the cube obj file on graph paper if you have to to understand how the obj file is structured.
mikey, I deliberately posted that obj cube a while back with quad sides since that would help encourage you to think about how the faces are constructed, since you'll want to at least support quads (in addition to triangles). So in this case you'll have to split each quad into two triangles. Do note that with obj's you might also encounter faces with more than four sides. You can either attempt to detect those and return an error, or ignore them I suppose, but just keep in mind that obj files are notoriously inconsistent in terms of sides and other random issues.
You're getting closer to being able to load obj files (especially now that you can load textures too), so keep at it! Again, be sure to carefully read this page, since it pretty much has all the info you'll need right now, and it's short. Try to draw out the cube obj file on graph paper if you have to to understand how the obj file is structured.
AnotherJake Wrote:You can either attempt to detect those and return an error, or ignore them I suppose
Or automatically triangulate them at load time.
ThemsAllTook Wrote:Or automatically triangulate them at load time.
Oh ya, sure, except that I don't want to allude to the next chapter where we explain how to use glutess
OK, I've taken Oddity007 (Thanks, BTW) advice and constructed this:
main.c
weaponry.c
Yet still nothing is drawn.
"Laser Carbine" is an OBJ I had kicking around (It's all in triangles) but it's 3,000 lines plus, is this a problem?
My main 3D modeller (Art of Illusion) exports it's OBJ's as triangles, so do I have to include support for other polygons?
PS. It doesn't print line is 0 anymore.
main.c
Code:
FILE * fp = fopen("Laser Carbine.obj" , "r");
if ( fp != NULL)
{
while ( fgets(line , 75 , fp) != NULL )
{
if (3 == sscanf(line, "v %*f %*f %*f") )
{
sscanf(line, " %*c %f %f %f ", &v[LCVcount].x , &v[LCVcount].y , &v[LCVcount].z );
LCVcount++;
}
else if (3 == sscanf(line, "f %*i %*i %*i") )
{
sscanf(line, " %*c %d %d %d " , &t[LCTcount].vert1 , &t[LCTcount].vert2 , &t[LCTcount].vert3 );
LCTcount++;
}
}
}
fclose(fp);weaponry.c
Code:
int i;
glTranslatef(0.0f,0.0f,-1.0f);
glBegin(GL_TRIANGLES);
for (i = 0 ; i < LCTcount ; i++)
{
vertex(v[t[i].vert1-1]);
}
glEnd();Yet still nothing is drawn.
"Laser Carbine" is an OBJ I had kicking around (It's all in triangles) but it's 3,000 lines plus, is this a problem?
My main 3D modeller (Art of Illusion) exports it's OBJ's as triangles, so do I have to include support for other polygons?
PS. It doesn't print line is 0 anymore.
~ Bring a Pen ~
I haven't had a good look through your code but you're only checking if fp != NULL, but not giving yourself a warning if it is NULL. So it could be that you file is not loading properly in the first place.
I don't think it's NULL. In my if (fp != NULL) block, i added an else statement, which does not print Error. Thanks anyway though.
~ Bring a Pen ~
why have 75? maybe that's too small
Sir, e^iπ + 1 = 0, hence God exists; reply!
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Weird behaviour with structs and the = operand | Jones | 2 | 2,344 |
Oct 12, 2006 07:11 PM Last Post: Jones |
|
| Free Structs | Justin Brimm | 4 | 2,962 |
May 30, 2006 06:20 AM Last Post: Jones |
|

