So. Raylib is a lovely, clean, slick piece of C appreciation. But lets get to the point. I will try to explain everything as clearly as possible so everyone can more or less know what is going on here
I started writing GLTF2 importer. It's actually a layer between Lungudunum Engine loader (https://github.com/Lugdunum3D/glTF2-loader
) and the Raylib itself.
If you don't know what GLTF2 is it's a new open source format for saving 3D scenes. Seems like a good way to put fbx to rest when more engines will support it. It has been made by Khronos Group. You can read more about it here https://www.khronos.org/gltf/
So in order to render the GLTF file, a new Mesh struct needs to be created and filled with proper data read from GLTF file. I think I have everything ready except:
float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
From what I have read usually tangent vectors are stored in Vec4. It contains 3 vector components representing the tangent and one additional scalar deciding handness of the vertex frame. In the picture below you can see normal and tangent vector (welp you can embed pictures here...sorry).http://www.opengl-tutorial.org/assets/images/tuto-13-normal-mapping/TangentVectorFromUVs.png
Having those two you can compute a third vector which is perpendicular to the plane those two create. It can be perpendicular in two directions. That's what this fourth component of Vec4 is used for. It decides which direction this vector (called bitangent) aligns with. Picture below shows the third vector added.http://www.opengl-tutorial.org/assets/images/tuto-13-normal-mapping/NTBFromUVs.png
Raylib uses Vec3 meaning that you don't have the control over the direction of the bitangent vector. Since GLTF specs use Vec4 it makes the array of data incompatible. Let's look at the memory of those two:
Vec3 : | x1 | y1 | z1 | x2 | y2 | z2 | x3 | ...
Vec4 : | x1 | y1 | z1 | w1 | x2 | y2 | z2 | ...
If Raylib stored tangents in Vec4 I could just point Mesh.tangents (it's a pointer) to the Vec4 data supplied by GLTF loader and that would be it. Since there is data type difference the data get misaligned.
My question is: why does Raylib use Vec4? Is there anything better I can do except extracting x, y, z components to a new array and pointing Mesh.tangents to this new memory block aligned with Vec3 struct?
Another thing I need a bit more info about are mesh indices. Vertex indices allow us to not repeat vertices positions in the file. Every vertex is defined once in an array. Another array, an array of indices allows building of the triangles. We just take three consecutive indices which tell us which vertices are used to build the triangle.
In Raylib Mesh.indices is a pointer to unsigned short type which would mean that single index would be able to point to 65535th vertex maximum. If the mesh is made out of more vertices then how would you save its index in an array of 16 bit variables? Does this limit primitive density in Raylib? In GLTF the type the indices array holds changes depending on how many vertices are stored.
Final thing are two properties listed below. From what I read in Raylib's code those are filled by the library, am I right? I shouldn't touch those?
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
Sorry for the long and convoluted post... I do hope everything is clear
If you want to read more I recommend this link:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/