Могу ли я создавать объекты буфера вершин без информации о цвете? - PullRequest
1 голос
/ 01 декабря 2011

Я хочу создать сетку прямоугольников для симуляции, где мы раскрасим прямоугольники на основе результатов расчета.

Изначально я просто хотел бы построить VBO для определения сетки.И затем в каждом кадре просто присваивайте цвета прямоугольникам.

Возможно ли это или VBO всегда "зашито" с набором цветов?Потому что все примеры, которые я нахожу в Интернете, делают это так.Они инициализируют VBO вместе с цветами, а не только с данными о положении вершин, например this :

// allocate a new buffer
glGenBuffers(1, &cubeVBO);

// bind the buffer object to use
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);

const GLsizeiptr vertex_size = NUMBER_OF_CUBE_VERTICES*NUMBER_OF_CUBE_COMPONENTS_PER_VERTEX*sizeof(GLfloat);
const GLsizeiptr color_size = NUMBER_OF_CUBE_COLORS*NUMBER_OF_CUBE_COMPONENTS_PER_COLOR*sizeof(GLubyte);

// allocate enough space for the VBO
glBufferData(GL_ARRAY_BUFFER, vertex_size + color_size, 0, GL_STATIC_DRAW);

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

VBO - это просто часть памяти, вы используете ее для ускорения работы, располагая данные на видеокарте. (Некоторое оборудование использует системную память для VBO, поэтому в этом случае выиграть немного) Я также считаю чище всегда использовать VBO, но это немного личное предпочтение.

В любом случае, вы можете создавать VBO, а затем изменять данные внутри них, так же, как часть оперативной памяти, если вам нужно менять все на VBO каждый кадр снова, это не дает выигрыша в производительности, но если вам нужно только время от времени менять материал или некоторые данные исправлены (скажем, ваши вершинные данные), тогда вы начинаете получать некоторые преимущества ...

например:

glGenBuffers(1, &vboObjects[vboGroupBeaver]);
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
glBufferData(GL_ARRAY_BUFFER, beaverVerts*8*sizeof(GLfloat), 0, GL_STATIC_DRAW);
GLvoid*  vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
NSString *path;
path = [[NSBundle mainBundle] pathForResource:@"beaver01" ofType:@"bin"];
NSFileHandle *model = [NSFileHandle fileHandleForReadingAtPath:path];
float vertice[8];
int counter = 0;
while (read([model fileDescriptor], &vertice, 8*sizeof(float))) {
    memcpy(vbo_buffer, vertice, 8*sizeof(GLfloat));        // 0
    vbo_buffer += 8*sizeof(GLfloat);
    counter++;
}
NSLog(@"Vertices %1i",counter);
glUnmapBufferOES(GL_ARRAY_BUFFER); 

Этот фрагмент кода загружает модель в VBO (vboGroupBeaver), в данном примере это первый ключевой кадр анимации. Все данные теперь в VBO, если я сделаю это после:

    glVertexPointer(3, GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL));
    glNormalPointer(GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
    glTexCoordPointer(2, GL_FLOAT,8*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat))); 
    glDrawArrays(GL_TRIANGLES, 0, beaverVerts);

Я нарисовал бобра ... (Обратите внимание, что я использую данные вершин с чередованием, поэтому вызовы указателей имеют дополнительную информацию). В вашем случае у вас будет Цветовой указатель вместо Текстурного указателя.

Теперь, если вы хотите изменить что-то, все, что вам нужно сделать, это glMapBufferOES на буфер var и использовать его для изменения только тех частей, которые вам нужны. Что-то вроде:

vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
for (int i = start; i < end; i++) {
   vbo_buffer += 6*sizeof(GLfloat); // offset to position
   memcpy(vbo_buffer, whatYouWantToChange, 2*sizeof(GLfloat));  // change what you want, watch the size
 }

РЕДАКТИРОВАТЬ приведите пример с цветом

Сначала некоторые примеры данных, в данном случае треугольник с чередованием данных на каждую вершину:

static const ColoredTriangle vertexData[] = {
    {
        {0.0, 0.0, 0.0},           // Vertex 0
        {0.0, 0.0, 1.0},           // Normal 
        {1.0, 0.0, 0.0, 1.0}       // Color  
    },
    {
        {0.0, 480.0, 0.0},            // Vertex 1
        {0.0,   0.0, 1.0},            // Normal 
        {1.0, 1.0, 0.0, 1.0}          // Color  
    },
    {
        {320.0, 0.0, 0.0},           // Vertex 2
        {0.0, 0.0, 1.0},             // Normal
        {1.0, 1.0, 1.0, 1.0}         // Color 
    }

Скопируйте объект в vbo (после создания / привязки / MapBuffer.

memcpy(vbo_buffer, vertexData, 10*3*sizeof(float));

Нарисуй вещь

glVertexPointer(3, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glColorPointer(4, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)))   
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);

Итак, теперь у вас нарисован треугольник с чередованными данными из VBO.

Теперь на каждом кадре вы хотите что-то сделать, просто измените данные.

GLvoid*  vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
vbo_buffer += 6*sizeof(GLfloat); // position the buffer at the first vertex color data
for (int i = 0; i < 3; i++) {
    memcpy(vbo_buffer, newColor, 4*sizeof(GLfloat));
    vbo_buffer += 10*sizeof(GLfloat); // skip the stripe
}
glUnmapBufferOES(GL_ARRAY_BUFFER);

Затем нарисуйте снова, и вы просто изменили информацию о цвете. В зависимости от количества изменений, которые вы собираетесь сделать, может быть лучше изменить GL_STATIC_DRAW на что-то еще ...

Ответственность Это было сделано на лету, так что остерегайтесь драконов.

2 голосов
/ 01 декабря 2011

Вы можете определить координаты вершины в VBO и цвета вершин в другом, затем вы можете использовать glVertexAttribPointer (или glVertexPointer, glColorPointer), чтобы установить атрибуты вершины для визуализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...