Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL obj loader in C

Tags:

c

opengl

As a learning endeavor I'm trying to make an OpenGL(3.3+) program in C, but I've hit a snag on the model loader. Everything I can find on the internet about loading obj files happens to involve C++ vectors and GLM matrices for storing the vertices and normals but as you know neither of those abstractions are available for C, and I would rather not use C++ because I do not know C++ and C++ isn't just "C with classes" anymore, so I'd be misusing it.

I know there are probably libraries for C that provide similar functionality to vectors and matrices, but I'm trying to gain a concrete knowledge of how the model loading is actually done and I can't seem to understand all of the C++ floating around on the internet (again, I'm not very familiar with it).

So what I want to know is, what are the steps to loading a model into OpenGL from a C perspective?

like image 553
Red Avatar asked Apr 23 '14 17:04

Red


1 Answers

There is nothing in OpenGL requiring C++. OpenGL itself is designed as a C API. People use mostly C++ because it is faster to develop in it.

OpenGL doesn't really care what container the data is in, whether it is a C++ vector, a vanilla, on-the-stack C array or a memory pool allocated with malloc. The majority of GL functions that involve transfer of data to the GPU take in a pointer to the first element and a size variable to indicate how long it is.

The same applies to matrices and multi-component vectors (different from C++ std::vector) - as long as the data is appropriately aligned you are good to go.

Here is an example taken out of the QVector4D class which works perfectly with OpenGL. A quick peek at its "private parts" reveals there is nothing to it:

private:
    float xp, yp, zp, wp;

That's all it is, 4 floats side by side. Take a look at a 4x4 matrix class - no rocket science either:

private:
    float m[4][4];          // Column-major order to match OpenGL.

So, you can perfectly well use OpenGL with C, the GL functions are the same, the only thing that changes is you will be working with "C idioms" rather than C++.

EDIT: For a basic "hello triangle" or something really simple, you could just use a C array on the stack. But 3D models may actually pack quite a lot of vertices, plus there is no way for you to know in advance how many, which makes stack arrays not applicable - the geometry may exceed the stack and lead to... well... stack overflow and crash, plus the array size must be known at compile time.

So, what you should be doing is allocate memory dynamically with malloc(vertCount * sizeof(float), as much as you need for the particular mesh, load the floats from the mesh in and use that "array" to pass to OpenGL functions. If you haven't used dynamic memory don't worry, just look it up, it is (almost) the same as working with a stack array, with the caution note that you have to free() that memory manually otherwise it will leak.

You shouldn't have too much trouble with importing OBJ, it is an open and rather simple format. But parsing it is a whole different topic.

like image 63
dtech Avatar answered Sep 19 '22 15:09

dtech