I'm trying to use a 2D vector array of GLfloats to draw a grid. I cant seem to get the right code for glBufferData with a 2d vector instead of the examples I see online which are for 1D.
UPDATED - I have to multply glBufferData by 2 or else only half the grid gets drawn....
struct point
{
GLfloat x;
GLfloat y;
};
float gridMinus = flatGrid_lines / 2.0f;
//point Vertices[20][20];
GLfloat HEIGHT = 20.0f;
GLfloat WIDTH = 20.0f;
vector<point> VerticesD(flatGrid_lines * flatGrid_lines);
//VERTICAL LINES
for (int i = 0; i < flatGrid_lines; i++)
{
for (int j = 0; j < flatGrid_lines; j++)
{
VerticesD[i + j * flatGrid_lines].x = (j - gridMinus) / gridMinus;
VerticesD[i + j * flatGrid_lines].y = (i - gridMinus) / gridMinus;
}
}
glGenVertexArrays(1, &vao_grid1);
glBindVertexArray(vao_grid1);
glGenBuffers(1, &vbo_grid1);
glBindBuffer(GL_ARRAY_BUFFER, vbo_grid1);
glBufferData(GL_ARRAY_BUFFER, VerticesD.size() * 2 * sizeof(GLfloat), &VerticesD[0], GL_STATIC_DRAW);
Related
I'm trying to center a square texture on a circle using openGL, I have created a loop that fills an array with my circle coordinates, followed by my +/-normals for lighting, finally followed by my (x,y) for the texture coordinates.
For some reason the image ends up kind of smooshed instead of evenly spreading out around the circle. I'm ot sure if my calculations for the polar to cartesian coordinates are a little off or what.
Below is a section of the code as well as an image of the output.
{
/*FIX STILL NEEDED TO DYNAMICALLY UPDATE THESE VALUES*/
//When changing numberOfSides need to also update indices[] to numberOfSides*3 and allCircleVertices[] to numberOfVertices*numberOfSides
GLfloat x = 0;
GLfloat y = 0;
GLfloat z = 0;
GLfloat radius = 4;
GLuint numberOfSides = 20;
GLuint numberOfVertices = numberOfSides + 1;
GLuint k = 22;
GLuint angle = 360 / numberOfSides;
GLushort indices[60];
GLfloat doublePi = 2.0f * M_PI;
GLfloat* circleVerticesX = new GLfloat[numberOfVertices];
GLfloat* circleVerticesY = new GLfloat[numberOfVertices];
GLfloat* circleVerticesZ = new GLfloat[numberOfVertices];
GLfloat allCircleVertices[420]; /*= new GLfloat[numberOfVertices * numberOfSides];*/
circleVerticesX[0] = x;
circleVerticesY[0] = y;
circleVerticesZ[0] = z;
//Loop to determine angles between vertices
for (int i = 1; i < numberOfVertices; i++)
{
circleVerticesX[i] = x + (radius * cos(i * doublePi / numberOfSides));
circleVerticesY[i] = y;
circleVerticesZ[i] = z + (radius * sin(i * doublePi / numberOfSides));
}
//Loop to fill array with vertices
for (int i = 0; i < numberOfVertices; i++)
{
allCircleVertices[i * 8] = circleVerticesX[i];
allCircleVertices[(i * 8) + 1] = circleVerticesY[i];
allCircleVertices[(i * 8) + 2] = circleVerticesZ[i];
allCircleVertices[(i * 8) + 3] = 0.0f;
allCircleVertices[(i * 8) + 4] = 1.0f;
allCircleVertices[(i * 8) + 5] = 0.0f;
if ((i * 8) + 6 == 6)
{
allCircleVertices[6] = 0.5f;
}
else
{
allCircleVertices[(i * 8 + 6)] = 0.5 * (sin(angle * i));
}
if ((i * 8 + 7) == 7)
{
allCircleVertices[7] = 0.5f;
}
else
{
allCircleVertices[(i * 8 + 7)] = 0.5 * (cos(angle * i));
}
}
//For loop to fill Indices array with correct indices based on number of sides
for (int i = 0; i < numberOfSides; i++)
{
if (i == (numberOfSides - 1))
{
indices[i * 3] = 0;
indices[(i * 3) + 1] = indices[2];
indices[(i * 3) + 2] = numberOfSides;
//cout << indices[i * 3] << ", " << indices[(i * 3) + 1] << ", " << indices[(i * 3) + 2] << endl;
}
else
{
indices[i * 3] = 0;
indices[(i * 3) + 1] = i + 2;
indices[(i * 3) + 2] = i + 1;
//cout << indices[i * 3] << ", " << indices[(i * 3) + 1] << ", " << indices[(i * 3) + 2] << endl;
}
}
const GLuint floatsPerVertex = 3;
const GLuint floatsPerNormal = 3;
const GLuint floatsPerUV = 2;
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create 2 buffers: first one for the vertex data; second one for the indices
glGenBuffers(2, mesh.vbos);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbos[0]); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(allCircleVertices), allCircleVertices, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
mesh.nIndices = sizeof(indices) / sizeof(indices[0]) * (floatsPerVertex + floatsPerNormal + floatsPerUV);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Strides between vertex coordinates is 6 (x, y, z, r, g, b, a). A tightly packed stride is 0.
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerNormal + floatsPerUV);// The number of floats before each
// Create Vertex Attribute Pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerNormal, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float)* floatsPerVertex));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, floatsPerUV, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float)* (floatsPerVertex + floatsPerNormal)));
glEnableVertexAttribArray(2);
}
I need to generate procedural terrain using Noise (using Perlin noise) in OpenGL. Each time the application runs a new terrain, it needs to be generated using a new seed. (Do not use external library.) Is there a method/requirement needed when making a class for noise terrains. What functions/calculation i need to call and in which order ?
PS: I use Visual Studio 2019.
// Copy the array data into a float array, and scale and offset the heights.
mHeightmap.resize(NumRows * NumCols, 0);
for( int i = 0; i < NumRows * NumCols; ++i)
{
mHeightmap[i] = (float)in[i] * HeightScale;
}
// A height for each vertex
{
std::vector<unsigned char> in(NumRows * NumCols);
// Open the file.
std::ifstream inFile;
inFile.open(heightmapName.c_str(), std::ios_base::binary);
if (inFile)
{
// Read the RAW bytes.
inFile.read((char*)&in[0], (std::streamsize)in.size());
// Done with file.
inFile.close();
}
// Copy the array data into a float array, and scale and offset the heights.
mHeightmap.resize(NumRows * NumCols, 0);
for( int i = 0; i < NumRows * NumCols; ++i)
{
mHeightmap[i] = (float)in[i] * HeightScale;
}
void Terrain::CreateVAO()
{
std::vector<GLfloat> vertices;
vertices.reserve(NumCols * NumRows * 8);
float invTwoDX = 1.0f / (2.0f * CellSpacing);
float invTwoDZ = 1.0f / (2.0f * CellSpacing);
//vertices
for ( int z = 0; z < NumRows; z++)
{
for ( int x = 0; x < NumCols; x++)
{
//vertex data
int i = z * NumCols + x;
vertices.push_back((float)x*CellSpacing);
vertices.push_back(mHeightmap[i]);
vertices.push_back((float)z * CellSpacing);
//normal data
glm::vec3 _N = { 0.0f,1.0f, 0.0f };
if(z >= 1 && z < NumRows -1 && x >= 1 && z < NumCols - 1)
{
float t = mHeightmap[(z - 1) * NumCols + x];
float b = mHeightmap[(z + 1) * NumCols + x];
float l = mHeightmap[z * NumCols + x - 1];
float r = mHeightmap[z * NumCols + x + 1];
glm::vec3 tanZ(0.0f, (b - t) * invTwoDZ, 1.0f);
glm::vec3 tanX(1.0f, (r - l) * invTwoDX, 0.0f);
glm::vec3 _C, _N;
_C = glm::cross(tanZ, tanX);
_N = glm::normalize(_C);
}
vertices.push_back(_N.x);
vertices.push_back(_N.y);
vertices.push_back(_N.z);
vertices.push_back((float)x);
vertices.push_back((float)z);
}
}
std::vector<GLuint> indices;
vertices.reserve((NumCols-1)*(NumRows -1)*6);
//indices
for ( int z = 0; z < NumRows-1; z++)
{
for ( int x = 0; x < NumCols-1; x++)
{
GLint a = z * NumCols + x;
GLint b = (z +1) * NumCols + x;
GLint c = z * NumCols + (x+1);
GLint d = (z+1) * NumCols + (x+1);
indices.push_back(c);
indices.push_back(a);
indices.push_back(b);
indices.push_back(c);
indices.push_back(b);
indices.push_back(d);
}
}
indexcount = indices.size();
GLuint VBO, EBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
8 * sizeof(GLfloat), //Strude of the single vertex(pos)
(GLvoid*)0); //Offset from beginning of Vertex
glEnableVertexAttribArray(0);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
8 * sizeof(GLfloat), //Strude of the single vertex(pos+color)
(GLvoid*)(3 * sizeof(GLfloat))); //Offset from beginning of Vertex
glEnableVertexAttribArray(1);
glVertexAttribPointer(
2,
2, //2 float component for coordinates
GL_FLOAT,
GL_FALSE,
8 * sizeof(GLfloat), //Strude of the single vertex(pos+color+texture)
(GLvoid*)(6 * sizeof(GLfloat)));//Offset from beginning of Vertex
glEnableVertexAttribArray(2);
I'm not sure if I see usage of Perlin noise in your code. Try this lightweight, easy to integrate library:
https://github.com/Auburn/FastNoise which has Perlin and tons of other useful stuff like a visualizer.
Usage is as simple as
noise.GetNoise((float)x, (float)y); which you can plug into your height function
I am porting old fixed function pipeline code to shaders and for the torus geometry i am not able to create the correct indexes.
The old code
int CTorus::initevVertex2Ds()
{
const float twopi = 2.0 * M_PI;
// factor for texture coordinate per step in X/Y
const float fXtex = 1. / float(m_nCorners);
const float fYtex = 1. / float(m_nTesselation);
int i;
// go around cross section
for (i = 0; i < m_nTesselation; i++) {
register int base = i * m_nCorners;
register int baseTX = i * (m_nCorners+1);
// Y texture coordinate ...
m_texcoord[baseTX].x = fYtex * float(i);
// go around top view
const float f2Pi_i_corners = (twopi * float(i+m_nTesselation/2)) / float(m_nTesselation);
const float evVertex2D_z = m_fRadiusCrossSect * fsin(f2Pi_i_corners);
const float fXY = m_fRadiusTorus + m_fRadiusCrossSect * fcos(f2Pi_i_corners);
for (int j = 0; j < m_nCorners; j++) {
register int index = base + j;
const float fXj = fcos(twopi*float(j)/m_nCorners);
const float fYj = fsin(twopi*float(j)/m_nCorners);
m_GLVertex2D[index].x = fXY * fXj;
m_GLVertex2D[index].y = fXY * fYj;
m_GLVertex2D[index].z = evVertex2D_z;
m_texcoord[baseTX + j].y = 1. - fXtex * float(j);
m_texcoord[baseTX + j].x = m_texcoord[baseTX].x;
const float nx = m_GLVertex2D[index].x - m_fRadiusTorus * fXj;
const float ny = m_GLVertex2D[index].y - m_fRadiusTorus * fYj;
const float nz = m_GLVertex2D[index].z;
const float n = fsqrt(nx*nx + ny*ny + nz*nz);
m_norm[index].x = nx/n;
m_norm[index].y = ny/n;
m_norm[index].z = nz/n;
}
m_texcoord[baseTX + m_nCorners].y = 0.;
m_texcoord[baseTX + m_nCorners].x = m_texcoord[baseTX].x;
}
for (i=0; i<=m_nCorners; i++) {
m_texcoord[(m_nCorners+1)*m_nTesselation+i].y = m_texcoord[i].y;
m_texcoord[(m_nCorners+1)*m_nTesselation+i].x = 1.;
}
return 0;
}
This is the code where i have ported it to the shaders but i am not able to creat indexes for the element array buffer correctly
void Torus::init()
{
const float twopi = 2.0 * M_PI;
// factor for texture coordinate per step in x/y
const float fXtex = 1.0 / float(m_nCorners);
const float fYtex = 1.0 / float(m_nTesselation);
int i;
for (i = 0; i < m_nTesselation; i++)
{
register int base = i * m_nCorners;
register int baseTX = i * (m_nCorners + 1);
// go around top view
const float f2Pi_i_corners = (twopi * float(i + m_nTesselation / 2)) / float(m_nTesselation);
const float evVertex2D_z = m_fRadiusCrossSect * sinf(f2Pi_i_corners);
const float fXY = m_fRadiusTorus + m_fRadiusCrossSect * cosf(f2Pi_i_corners);
for (int j = 0; j < m_nCorners; j++)
{
register int index = base + j;
const float fXj = cosf(twopi*float(j) / m_nCorners);
const float fYj = sinf(twopi*float(j) / m_nCorners);
data.push_back(fXY * fXj);
data.push_back(fXY * fYj);
data.push_back(evVertex2D_z);
const float nx = (fXY * fXj) - m_fRadiusTorus * fXj;
const float ny = (fXY * fYj) - m_fRadiusTorus * fYj;
const float nz = evVertex2D_z;
const float n = sqrt(nx*nx + ny * ny + nz * nz);
data.push_back(nx / n);
data.push_back(ny / n);
data.push_back(nz / n);
// Pushing texture coordinates
data.push_back(0.0);
data.push_back(0.0);
}
}
std::vector<unsigned int> stdvecIndex;
unsigned int index;
// Create the indexes
for (int i = 0; i < m_nTesselation; i++)
{
index = ((i + 1) % m_nTesselation) * m_nCorners;
stdvecIndex.push_back(index);
for (int j = 0; j < m_nCorners; j++)
{
index = i * m_nCorners + j;
stdvecIndex.push_back(index);
index = ((i + 1) % m_nTesselation) * m_nCorners + ((j + 1) % m_nCorners);
stdvecIndex.push_back(index);
}
index = i * m_nCorners;
stdvecIndex.push_back(index);
}
if (!isInited)
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, stdvecIndex.size() * sizeof(unsigned int), &stdvecIndex[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)( 3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)(6 * sizeof(float)));
}
}
I have tried creating the indexes for the buffer but unfortunately i get inter mangled geometry instead of a torus.
The stride (5th) argument to glVertexAttribPointer is wrong. stride specifies the byte offset between consecutive generic vertex attributes.
The size of the attributes is 8 (x, y, z, nx, ny, nz, u, v).
Hence stride has to be 8 * sizeof(float) rather than 3 * sizeof(float):
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
Is there an algorithm that could be used to generate a plane using the GL_TRIANGLES primitive type?
Here's my current function:
Mesh* Mesh::CreateMeshPlane(vec2 bottomleft, ivec2 numvertices, vec2 worldsize){
int numVerts = numvertices.x * numvertices.y;
float xStep = worldsize.x / (numvertices.x - 1);
float yStep = worldsize.y / (numvertices.y - 1);
VertexFormat* verts = new VertexFormat[numVerts];
for (int y = 0; y < numvertices.y; y++)
{
for (int x = 0; x < numvertices.x; x++)
{
verts[x + (y * numvertices.x)].pos.x = bottomleft.x + (xStep * x);
verts[x + (y * numvertices.x)].pos.y = bottomleft.y + (yStep * y);
verts[x + (y * numvertices.x)].pos.z = 0;
}
}
Mesh* pMesh = new Mesh();
pMesh->Init(verts, numVerts, indices, 6, GL_STATIC_DRAW);
glPointSize(10.0f);
pMesh->m_PrimitiveType = GL_POINTS;
delete[] verts;
return pMesh;}
I'm just unsure how to implement indices into the for loop to be able to know which points to draw.
What I think I need to know:
Each square will be made up of 2 triangles, each square requiring 6 indices
Currently I'm drawing from the bottom left
I need to know how many squares I'll have from the numbers passed in
Maybe something like this:
int width = 4;
int length = 6;
int height = 1;
std::vector<float> planeVertices;
for (int x = 0; x < width - 1; x++) {
for (int z = 0; z < length - 1; z++) {
planeVertices.push_back(x);
planeVertices.push_back(height);
planeVertices.push_back(z);
planeVertices.push_back(x);
planeVertices.push_back(height);
planeVertices.push_back(z + 1);
planeVertices.push_back(x + 1);
planeVertices.push_back(height);
planeVertices.push_back(z + 1);
planeVertices.push_back(x);
planeVertices.push_back(height);
planeVertices.push_back(z);
planeVertices.push_back(x + 1);
planeVertices.push_back(height);
planeVertices.push_back(z);
planeVertices.push_back(x + 1);
planeVertices.push_back(height);
planeVertices.push_back(z + 1);
}
}
...
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, planeVertices.size() * sizeof(float), planeVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(0);
...
glDrawArrays(GL_TRIANGLES, 0, (width - 1) * (length - 1) * 6);
This code creates an std::vector<float> and adds the plane vertices to it. The nested for loops add two triangles for every unit of the plane (so with width as 4 and length as 6 the plane will be 4 units by 6 units, and will be made of 6 * 4 * 2 = 48 triangles). The height of the plane is set by the height variable. This only generates flat planes, but a simple transformation lets you rotate and scale this as you need.
WARNING: this code is untested.
Just to close this question here's how I did it:
Mesh* Mesh::CreateMeshPlane(vec3 bottomleft, ivec2 numvertices, vec2
worldsize, vec2 texturerepetition)
{
int numVerts = numvertices.x * numvertices.y;
int numFaces = (numvertices.x - 1) * (numvertices.y - 1);
int numIndices = numFaces * 6;
float xStep = worldsize.x / (numvertices.x - 1);
float yStep = worldsize.y / (numvertices.y - 1);
float zStep = worldsize.y / (numvertices.y - 1);
float uStep = texturerepetition.x / (numvertices.x - 1);
float vStep = texturerepetition.y / (numvertices.y - 1);
VertexFormat* verts = new VertexFormat[numVerts];
unsigned int* indices = new unsigned int[numIndices];
for (int y = 0; y < numvertices.y; y++)
{
for (int x = 0; x < numvertices.x; x++)
{
verts[x + (y * numvertices.x)].pos.x = bottomleft.x + (xStep * x);
verts[x + (y * numvertices.x)].pos.y = bottomleft.y;
verts[x + (y * numvertices.x)].pos.z = bottomleft.z + (zStep * y);
verts[y * numvertices.x + x].uv.x = uStep * x;
verts[y * numvertices.x + x].uv.y = vStep * y;
}
}
int offset = 0;
for (int i = 0; i < numIndices; i++)
{
// The bottom left index of the current face
// + the offset to snap back when we hit the edge
unsigned int cornerIndex = i/6 + offset;
// If we reach the edge we increase the offset so that it goes to the next bottom left
if ((cornerIndex + 1)%numvertices.x == 0)
{
offset++;
cornerIndex++; // Adding new offset to the bottom left
}
// First triangle
indices[i] = (unsigned int)cornerIndex;
i++;
indices[i] = (unsigned int)cornerIndex + numvertices.x;
i++;
indices[i] = (unsigned int)cornerIndex + numvertices.x + 1;
i++;
// Second triangle
indices[i] = (unsigned int)cornerIndex;
i++;
indices[i] = (unsigned int)cornerIndex + numvertices.x + 1;
i++;
indices[i] = (unsigned int)cornerIndex + 1;
}
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
Mesh* pMesh = new Mesh();
pMesh->Init(verts, numVerts, indices, numIndices, GL_STATIC_DRAW);
delete[] verts;
return pMesh;
}
Workflow:
1. Calculating number of faces I need, then the number of indices
2. Creating an offset that is added to the cornerIndex when we realize we hit the edge of the vertex array (by using modulus numvertices.y)
3. Doing simple math to draw corners in correct order based on the cornerIndex
Notes:
1. Im drawing using GL_TRIANGLES as the primitive type
2. Drawing from bottom left to top right
3. cornerIndex therefore is the bottom left of the current square we're drawing on
Hope someone can find this helpful!
I had glDrawElements working consistently, initially with a simple box and then with more complex shapes made up of a large amount of vertices. Then it simply stopped drawing the mesh. I have taken the code back to it's most basic, just drawing 2 triangles to make a 2D square. This also no longer works.
void createMesh(void) {
float vertices[12];
vertices[0] = -0.5; vertices[1] = -0.5; vertices[2] = 0.0; // Bottom left corner
vertices[3] = -0.5; vertices[4] = 0.5; vertices[5] = 0.0; // Top left corner
vertices[6] = 0.5; vertices[7] = 0.5; vertices[8] = 0.0; // Top Right corner
vertices[9] = 0.5; vertices[10] = -0.5; vertices[11] = 0.0; // Bottom right corner
short indices[] = { 0, 1, 2, 0, 2, 3};
glEnableClientState(GL_VERTEX_ARRAY); // Enable Vertex Arrays
glVertexPointer(3, GL_FLOAT, 0, vertices); // Set The Vertex Pointer To Our Vertex Data
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_SHORT, indices);
glDisableClientState(GL_VERTEX_ARRAY);
}
The more advanced code that used to work is shown below:
void createMesh(void) {
float vertices[(amountOfHorizontalScans * 480 * 3)];// Amount of vertices
//build the array of vertices from a matrix of data
int currentVertex = -1;
std::vector <std::vector<double>> currentPointCloudMatrix = distanceCalculator.getPointCloudMatrix();
double plotY = 0;
double plotX = 0;
for (int j = 0; j < currentPointCloudMatrix.size(); j++){
std::vector <double> singleDistancesVector = currentPointCloudMatrix.at(j);
for (int i = 0; i < singleDistancesVector.size(); i++){
if (singleDistancesVector.at(i) != 0){
vertices[++currentVertex] = plotX;
vertices[++currentVertex] = plotY;
vertices[++currentVertex] = singleDistancesVector.at(i);
}
plotX += 0.1;
}
plotX = 0;
plotY += 0.2; //increment y by 0.02
}
//Creating the array of indices, 480 is the amount of columns
int i = 0;
short indices2[(amountOfHorizontalScans * 480 * 3)];
for (int row = 0; row<amountOfHorizontalScans - 1; row++) {
if ((row & 1) == 0) { // even rows
for (int col = 0; col<480; col++) {
indices2[i++] = col + row * 480;
indices2[i++] = col + (row + 1) * 480;
}
}
else { // odd rows
for (int col = 480 - 1; col>0; col--) {
indices2[i++] = col + (row + 1) * 480;
indices2[i++] = col - 1 + +row * 480;
}
}
}
glEnableClientState(GL_VERTEX_ARRAY); // Enable Vertex Arrays
glVertexPointer(3, GL_FLOAT, 0, vertices); // Set The Vertex Pointer To Our Vertex Data
glDrawElements(GL_TRIANGLE_STRIP, (amountOfHorizontalScans * 480 * 3), GL_UNSIGNED_SHORT, indices2);
glDisableClientState(GL_VERTEX_ARRAY);
}
I am at a complete loss as to why it has stopped working as it was working perfectly for a good number of runs, then just completely stopped. I have debugged through and all the code is being reached, also the vertices and indices are populated with data. What could cause this to stop working?
EDIT:
So I am really quite confused now. I came back to this issue this morning, and everything worked fine again, as in the meshes would draw with no issues. After doing some tests and running the program a number of times it has simply stopped drawing meshes again!
Could this be something memory related? I am not 100% sure on how glDrawElements stores the data passed to it, so could it be that I have to clear something somewhere that I keep filling up with data?
You cannot allocate dynamically arrays in stack:
short indices2[(amountOfHorizontalScans * 480 * 3)];
In code:
short indices2[(amountOfHorizontalScans * 480 * 3)];
for (int row = 0; row<amountOfHorizontalScans - 1; row++) {
if ((row & 1) == 0) { // even rows
for (int col = 0; col<480; col++) {
indices2[i++] = col + row * 480;
indices2[i++] = col + (row + 1) * 480;
}
}
else { // odd rows
for (int col = 480 - 1; col>0; col--) {
indices2[i++] = col + (row + 1) * 480;
indices2[i++] = col - 1 + +row * 480;
}
}
}
Must be
short* indices2 = new short[(amountOfHorizontalScans * 480 * 3)];
than free allocated memory
delete [] indices2;
Triangle strip is pretty tricky mode did you try to work directly with GL_TRIANGLES.