i am trying to build a tessellated rectangle based from the answer to this question.
How to build data for a tessellated rectangle
My final result has only the half rectangle drawn and the geometry looks broken.
This is my code which i have tried to port to VAO and VBO.
Generating the Data.
std::vector<float> verticesRect;
std::vector<unsigned int> indicesRect;
nSegments = 16; mSegments = 16;
void Rectangle2::Generate()
{
const int n8 = nSegments * 8; // size of VBO gfx data
const int sz0 = mSegments * n8; // size of VBO gfx data
const int sz1 = (mSegments - 1) * (nSegments - 1) * 6;// size of indices
verticesRect.clear();
indicesRect.clear();
int a,i, j, k, b;
GLfloat x, y, z, dx, dy, l;
glm::vec3 u, v, nor;
dx = 2.0 * (width / float(nSegments - 1));
dy = 2.0 * (height / float(mSegments - 1));
for (a = 0,y = -height, j = 0; j < mSegments; j++, y += dy)
for (x = -width, i = 0; i < nSegments; i++, x += dx)
{
z = 20.0 * sin((x * x) + (y * y));
verticesRect.push_back(x); a++;
verticesRect.push_back(y); a++;
verticesRect.push_back(z); a++;
// Normal ( will be recomputed later)
verticesRect.push_back(0.0); a++;
verticesRect.push_back(0.0); a++;
verticesRect.push_back(1.0); a++;
// TexCoord
verticesRect.push_back((x + width) / (width + width)); a++;
verticesRect.push_back((y + height) / (height + height)); a++;
}
// triangulation indices
for(a = 0, j = 1; j < mSegments; j++ )
for (i = 1; i < nSegments; i++)
{
b = ((nSegments * j) + i) * 8;
// First triangle per quad
indicesRect.push_back(b - 8); a++;
indicesRect.push_back(b - 8 - n8); a++;
indicesRect.push_back(b); a++;
// Second triangle per quad
indicesRect.push_back(b - 8 - n8); a++;
indicesRect.push_back(b - n8); a++;
indicesRect.push_back(b); a++;
// recompute inner normals
for (k = 0; k < 3; k++) {
u[k] = verticesRect[indicesRect[a - 6] + k] - verticesRect[indicesRect[a - 4] + k];
v[k] = verticesRect[indicesRect[a - 5] + k] - verticesRect[indicesRect[a - 4] + k];
}
glm::vec3 cross1 = crossProduct(u, v);
cross1 = glm::normalize(cross1);
for (k = 0; k < 3; k++) {
u[k] = verticesRect[indicesRect[a - 3] + k] - verticesRect[indicesRect[a - 1] + k];
v[k] = verticesRect[indicesRect[a - 2] + k] - verticesRect[indicesRect[a - 1] + k];
}
glm::vec3 cross2 = crossProduct(u, v);
cross2 = glm::normalize(cross2);
for (k = 0; k < 3; k++) {
verticesRect[indicesRect[a - 1] + 3 + k] = 0.5 * (cross1[k] + cross2[k]);
}
}
}
Creating the VAO and VBO
void Rectangle2::init()
{
Generate();
glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VBO);
glGenBuffers(1, &m_EBO);
glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, verticesRect.size() * sizeof(float), &verticesRect[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indicesRect.size(), &indicesRect[0], GL_STATIC_DRAW);
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)));
isInited = true;
}
Drawing the Object.
glBindVertexArray(m_VAO);
glDrawElements(GL_TRIANGLES, indicesRect.size() - 1, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);