Reputation: 39
Can someone please tell me which part of the code I'm messing up?
In glDrawElements, I got like only 1/3 of the sphere with "indices.size() / 3" , which was how most tutorial was conducted, but when I tried indices.size()
, I got segmentation fault and nothing showed up.
vector<GLfloat> vertices, normals, texCoords;
vector<GLushort> indices;
void setupSphere(double r, int slice, int stack)
{
vertices.resize(slice * stack * 3);
normals.resize(slice * stack * 3);
texCoords.resize(slice * stack * 2);
float x, y, z, xz;
float nx, ny, nz, lengthInv = 1.0f / r;
float s, t;
float sliceAngle, stackAngle;
vector<GLfloat>::iterator itV = vertices.begin();
vector<GLfloat>::iterator itN = normals.begin();
vector<GLfloat>::iterator itT = texCoords.begin();
for (int i = 0; i < stack; i++)
{
stackAngle = M_PI_2 - M_PI * i / stack;
xz = r * cosf(stackAngle);
y = r * sinf(stackAngle);
for (int j = 0; j < slice; j++)
{
sliceAngle = 2 * M_PI * j / slice;
x = xz * sinf(sliceAngle);
z = xz * cosf(sliceAngle);
*itV++ = x;
*itV++ = y;
*itV++ = z;
nx = x * lengthInv;
ny = y * lengthInv;
nz = z * lengthInv;
*itN++ = nx;
*itN++ = ny;
*itN++ = nz;
s = (float)j / slice;
t = (float)i / stack;
*itT++ = s;
*itT++ = t;
}
}
int first, second;
for (int i = 0; i < stack; i++)
{
for (int j = 0; j < slice; j++)
{
first = i * slice + j;
second = first + slice + 1;
indices.push_back(first);
indices.push_back(second);
indices.push_back(first + 1);
indices.push_back(first + 1);
indices.push_back(second);
indices.push_back(second + 1);
}
}
}
void drawSphere()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
glNormalPointer(GL_FLOAT, 0, &normals[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &texCoords[0]);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, &indices[0]);
}
Upvotes: 1
Views: 1074
Reputation: 210889
You generate N stacks and M slices. Hence you can just create (N-1)x(M-1) quads.
The indices of the quads are (first, first+slice, first+1, first+slice+1), where first is the first index of the quad:
for (int i = 0; i < stack-1; i++)
{
for (int j = 0; j < slice-1; j++)
{
int first = i*slice + j;
unsigned short qi[]{first, first+slice, first+1, first+slice+1};
indices.insert(indices.end(), {qi[0], qi[2], qi[3], qi[0], qi[3], qi[1]});
}
}
See the answer to the questions Sphere Calculations and How to map texture to sphere that rendered by parametric equation using points primitive.
Upvotes: 1
Reputation: 13413
The correct is indeed indices.size() / 3
, because you must pass the number of triangles, not the number of indices.
The correct is indeed indices.size()
, because you must pass the number of elements in the array you are passing. I don't know why the tutorials you saw used / 3
variation.
As to the problem of the missing sphere section, my best guess with the provided information is that you have more than 65535 vertices, so the indices wraps around that value, because you are using GL_UNSIGNED_SHORT
.
Try changing from vector<GLushort> indices;
to vector<GLuint> indices;
and using GL_UNSIGNED_INT
in glDrawElements()
.
Alternatively, lower the values of slice
and stack
so that slice * stack * 3 <= 65535
.
Upvotes: 1