2013-07-28 3 views
-1

В моем приложении у меня есть представление, которое отображает файлы STL. Файлы STL по существу представляют собой список треугольных вершин с нормалями, у них нет индексов.OpenGL ES на iOS Несколько VBO без индексов

Каждое учебное пособие, которое я нашел, объясняет, как использовать несколько VBOs, но с индексами, и когда я пытаюсь использовать drawArrays, а не drawElements, это не сработает. Я новичок в OpenGL и был бы очень признателен, если бы кто-то мог предоставить примеры кода для использования нескольких VBO для настройки и рисования их без индексов.

Вот как я пытаюсь сделать это сейчас безрезультатно. SetupGL:

[EAGLContext setCurrentContext:self.context]; 

[self loadShaders]; 

self.effect = [[GLKBaseEffect alloc] init]; 
self.effect.light0.enabled = GL_TRUE; 
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f); 

glEnable(GL_DEPTH_TEST); 
glClearColor(0.88f, 0.88f, 0.88f, 1.0f); 

//---- First Vertex Array Object -------- 
glGenVertexArraysOES(1, &_vertexArray); 
glBindVertexArrayOES(_vertexArray); 

glBindVertexArrayOES(_vertexArray); 

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, verticesBuff, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 

//----- Second Vertex Array Object ---------- 
glGenBuffers(1, &_gridVertexBuffer); 

glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, gridVertCount*sizeof(gridVerticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW); 

glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 

glBindBuffer(GL_ARRAY_BUFFER,0); 
glBindVertexArrayOES(0); 

И это мой Жеребьевка код:

glBindVertexArrayOES(_vertexArray); 

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glUseProgram(_program); 
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
glDrawArrays(GL_TRIANGLES, 0, vertCount); 

///////// second VBO and shader program: 
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer); 
glUseProgram(_program); 
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
glDrawArrays(GL_TRIANGLES, 0, 108); 

Кроме того, здесь есть код, который я использовал до этого не делаю как массивы, но это не делает один (verticesBuff). SetupGL:

[EAGLContext setCurrentContext:self.context]; 

[self loadShaders]; 

self.effect = [[GLKBaseEffect alloc] init]; 
self.effect.light0.enabled = GL_TRUE; 
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f); 

glEnable(GL_DEPTH_TEST); 
glClearColor(0.88f, 0.88f, 0.88f, 1.0f); 

glGenVertexArraysOES(1, &_vertexArray); 
glBindVertexArrayOES(_vertexArray); 

glGenBuffers(1, &_gridVertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer); 
glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 
glBufferData(GL_ARRAY_BUFFER, 108 * sizeof(gridVerticesBuff), NULL, GL_STATIC_DRAW); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(gridVerticesBuff) * 108, gridVerticesBuff); 


glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verticesBuff) * vertCount * 3, verticesBuff); 

glBindVertexArrayOES(0); 

А вот код Жеребьевка:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

if (loaded) { 
    // Render the object with GLKit 
    [self.effect prepareToDraw]; 


    glBindVertexArrayOES(_gridVertexArray); 
    glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer); 
    glDrawArrays(GL_TRIANGLES, 0, 108); 

    glBindVertexArrayOES(_vertexArray); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
    glDrawArrays(GL_TRIANGLES, 0, vertCount); 
} 
+0

Как и вы. Делайте все так же, как и с индексами, просто без индексного буфера и вместо 'glDrawArrays' (и с вершинами, выложенными в порядке треугольника, конечно). Будьте уверены, что это прекрасно работает. Если это не для вас, тогда опубликуйте свой фактический код и опишите немного больше *, в каком виде * он * «не работает» *. –

+0

Хорошо, я опубликовал 2 версии моего кода, ни один из которых не работает с несколькими VBOs, но один из них отобразит 1 из них. – harryisaac

ответ

0

Это трудно, чтобы точно знать, что это неправильно, не видя кода, но если вы будете следовать этим общие шаги, которые вы должны быть в состоянии фигуры это из. Существует мало различий между индексированными и плоскими данными. Использование VBOs будет проще, если вы поймете, что они делают. По сути VBOs позволяют предварительно загружать общие данные вершин на графическую карту, поэтому ее не нужно загружать при каждом обращении с призывом. Имея это в виду, вам нужно подумать о том, как упаковать все данные вершин, используемые в обычном обратном вызове, в один буфер памяти.

Создание буфера:

glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STATIC_DRAW); /* totalBufferSize is sizeof vertices buffer + sizeof normals buffer */ 
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexBufferSize, vertexBuffer); /* offset 0 */ 
glBufferSubData(GL_ARRAY_BUFFER, vertexBufferSize, normalBufferSize, normalBuffer); /* offset vertexbufferSize */ 

Draw Буфер:

glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glVertexAttribPointer(VERTEX_ATTRIB ..., ((char*)NULL) + 0); /* start at beginning (0 offset) of the vertex buffer */ 
glVertexAttribPointer(NORMAL_ATTRIB ..., ((char*)NULL) + vertexBufferSize); /* start at normal subdata (offset vertexBufferSize) of the vertex buffer */ 

glDrawArrays(..., vertexCount); 

(char*)NULL вещь может выглядеть немного странно. Вместо того, чтобы передавать указатель на буфер в ОЗУ, вы передаете смещение в привязанный к настоящему времени VBO. Аргументам функции по-прежнему требуется указатель, поэтому адрес указателя используется как смещение. Понять NULL равен 0 и обработать код, как будто (char*)NULL + не существует.

+0

Хорошо, я добавил свой код, чтобы показать, что я делаю сейчас. Я также пробовал свой код с моими переменными, которые не работали. Он ничего не делал. – harryisaac

+0

@ harry1795671 Вы не упомянули о ВАО, плохо взгляните. –

+0

@ harry1795671 vertCount * sizeof (verticesBuff) * 3 * 2 это выглядит неправильно, sizeof в случае массива стека даст вам весь размер массива. С точки зрения указателя вы укажете размер указателя. Вершины плотно упакованы? Если вы уверены, что шаг правилен? –

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