scanf/fscanf problem with an OBJ reader

Don't enable client states that you aren't using; doing so is a pretty good way to produce a crash. I don't know the specific details for sure, but presumably if the GL is expecting a pointer to be set for a given array and that pointer is invalid then obviously something is likely to go terribly wrong.

That said, if you're using glDrawArrays, then you'll at least need to have the vertex pointer set, so that one can be left on at init. Likewise, if you know for a fact that all of your geometry throughout the entire program will be using texture coordinates then you can leave that on at init too (same for the other client states). However, it is unlikely you'll use normals for everything in any given program.

In a situation where you will be drawing an object with normals and then another without you would first glEnableClientState(GL_NORMAL_ARRAY); for that object using normals, then turn it off after you've drawn it by calling glDisableClientState(GL_NORMAL_ARRAY); ... Again, same for other client states -- switch them on and off as needed. Obviously fewer calls help performance, but I would say that it's usually better to be safe than sorry, especially when in doubt.

Of course not. Unfortunately, loading obj isn't anywhere near as simplistic as you think. You can't just load the data directly into an array and expect things to work.

When I say "line" in what follows, I mean a line of text as loaded from the obj file: The obj file has vertex lines, normal lines, texture coordinate lines, and face lines, and some other stuff too (the other stuff can usually be ignored). At the very least, you will need to load all the vertex lines into memory first. Then you can read all the face lines and construct your real array of vertices from the vertex lines indicated by those faces. The face lines are indices into the verts, normals, and tex coords, and are all mixed up so as to reuse data in the file to save space. You have to essentially "unpack" the obj file to actually use it, which is why it isn't as easy as just loading the file straight into memory and letting it rock.

Learning how to load an obj file is going to be quite a challenge for you. Probably worth the adventure though, and it makes OpenGL much more useful when you can load 3D models. However, I should point out that even many experienced developers choke on trying to load an obj file, so it's really not a no-brainer. To make matters worse, the files are rarely consistent coming from different programs.

mikey Wrote:I know, I couldn't count the number of 'v''s (v's?) in the OBJ. I still don't see the connection between the faces and the vertices?

Right. You'll have to figure out how the faces and vertices connect before you can do that too. That's why I suggest reading up on obj files before going any further with them for now.

mikey Wrote:Is it worth creating my own file format that just contains vertices? would that work?

Sure! Nothing wrong with that. The only problem is that you'll obviously have to make the file by hand by specifying the verts yourself, but otherwise it'll work just fine. Besides, it can be fun, although tedious, to create your own models that way.

I highly recommend making your own model format, that you can just load in as a vertex array.

Loading .objs is fine for prototyping, but why would you waste disk space or CPU time parsing text files when your customers launch your app? After your models are finalized, convert them to a simple binary format that you load directly into a VBO.

Even better is to procedurally generate your geometric data, so you don't spend any time loading from disk. Of course that's only easy for fairly simple geometric shapes.

Using your own file format that you can load directly into an array is definitely the best thing to do, but the problem here is that one needs to know where to get the model data from in the first place. You can't expect any 3D editor out there to know how to export to your own model format, so you'll either have to write an exporter for it (via script if available or API if available), or you'll have to convert from an existing format such as .obj. OR you'll have to write your model data by hand, which is not practical for anything but the simplest of models.

One exception to this is that Cheetah3D has a .h export which would allow you to compile the model right into your program in a format which is already compatible with glDrawElements. The drawback being that that's all it does, and lacks flexibility like specifying what texture(s) to use, etc.

So practically speaking, learning how to either load or convert .obj is a good place to start.

The OBJ file format is just fine. You're pretty close to getting it to work. Having your own file format can be a bit tedious because you have to convert all the models first even when making slight changes.

I recommend you putting the vertices in std:vectors. This way the array scales automatically, and if you later want to switch to glDrawArrays, they are continuous in memory, too. I'd say that it will be a lot simpler to get the model to draw with OpenGL immediate mode (unless you're developing for the iPhone). You can still later switch to faster drawing methods.

edit: you can put the faces in std:vectors, too. The loading is just the same. The drawing can then go something like this:

Code:

for all faces:
if this is a triangle, draw a triangle, else draw a quad.
for all vertices that correspond to this face:
draw vertex at x, y, z.
next
next

Yes. You can create a dynamically-sized array in C by keeping track of its allocated size, adjusting it as necessary when you want to add an item to the array (I like to start with one element and double the size each time I go over, but there may be more optimal approaches for your particular situation), and call realloc() to resize the array. For example: