PDA

View Full Version : I can't understand what is wrong exactly...

BCKong
11-10-2009, 10:16 AM
I'm trying to draw a sphere using vertex array....

This is my Creating Code....

int CSampleRendererDoc::CreateSphere(double dRadius, int nSlice, int nStack,
float **ppOutTexCoords, float **ppOutNormals, float **ppOutVertices)
{
// check params
if (!ppOutNormals || !ppOutVertices || nSlice <= 0 || nStack <= 0) return -2;

//###############
//## Fill Here ##
//###############
// Longitude, Latitude.
float fLon, fLat;
float fLonStep = M_PI/static_cast<float>(nStack);
float fLatStep = M_PI/static_cast<float>(nSlice);

int iCntVertices = 0;
int iTotalVertex = ((M_2PI/fLonStep) * ((M_PI+fLatStep)/fLatStep)) * 2 * 3 + 1;

(*ppOutNormals) = new float[iTotalVertex];
(*ppOutVertices) = new float[iTotalVertex];
memset((*ppOutNormals), 0, iTotalVertex*sizeof(float));
memset((*ppOutVertices), 0, iTotalVertex*sizeof(float));

for (fLon = 0.0; fLon <= M_2PI; fLon += (fLonStep))
{
for (fLat = 0.0; fLat <= M_PI + fLatStep; fLat += (fLatStep))
{
(*ppOutNormals)[iCntVertices + 0] = dRadius * cosf(fLon)*sinf(fLat);
(*ppOutNormals)[iCntVertices + 1] = dRadius * sinf(fLon)*sinf(fLat);
(*ppOutNormals)[iCntVertices + 2] = dRadius * cosf(fLat);
(*ppOutVertices)[iCntVertices + 0] = dRadius * cosf(fLon)*sinf(fLat);
(*ppOutVertices)[iCntVertices + 1] = dRadius * sinf(fLon)*sinf(fLat);
(*ppOutVertices)[iCntVertices + 2] = dRadius * cosf(fLat);

iCntVertices += 3;

(*ppOutNormals)[iCntVertices + 0] = dRadius * cosf(fLon + fLonStep)*sinf(fLat);
(*ppOutNormals)[iCntVertices + 1] = dRadius * sinf(fLon + fLonStep)*sinf(fLat);
(*ppOutNormals)[iCntVertices + 2] = dRadius * cosf(fLat);
(*ppOutVertices)[iCntVertices + 0] = dRadius * cosf(fLon + fLonStep)*sinf(fLat);
(*ppOutVertices)[iCntVertices + 1] = dRadius * sinf(fLon + fLonStep)*sinf(fLat);
(*ppOutVertices)[iCntVertices + 2] = dRadius * cosf(fLat);

iCntVertices += 3;
}
}

return iCntVertices;
}

I'm pretty sure my creating code is not bad...

however, on the drawing codes, my application crashes at glArrayElement()

void CSampleRendererDoc::DrawSphereVA(int iSSID)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
{
glVertexPointer(3, GL_FLOAT, 0, m_aSunAndPlanets[iSSID].m_pVertexArray);
glNormalPointer(GL_FLOAT, 0, m_aSunAndPlanets[iSSID].m_pNormalArray);

glBegin(GL_TRIANGLE_STRIP);
{
for(GLint iCnt=0; iCnt<m_aSunAndPlanets[iSSID].m_iVertices; iCnt+=3)
{

glArrayElement(iCnt+0);
glArrayElement(iCnt+1);
glArrayElement(iCnt+2);
}
}
glEnd();
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}

I can't understand why does my app crash....

Thank you.

igorgiv
11-11-2009, 04:54 PM
It seems to me that what you run into is a buffer overrun - that's why your application crashes...
In other words you're trying to access an array element which is beyond the last element in your vertex array.
Something doesn't make sense to me in your second code snippet.

Isn't it supposed to be like this?

glBegin(GL_TRIANGLE_STRIP);
{
glArrayElement(0);
glArrayElement(1);
for(GLint iCnt=2; iCnt<m_aSunAndPlanets[iSSID].m_iVertices; iCnt++) {
glArrayElement(iCnt);
}
}
glEnd();

It might be helpful for you to check the definition of the triangle strip in the Red Book...

igorgiv
11-12-2009, 06:25 AM
How do you calculate m_aSunAndPlanets[iSSID].m_iVertices?
Is it equal to the return value iCntVertices from CSampleRendererDoc::CreateSphere(...)?
If yes then that's the problem as it should be divided by 3.

I wanted to apologize for the confusion I created: my code snippet is actually equivalent to yours (I got confused by the fact that you specified 3 vertices in a single loop iteration). It's just that I wanted to emphasize that the first triangle is specified by 3 vertices while each next requires only 1 vertex.