Question

I'm working on a 3d map generator platform on C++/OpenGL and, after finishing with Perlin's Noise, I needed to load some 3d models into my screen. I never tried it before and after read about it I decided to use COLLADA's model format. The first thing I did was to read the XML file through TinyXML and convert it to understandable classes inside my code. I can access everything with no problem. So far all was well, but the problem to me appeared when I tried to properly convert the XML's information in 3d static models. I read many tutorials about, but I think I didn't catch the "essence" of COLLADA and then I'm here asking for help. My ".dae" file consists of a simple sphere created on Blender. It doesn't matter what I do, whenever I try to load it into my screen what I get is always something as a "thorny thing", like this image:

http://s2.postimg.org/4fdz2fpl4/test.jpg

Surely I'm not taking the correct coordinates or at least I'm not implementing them correctly. Here is the exactly COLLADA file that I'm testing. In short, what I'm doing is the following:

1 - First I access "polylist" and get the values of "p", also the ID whose semantic is VERTEX, in this case "ID2-mesh-vertices"

2 - I access "vertices" and get the source ID whose semantic is POSITION, in this case "#ID2-mesh-positions"

3 - I access the source "#ID2-mesh-positions" and take the float values

4 - After that I started to loop through the "p" values from three to three (accordingly to "technique_common") to get, respectively, the indexes of vertices X, Y and Z located within the float values of the source. For example, what the code does =>

  • 0 0 1 = {X -> 0.4330127;Y -> 0.4330127; Z -> 0.25}
  • 1 2 2 = {X -> 0.25;Y -> 0; Z -> 0}
  • 1 1 0 = {X -> 0.25;Y -> 0.25; Z -> 0.4330127}

Obviously I'm doing something very wrong, because I cannot get a simple sphere.

Was it helpful?

Solution

*

<input semantic="VERTEX" source="#ID2-mesh-vertices" offset="0"/>
<input semantic="NORMAL" source="#ID2-mesh-normals" offset="1"/>

This tells you that for each vertex, you have 2 indices poking into the referenced sources. 0 0 is the first set, 1 1 is the second, 2 2 is the third. since your first polylist value is 3 (really, all of them are), that makes up your first triangle.

Now, those indices are going through the source accessor for the float array...

<accessor source="#ID2-mesh-normals-array" count="266" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>

This tells you that to read the normal associated with an index, you have to stride the array by 3 elements, and each vector is made up of 3 floats (X, Y, Z). Note that stride does not have to be the number of elements in each vertex, though it is often the case.

So, to conclude that example, to read the index 2 of the normal array, you need to go read the elements indexed with X_index=index*stride=6, Y_index=X_index+1=7, Z_index=X_index+2=8, to find the normal (X,Y,Z) = (-0.2561113 0 -0.8390759 -0.4953154)

And yes, this means that you have multiple indices per vertex, something that OpenGL does not support natively. See those various questions as reference material.

Rendering meshes with multiple indices

How to use different indices for tex coords array and vertex array using glDrawElements

3 index buffers

OTHER TIPS

Use the collada de-indexer to pre-process the .dae and eliminate multiple indices per vertex. While you are at it, convert to triangles in the pre-process to simplify even further your loader. https://collada.org/mediawiki/index.php/COLLADA_Refinery

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top