OpenGL Drawing Elements for many cube objects [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am building a renderer which takes in many objects and batch renders them to the screen. The full renderer code -> https://github.com/rob-DEV/OpenGL-Model-Viewer/tree/master/OpenGL-Model-Viewer/src/graphics/renderer
Pushing the object (all are cubes containing indexed vertices (8) and 36 indices) to the renderer on each frame call.
//load models
for (int j = 0; j < 5; j++)
{
models.push_back(ObjModel("test-models/box.obj", glm::vec3(i * 5, i, j * 5)));
}
renderer.begin();
for (int i = 0; i < models.size(); i++)
{
//add to render call
renderer.submit(models[i]);
}
renderer.end();
renderer.flush();
render init()
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VBO);
glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, NULL, GL_STATIC_DRAW);
glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glEnableVertexAttribArray(SHADER_COLOR_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const GLvoid*)0);
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, RENDERER_VERTEX_SIZE, (const GLvoid*)(offsetof(VertexData, VertexData::colour)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
//setup element
glGenBuffers(1, &m_IBO);
glBindVertexArray(0);
submission of an object
void Renderer::submit(ObjModel& object)
{
//a vector of vec3 vertices // these are indexed all objects are cubes so 8 verts per object
std::vector<glm::vec3> vertices = object.get_vertices();
std::vector<unsigned int> indices = object.get_indices();
std::vector<unsigned int> colours = object.get_colours();
//adjust the postion and give each picture a random colour & add to buffer
for (unsigned int i = 0; i < vertices.size(); i++)
{
vertices[i] += object.position;
m_VertexBuffer->vertex = vertices[i];
m_VertexBuffer->colour = colours[i];
m_VertexBuffer++;
m_VertexDataCount++;
}
m_IndiceCount += indices.size();
indiceData.insert(indiceData.end(), indices.begin(), indices.end());
}
as you can see i put each vertex (adding the position in the world) and colour in to a simple struct (VertexData*) and I add the indices to a vector.
Here is the actual draw
void Renderer::flush()
{
glBindVertexArray(m_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_IndiceCount * sizeof(unsigned int), &indiceData[0], GL_STATIC_DRAW);
// Draw the triangles !
glDrawElements(
GL_TRIANGLES, // mode
m_IndiceCount, // count
GL_UNSIGNED_INT, // type
(void*)0 // element array buffer offset
);
indiceData.clear();
m_IndiceCount = 0;
m_VertexDataCount = 0;
}
I realise the length but my question is, why does the position only work for the first cube (either the are drawing on top of each other or only the first cube draws) I can't figure this out. Is there a better way I out of ideas :)

why does the position only work for the first cube (either the are drawing on top of each other or only the first cube draws)
Because you're only drawing these first vertices, just several times:
Pushing the object (all are cubes containing indexed vertices (8) and 36 indices) to the renderer on each frame call.
Every time you call submit, you add those 8 vertices at the end of the vertex array, and you just copy the 36 indices to the end of the index array:
m_IndiceCount += indices.size();
indiceData.insert(indiceData.end(), indices.begin(), indices.end());
For the first cube, the all indices will be in the range 0 to 7, that's fine. But for all following cubes, you also will only use the indices 0 to 7 (because that are the correct indices for the local object alone). However, the second cube's vertices are at index 8 to 15 in the global vertex array. So when you draw the two cubes at once, it will re-draw the first cube just twice.
So the solution should be easy to see: You just need to offset each index in the index array by the actual base offset of the vertices in the global vertex array.

Related

OpenGL indices Array

I have a class terrain which create a grid of Quads. I do it like this
for(int z=0; z<_length;z++){
for(int x=0; x<_width;x++){
vertices.push_back(vec3((float)x*250, 0.f, (float)z*250));
}
}
for(int z=0; z<(_length-1);++z){
for(int x=0; x<(_width-1);++x){
int index = z*_width+x;
Vertex _vertices[] = {
Vertex(vertices.at(index),vec3(0, 0, 0)),
Vertex(vertices.at(index+1),vec3(0, 0, 0)),
Vertex(vertices.at(index+_width),vec3(0, 0, 0)),
Vertex(vertices.at(index+1+_width),vec3(0,0,0))
};
unsigned short indices[]= {index,index + 1,index +
_width,index + 1,index + _width,index + _width + 1};
Quad quad(_vertices, 4, indices, 6);
squares.push_back(quad);
i++;
}
}
The vertices and the logic are correct, but the indices aren't, for some reason. here is the output for this code :
But when I change this indices to this :
unsigned short indices[]= {0,1,2,1,2,3};
It works great :
The problem is I don't understand why this line
unsigned short indices[]= {index,index + 1,index +
_width,index + 1,index + _width,index + _width + 1};
doesn't work. And if it worked, my grid would consume a lot less ressources. If someone could explain me why it doesn't work, It would be great, thanks you.
In case you need to know how I draw a Quad, here is the code :
class Quad{
public:
Quad(Vertex *_vertices, int _n, unsigned short * _indices, unsigned short _numIndices){
for(int i=0; i < _numIndices; i++){
indices.push_back(_indices[i]);
}
for(int i=0; i<_n; i++){
vec3 v = vec3(_vertices[i].position, _lengthPower);
position.push_back(v);
}
glGenVertexArrays(1, &mVertexArray);
glBindVertexArray(mVertexArray);
glGenBuffers(1, &mPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*position.size(), position.data(), GL_STATIC_DRAW);
glGenBuffers(1, &mIndicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*indices.size(), indices.data(), GL_STATIC_DRAW);
}
void draw(){
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
}
~Quad(){
}
private:
std::vector<unsigned short> indices;
std::vector<vec3> position;
GLuint mVertexArray;
GLuint mPositionBuffer;
GLuint mIndicesBuffer;
};
I'm using, OpenGL, glm, glfw etc.
The posted code uses parts of two solutions to draw the terrain. Each one would work just fine by itself, but this is halfway between.
Separate Quads
Most of the code shown treats the terrain as a set of separate quads. In this case, you have length - 1 times width - 1 quad instances, each one with 4 vertices and 6 indices.
This is exactly what your Quad class implements. It stores 4 vertices and 6 indices in its own pair of VBOs, and sets up a VAO with the attribute state. Then you instantiate a Quad for each square in your terrain.
Since the vertices for each Quad are stored in its own buffers, the implication is that the indices reference vertices within this buffer. Which means that the indices are in the range 0 to 3, which is exactly what you found to be working.
The downside of this choice is that it will be inefficient for large terrains. You'll have a lot of objects (2 VBOs and 1 VBO for each quad), and need a separate draw call for rendering each quad. You're also not sharing vertices, having 4 copies of most vertices in your overall data structure.
You could actually drop the indices for this approach, and use a glDrawArrays(GL_TRIANGLE_STRIP, 4) call to draw the quad. But the other disadvantages remain.
Shared Vertices
A much more efficient approach is to store the entire terrain in a single VBO. Your code started doing that here:
for(int z=0; z<_length;z++){
for(int x=0; x<_width;x++){
vertices.push_back(vec3((float)x*250, 0.f, (float)z*250));
}
}
But then you do not follow through with it. What you need to do is store these vertices in a single VBO for the entire terrain.
Since the indices will then reference vertices by their position in this vertex buffer that contains all vertices in the terrain, the index calculations start to make much more sense:
int index = z*_width+x;
unsigned short indices[]= {index,index + 1,index +
_width,index + 1,index + _width,index + _width + 1};
This would be the indices for a quad within this overall VBO. You would want to change this to also build an index array for the entire terrain. This could look something like this:
for(int z = 0; z < _length - 1; ++z) {
for(int x = 0; x < _width; ++x) {
indices.push_back(z * width + x);
indices.push_back((z + 1) * width + x);
}
}
This can then be rendered using length - 1 triangle strips. with 2 * _width indices each. The common vertices are shared, which makes the whole thing much more efficient. You could reduce the rendering to a single draw call by using slightly more advanced features, like primitive restart.
The only downside is that it might seem less object oriented to not have objects for each quad. But that seems sort of artificial anyway. You have a terrain that consists of a grid of vertices. I see nothing wrong with having a terrain object containing this whole grid. And I like classes and objects as much as the next guy (some say too much...).

VBO Generate Verts for Chunks (Voxel Engine, Cpp)

I'm working on a Voxel Engine and I'm using VBO.
My problem is that I don't know how to generate Vertices.
I need to generate vertices for a chunk, So create a Chunk of cubes (With one VBO) from X,Y,Z coords.
How Can I do this?
First you will need to create/load the data for the voxels. Something like the following could be used to generate a 10x10x10 field of binary voxels:
Note: All code is untested and probably not optimal.
class Field {
bool data[10*10*10];
public:
bool& at(int i, int j, int k) { return data[i*10*10 + j*10 + k]; }
};
Field aField;
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
for (int k = 0; k < 10; ++k) {
aField.at(i, j, k) = !(rand() % 2);
}
}
}
I'm assuming you are after Minecraft style voxels, otherwise you probably want to use something like Marching Cubes to process the binary voxel field and pass the result to the vertex buffer code.
The next step is for each occupied voxel in the field, draw the faces associated with the cube. For this we need to create a list of all vertices and (in this case) triangle indices.
std::vector< std::array<GLfloat, 3> > vecVerts;
std::vector< std::array<GLuint, 3> > vecTris;
for (int i,j,k from 0 to 10) {
if (aField.at(i,j,k)) {
// Add vertices for eight corners of cube
vecVerts.emplace_back(dWidth*(i ), dWidth*(j ), dWidth*(k ));
vecVerts.emplace_back(dWidth*(i+1), dWidth*(j ), dWidth*(k ));
vecVerts.emplace_back(dWidth*(i ), dWidth*(j+1), dWidth*(k ));
vecVerts.emplace_back(dWidth*(i+1), dWidth*(j+1), dWidth*(k ));
vecVerts.emplace_back(dWidth*(i ), dWidth*(j ), dWidth*(k+1));
vecVerts.emplace_back(dWidth*(i+1), dWidth*(j ), dWidth*(k+1));
vecVerts.emplace_back(dWidth*(i ), dWidth*(j+1), dWidth*(k+1));
vecVerts.emplace_back(dWidth*(i+1), dWidth*(j+1), dWidth*(k+1));
// Add triangle coordinates for each triangle
vecTris.emplace_back(0, 1, 3); vecTris.emplace_back(0, 2, 3);
vecTris.emplace_back(4, 5, 7); vecTris.emplace_back(4, 6, 7);
/* todo: add remaining triangles, should be 8 more */
}
}
The above code will create two arrays in memory storing your vertex locations and the indices for the triangles. You'll notice that the code always draws 12 triangles for each voxel, it would be better to do a check if there is an adjacent occupied voxel and remove faces between such voxels, but I'll leave that for you. I also recommend you consider using glm::vec3 for storing vertex data rather then just a array.
We can now pass our arrays to OpenGL:
GLuint unVertexArray;
glGenVertexArrays(1, &unVertexArray);
glBindVertexArray(unVertexArray);
GLuint unVertexBuffer;
glGenBuffers(1, &unVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, unVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 3*vecVerts.size()*sizeof(GLfloat),
&vecVerts[0][0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
GLuint unIndiciesBuffer;
glGenBuffers(1, &unIndicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, unIndicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3*vecTris.size()*sizeof(GLuint),
&vecTris[0][0], GL_STATIC_DRAW);
glBindVertexArray(0);
Then finally, to draw our arrays:
glBindVertexArray(unVertexArray);
glDrawElements(GL_TRIANGLES, 3*vecTris.size(), GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
I might (am almost certain I) have forgotten a few things here, but this should give you a general outline of what you will need to do. For a proper explanation of most of the gl calls used above there are many online references, such as http://arcsynthesis.org/gltut/index.html

Vertex buffers and rendering problems

I am trying to approximate a curved surface using quadrilateral patches. I did it using straight forward rendering using GL_QUADS and specifying the four vertices of the quad patch.
Now I am trying to get some performance using vertex buffers and overlayed array (verNor) of vertices and normals. The problem is that I get some random shapes but not the correct shape I got previously.
Here I am putting my code:
GLenum err = glewInit();
if (GLEW_OK != err){
std::cout<<"Filed to Initialize GLEW :: "<<glewGetErrorString(err)<<std::endl;
}
verNor = new GLfloat [NA*NP*6]; // NA and NP are number of points in lets say x and y axis
indices = new GLuint [(NA)*(NP)*4]; // When the tube is cut an spread out.
// VBOs
glGenBuffers(1, &vbo_tube); // Ask the GPU driver for a buffer array. "vbo" now has the ID
glGenBuffers(1, &ibo_indices);
// For Vertices and Normals which are interleved
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6*NA*NP, NULL, GL_STATIC_DRAW);
// Obtaining the pointer to the memory in graphics buffer
buffer_verNor = glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
// For Indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 4*(NA-1)*(NP-1), NULL, GL_STATIC_DRAW);
buffer_indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER,GL_WRITE_ONLY);
// Calculate the vertices of the points around the tube. Correctness guarenteed because I can draw exactly what I wanted
// using normal stright forward GL_QUADS that is drawing quad by quad and with out any VBOs
// Calculated vertices are stored in vPoints.
for (int i=0; i<NP; i++) {
for (int j=0; j<NA; j++) {
// Calculate the normals of each and every point above and store them in v3
// Storing the vertices
verNor[6*( (i)*NA+(j) )+0] = (GLfloat)vPoints[i*NA+j].GetX();
verNor[6*( (i)*NA+(j) )+1] = (GLfloat)vPoints[i*NA+j].GetY();
verNor[6*( (i)*NA+(j) )+2] = (GLfloat)vPoints[i*NA+j].GetZ();
// Storing the Normals
verNor[6*((i-1)*NA+(j-1))+3] = (GLfloat)v3.GetX();
verNor[6*((i-1)*NA+(j-1))+4] = (GLfloat)v3.GetY();
verNor[6*((i-1)*NA+(j-1))+5] = (GLfloat)v3.GetZ();
// Calculating the indices which form the quad
indices[4*((i)*NA+(j))+0] = (GLuint) (i)*NA+j ;
indices[4*((i)*NA+(j))+1] = (GLuint) (i+1)*NA+j ;
indices[4*((i)*NA+(j))+2] = (GLuint) (i+1)*NA+j+1 ;
indices[4*((i)*NA+(j))+3] = (GLuint) (i)*NA+j+1 ;
}
}
memcpy(buffer_verNor, verNor, 6*(NA)*(NP));
glUnmapBuffer(GL_ARRAY_BUFFER); // Unmapping the buffer
memcpy(buffer_indices, indices, 4*(NA-1)*(NP-1));
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glEnable(GL_LIGHTING);
// Performing the Vertex Buffer Stuff
// For Vertices and Normals
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glVertexPointer( 3, GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)((char*)NULL + 0*sizeof(GLfloat)) );
glNormalPointer( GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)(((char*)NULL)+3*sizeof(GLfloat)) );
// For Indices
// Mapping the indices_vbo memory here
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*4*(NA-1)*(NP-1), indices, GL_STATIC_DRAW);
// Enabling all the buffers and drawing the quad patches
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
// Enabling normals and vertices to draw
glEnableClientState (GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// Drawing the patches
glDrawElements(GL_QUADS, (NA-1)*(NP-1), GL_UNSIGNED_INT,(GLvoid*)((char*)NULL));
// Disabling the buffer objects for safety
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDeleteBuffers(1, &vbo_tube);
glDeleteBuffers(1, &ibo_indices);
The gird has NA by NP points so I have to draw (NP-1)*(NA-1) quads.
Also I can only get some thing(but not correct) drawn only when I give wrong offsets and stride in glVertexPointer() and glNormalPointer() function. Correct ones i think are
vertexPointer :: Stride - 6*sizeof(GLfloat) , offset - 0(last argument)
normalPointer :: Stride - 6*sizeof(GLfloat) , offset - 3*sizeof(GLfloat)

Using C++ std::Vector in glVertexPointer OpenGL function

I have a vector of floats, this vector describes a set of triangles each triangle is described using 18 floats, first 3 are the first vertex, next 3 decribes the normal of the last vertex, and so on 3 times until describe each triangle.
i am using
std::vector< GLfloat >
to store all numbers, and this is my code to render the triangles
void Visualizer::draw3dModel()
{
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 6 * sizeof(GLfloat), this->vertexes->data() + 3);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), this->vertexes->data());
glPushMatrix();
glScalef(0.05f, 0.05f, 0.05f);
glColor3f(1,1,1);
glDrawArrays(GL_TRIANGLES, 0, this->vertexes->size());
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
this code actually works, but in certain moments I recreate the vector of floats with new triangles, it can be more or less triangles
before creating new triangles I clear the vector of vertexes, using this functions
std::vector< GLfloat >* MarchingCubesThread::getTriangles(float minvalue_scale)
{
this->generateTriangles(minvalue_scale);
for(unsigned int i=0; i < this->num_triangles; i++)
{
for(int j=0; j < 3; j++)
{
this->vertexes.push_back(this->triangles[i].p[j].x);
this->vertexes.push_back(this->triangles[i].p[j].y);
this->vertexes.push_back(this->triangles[i].p[j].z);
this->vertexes.push_back(this->triangles[i].norm.x);
this->vertexes.push_back(this->triangles[i].norm.y);
this->vertexes.push_back(this->triangles[i].norm.z);
}
}
return &(this->vertexes);
}
void MarchingCubesThread::generateTriangles(float minvalue_scale)
{
this->vertexes.clear();
this->triangles.clear();
this->triangles = MarchingCubesDataset(this->dataset->getMaxVal() * minvalue_scale, *(this->dataset), LinearInterp, this->num_triangles);
}
After playing around creating a new set of new triangles, the OpenGL render updates the mesh well, but in certain moments, I get some garbage triangles, and/or triangles that are from last iteration, and they should be cleared by calling this:
this->vertexes.clear();
this->triangles.clear();
here some screenshots taken in consecutive times:
any clues about what is happening here?, thank you
PD: for a complete source code, this is the public git repository on github:
https://github.com/joecabezas/MemoriaJoeCabezasCode/tree/visualizer
glDrawArrays expects not count of floats in your buffer, but count of vertices.
So correct call should be:
glDrawArrays(GL_TRIANGLES, 0, this->vertexes->size() / 6);
By letting glDrawArrays to draw 6 times more vertices you were displaying garbage after end of valid vector data, and sometimes it was data from previous iteration.

Rendering mesh polygons in OpenGL - very slow

I recently switched from intermediate mode and have a new rendering process. There must be something I am not understanding. I think it has something to do with the indices.
Here is my diagram: Region->Mesh->Polygon Array->3 vertex indices which references the master list of vertices.
Here my render code:
// Render the mesh
void WLD::render(GLuint* textures, long curRegion, CFrustum cfrustum)
{
int num = 0;
// Set up rendering states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Set up my indices
GLuint indices[3];
// Cycle through the PVS
while(num < regions[curRegion].visibility.size())
{
int i = regions[curRegion].visibility[num];
// Make sure the region is not "dead"
if(!regions[i].dead && regions[i].meshptr != NULL)
{
// Check to see if the mesh is in the frustum
if(cfrustum.BoxInFrustum(regions[i].meshptr->min[0], regions[i].meshptr->min[2], regions[i].meshptr->min[1], regions[i].meshptr->max[0], regions[i].meshptr->max[2], regions[i].meshptr->max[1]))
{
// Cycle through every polygon in the mesh and render it
for(int j = 0; j < regions[i].meshptr->polygonCount; j++)
{
// Assign the index for the polygon to the index in the huge vertex array
// This I think, is redundant
indices[0] = regions[i].meshptr->poly[j].vertIndex[0];
indices[1] = regions[i].meshptr->poly[j].vertIndex[1];
indices[2] = regions[i].meshptr->poly[j].vertIndex[2];
// Enable texturing and bind the appropriate texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textures[regions[i].meshptr->poly[j].tex]);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &vertices[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].u);
// Draw
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
}
}
}
num++;
}
// End of rendering - disable states
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
Sorry if I left anything out. And I really appreciate feedback and help with this. I would even consider paying someone who is good with OpenGL and optimization to help me with this.
There is no point in using array rendering if you're only rendering 3 vertices at a time. The idea is to send thousands through with a single call. That is, you render a single "Polygon Array" or "Mesh" with one call.