2012-05-06 4 views
2

У меня возникают проблемы с извлечением сферы.OpenGL VBOs: рисование сферы

std::vector<GLfloat> ballVerts; 

for(int i = 0; i <= 40; i++) 
{ 
    double lat0 = M_PI * (-0.5 + (double) (i - 1)/40); 
    double z0 = sin(lat0); 
    double zr0 = cos(lat0); 

    double lat1 = M_PI * (-0.5 + (double) i/40); 
    double z1 = sin(lat1); 
    double zr1 = cos(lat1); 

    for(int j = 0; j <= 40; j++) 
    { 
     double lng = 2 * M_PI * (double) (j - 1)/40; 
     double x = cos(lng); 
     double y = sin(lng); 

     ballVerts.push_back(x * zr0); //X 
     ballVerts.push_back(y * zr0); //Y 
     ballVerts.push_back(z0);  //Z 

     ballVerts.push_back(0.0f); 
     ballVerts.push_back(1.0f); 
     ballVerts.push_back(0.0f); 
     ballVerts.push_back(1.0f); //R,G,B,A 

     ballVerts.push_back(x * zr1); //X 
     ballVerts.push_back(y * zr1); //Y 
     ballVerts.push_back(z1);  //Z 

     ballVerts.push_back(0.0f); 
     ballVerts.push_back(1.0f); 
     ballVerts.push_back(0.0f); 
     ballVerts.push_back(1.0f); //R,G,B,A 
    } 
} 

glGenBuffers(1, &ballVbo); 
glBindBuffer(GL_VERTEX_ARRAY, ballVbo); 

GLuint sphereSize = 3200*7*4; //3200 vertixes * 7 floats 
glBufferData(GL_VERTEX_ARRAY,sphereSize, &ballVerts, GL_STATIC_DRAW); 



/* 
    Draw a ball 
*/ 
glBindBuffer(GL_VERTEX_ARRAY, ballVbo); 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 7*4, 0); 
glEnableClientState(GL_COLOR_ARRAY); 
glColorPointer(4, GL_FLOAT, 7*4, (void*)(3*4)); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 3200); 

glBindBuffer(GL_ARRAY_BUFFER, 0); 

Код для создания сферы штрафа в непосредственном режиме работы, но когда я положил его в VBO я получаю исключение нарушения прав доступа от glDrawArrays. Какие-либо предложения?

ответ

7
glBufferData(GL_VERTEX_ARRAY,sphereSize, &ballVerts, GL_STATIC_DRAW); 

ballVerts является не массив. Это std::vector. Принимая адрес std::vector, адрес адреса массива не содержит в пределахvector. Вы должны использовать &ballVerts[0];

+0

Это отсортировано, спасибо. Я знал, что это будет что-то маленькое ... – user1378179

+2

Если у вас есть доступ к C++ 11, вы также можете использовать метод std :: vector .data(). Это, я считаю, позволяет избежать проблемы использования оператора адреса в пустом массиве. – luke

0

лучше предварительно изменить размер вектора и использовать итератор подметать через него что-то вроде этого:

std::vector <GLfloat> vertices; 
vertices.resize(count * 3); 
... 
std::vector <GLfloat>::iterator v = vertices.begin(); 

for(U32 r = 0; r < m_prec/2; ++r) //широта 
    { 
     float const theta1 = -F_PI_BY_TWO + pi2p * r; 
     float const theta2 = theta1 + pi2p; 

     for(U32 s = 0; s < m_prec; ++s) //долгота 
     { 
      float const theta3 = s * pi2p;  

      float ex = cosf(theta3) *cosf(theta2); 
      float ey = sinf(theta2); 
      float ez = sinf(theta3) * cosf(theta2); 
      *v++ = m_x + m_radius * ex; 
      *v++ = m_y + m_radius * ey; 
      *v++ = m_z + m_radius * ez; 

т.д.

:: glVertexPointer (3, GL_FLOAT, 0, & вершины [0]) ;

будет работать

+0

Действительно ли это работает? почему я пытаюсь использовать код в промежуточном режиме, он просто дает мне круг? Также, когда я пытаюсь использовать glBegin (GL_Points) вместо этого, он просто дает мне очки, которые образуют круг. –

Смежные вопросы