2012-01-05 6 views
2

У меня есть код OpenGL, но я пытаюсь немного улучшить его производительность (хотел бы немного увеличить частоту кадров на старых устройствах). Я пытаюсь сделать это с помощью Vertex Buffer Object.Рисование с объектами буфера вершин в OpenGL ES 1.1 не работает

Весь мой код делает нарисовать серию из 360 GL_TRIANGLES, которые имеют текстуру, применяемую к ним. Я переплетаю координаты и координаты текстуры в структуру данных.

typedef struct { 
    GLfloat vertex[2]; 
    GLfloat texture[2]; 
    GLfloat padding[4]; 
} TextureVertex2D; 

typedef struct { 
    TextureVertex2D textureVertex[3]; 
} TextureTriangle2D; 

Вот соответствующая часть моей инициализации

textureTriangles = (TextureTriangle2D*)malloc(360 * sizeof(TextureTriangle2D)); 

glGenTextures(1, &texture[0]); 
glBindTexture(GL_TEXTURE_2D, texture[0]); 

// This section is the only new code introduced for the VBOs. 
glGenBuffers(1, &buffer[0]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(TextureTriangle2D)*360, textureTriangles[0].textureVertex[0].vertex, GL_DYNAMIC_DRAW); 
// end new code  

glVertexPointer(2, GL_FLOAT, sizeof(TextureVertex2D), textureTriangles[0].textureVertex[0].vertex); 
glTexCoordPointer(2, GL_FLOAT, sizeof(TextureVertex2D), textureTriangles[0].textureVertex[0].texture); 

/* 
textureTriangles is filled and the texture image is loaded in 
*/ 

Для экономии до фактического VBO, я попробовал два метода (оба из которых имели один и тот же результат)

// Option 1 
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 
memcpy(vbo_buffer, textureTriangles[0].textureVertex[0].vertex, 360 * sizeof(TextureTriangle2D)); 
glUnmapBufferOES(GL_ARRAY_BUFFER); 

// Option 2 
glBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureVertex2D), 360 * sizeof(TextureTriangle2D), textureTriangles[0].textureVertex[0].vertex); 

Затем я связываю буфер

glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); 

И, наконец, выполнить чертеж

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glDrawArrays(GL_TRIANGLES, 0, 3*360); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

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

+0

В файле 'glBufferSubData' второй аргумент должен be '0' вместо' sizeof (TextureVertex2D) '. Однако при обновлении всего буфера вы должны использовать 'glBufferData'. –

ответ

1

При использовании VBOs последний аргумент gl...Pointer не является указателем на некоторый массив, содержащий данные вершин, но смещение байта в текущем связанном GL_ARRAY_BUFFER. Таким образом, вы не specifiy адреса ваших данных CPU вершины, которые вы уже скопированы в буфер, но смещения в этом буфере данных, где атрибуты хранятся:

glVertexPointer(2, GL_FLOAT, sizeof(TextureVertex2D), 
    offsetof(TextureVertex2D,vertex)); 
glTexCoordPointer(2, GL_FLOAT, sizeof(TextureVertex2D), 
    offsetof(TextureVertex2D,texture)); 
+0

Это исправлено. Спасибо за помощь! –

+0

@ RossKimes Upvoting всегда ценится. –

0

В этой строке:

glBufferData(GL_ARRAY_BUFFER, sizeof(TextureTriangle2D)*360, textureTriangles[0].textureVertex[0].vertex, GL_DYNAMIC_DRAW); 

Я думаю, вы должны указать sizeof(TextureTriangle2D)*360*3, поскольку каждый треугольник (с использованием GL_TRIANGLES в запросе натяжного массива) требует 3 вершины координат.

Я не так много информации о прохождении 3D координат, используя только 2 координаты (я думаю, с Z фиксированной до нуля?), Но заявление само по себе должно быть предметом рассмотрения на вашей стороне

Я бы ожидать:

typedef struct { 
    GLfloat vertex[3]; 
    GLfloat texture[2]; 
    GLfloat padding[3]; 
} TextureVertex2D; 

Но это зависит от вашего двигателя.

+0

Использование только двух координат, только z будет 0 (например, w равно 1, если не используется). Если вы будете использовать 3 координаты, то, конечно, заполнение должно быть 3, а не 4 (при необходимости в любом случае). Я исправлю это. –

+0

Конечно, ошибка этого размера также должна быть изменена в его процедурах обновления. –

+0

@ChristianRau Я не думаю, что это проблема. Как вы сказали, z всегда будет равным 0 (чего я хочу, я всего лишь рисую 2D-объекты). –