Hello All,
I am just beginning to do a large leap from the classical way of using OpenGL 1.2 to the more modern way by using VAO/VBO and shaders. I am going to need a bit of help with some of the understanding as the books that I have read don’t go into the details enough in which they rely heavily on GLUT and GLEW for which I will not be using.
So, let me start by explaining my data. I am reading in several VRML files which is nothing more than a definition of an object by way of materials, coordinated, normal vectors and indexes for the later. Generally these files are structured as having a Materials Section always, a coordinates section always and may or may not include normals. The materials are always defined as per primitive, I.E. per triangle. As well as the data, there is always a coordinate index table and an material index table. In the coordinates table, there is always a restart index for the triangle primitive of -1. So this means that to describe a triangle there is a sequence in the index table like [0,3,10,-1][3,10,15,-1]…
In my existing code, I hold all the materials data (Ambient,Diffuse,Specular,Shininess,Transparency) in separate arrays. As well, I hold all of the coordinate vertexes in a separate array. For the normal vectors, if they are not included in the file, then they are created from the triangles and stored into an array. Yes my normal vectors are per triangle/primitive. Along with the actual data is stored two index array tables, one for vertexs and one for materials. Generally speaking, the count of elements in the materials index array are either the vertex index count/3 or exactly one. This allows me to assign the material either per object, or per primitive/triangle. My rendering loop goes like this:
if(FVisible)
{
glBegin(GL_TRIANGLES);
LMatIndex = 0;
try
{
if(FAmbientCount==1) //If there is only one entry in the material data arrays
{
LMatIndirect = FMaterialIndexList[0]; //Grab index into material table
LAmbient = FAmbientList[LMatIndirect]; //Get Ambient Color
LDiffuse = FDiffuseList[LMatIndirect]; //Get Diffuse Color
LSpecular = FSpecularList[LMatIndirect]; //Get Specular Color
glMaterialfv(GL_FRONT, GL_AMBIENT, LAmbient.ColorArray); //Set the ambient
glMaterialfv(GL_FRONT, GL_DIFFUSE, LDiffuse.ColorArray); //Set the diffuse
glMaterialfv(GL_FRONT, GL_SPECULAR, LSpecular.ColorArray);//Set the specular
glMaterialf(GL_FRONT, GL_SHININESS, FShininessList[LMatIndirect]*128.0); //Set the shininess
}
for (LIndex = 0;LIndex<FPointIndexCount-3;LIndex+=4)
{
try
{
LMatIndirect = FMaterialIndexList[LMatIndex];
if(FAmbientCount>1)
{
LAmbient = FAmbientList[LMatIndirect];
LDiffuse = FDiffuseList[LMatIndirect];
LSpecular = FSpecularList[LMatIndirect];
glMaterialfv(GL_FRONT, GL_AMBIENT, LAmbient.ColorArray);
glMaterialfv(GL_FRONT, GL_DIFFUSE, LDiffuse.ColorArray);
glMaterialfv(GL_FRONT, GL_SPECULAR, LSpecular.ColorArray);
glMaterialf(GL_FRONT, GL_SHININESS, FShininessList[LMatIndirect]*128.0);
}
glNormal3fv(FNormalList[LMatIndex++].V);
glVertex3fv(FPointList[FPointIndexList[LIndex]].V);
glVertex3fv(FPointList[FPointIndexList[LIndex+1]].V);
glVertex3fv(FPointList[FPointIndexList[LIndex+2]].V);
}
catch(...)
{
}
}
glEnd();
glEndList();
}
catch(...)
{
glEnd();
glEndList();
}
Ok, so you might be getting the idea, that the material is set once per triangle and there is also one normal per triangle. Also, if you notice the for loop increment my counter is LIndex+=4 when there is only three vertexs per triangle, this is because one index implies a restart for the primitive which is best suited for vertex arrays. I just skip over it but have kept it so that I can move forward with OpenGL.
Now, with that explained on over, how do I move to using shaders with VAO/VBO’s and the fact that I only need to set normal and materials once per triangle/primitive. Some of my objects will be using a transformation matrix to change its location in a scene, but none of my objects will ever be modified. The data and color are set in stone the moment they are loaded.
I am just starting to understand how to use VBO and a very, very basic shader for vertex and fragment, but none of the books I read really deal with the disconnect of number of vertex versus to the number of normals and materials. My application has some 1.7 million triangles and will grow to be three times this before I am finished.
I have all of the foundation work done to give me the ability to create rendering context up to the latest version of OpenGL 4.6 as well as give me access to all of the extensions that go along with it. But I am absolutely not using any GLUT or GLEW. I am only using the native OpenGL plus the extensions provided by the Kronos group
Ok, now that is over, how do I begin to describe this so that in the end, I end up with a single glDraw* call?
What I do know is that I need to allocate a buffer object, one per object, but how do I deal with the material and normal vectors. I read that there is a gl command that lets me do something per primitive in the geometry shader, and that there is a way to do something in the fragment shader, but nothing I read was clear on these topics. They always focused on per vertex colors/materials and normal vectors.
Thanks for any guidance on this.
James