Что такое современный OpenGL эквивалентный glBegin / glEnd

Я строю графический API для OpenGL, который основан на базовом графическом стиле призыва к рисованию. По сути, вместо того, чтобы хранить данные в графическом процессоре и вызывать их, используя их дескриптор, дайте информацию, чтобы нарисовать то, что должно быть при каждом обновлении. Я знаю, что это медленно, но это просто и для не критичных к производительности приложений. Во всяком случае, есть ли современный эквивалент glBegin / glEnd? Это не обязательно вызов для каждой вершины, но способ, которым я могу отправлять данные каждое обновление, не сохраняя вершины в GPU?

3

Решение

Вы в значительной степени ответили на свой вопрос.

есть ли современный эквивалент glBegin / glEnd? Это не обязательно вызов для каждой вершины, но способ, которым я могу отправлять данные каждое обновление, не сохраняя вершины в GPU?

В принципе нет, современный способ заключается в использовании VAOs с ОБВ (и IBO).

Если вы собираетесь изменить данные в VBO, помните, что вы можете изменить mode параметр в glBufferData.

  • GL_STREAM_DRAW — содержимое хранилища данных будет изменено один раз и использоваться не более нескольких раз.

  • GL_STATIC_DRAW — содержимое хранилища данных будет изменено один раз и использовано много раз.

  • GL_DYNAMIC_DRAW — содержимое хранилища данных будет неоднократно изменяться и использоваться много раз.

Тогда вместо использования GL_STATIC_DRAWзатем используйте GL_DYNAMIC_DRAW это значительно увеличит FPS по сравнению с использованием GL_STATIC_DRAWОднако это зависит от объема данных и частоты их изменения. Но постарайтесь ограничить его настолько, насколько сможете, например, не обновляйте данные в буферах, если вам это не нужно.

Вы можете прочитать больше о различных буферах на OpenGL Wiki нажмите здесь.

5

Другие решения

Ищите использование VAO / VBO, это то, что вы хотите реализовать.
В коде C / C ++ ниже приведен простой пример.
Режим входной переменной — GL_POINYS / TRIANGLES / QUADS / …. (как в glBegin ())
Это также единственный вариант с GLSL и профилем ядра для передачи атрибутов (glVertex / glNormal / … неизвестен в ядре в течение некоторого времени)

//------------------------------------------------------------------------------
//--- Open GL VAO example (GLSL) -----------------------------------------------
//------------------------------------------------------------------------------
#ifndef _OpenGL_VAO_example_h
#define _OpenGL_VAO_example_h
//------------------------------------------------------------------------------
GLuint vbo[4]={-1,-1,-1,-1};
GLuint vao[4]={-1,-1,-1,-1};
const float vao_pos[]=
{
//       x      y     z
0.75f, 0.75f, 0.0f,
0.75f,-0.75f, 0.0f,
-0.75f,-0.75f, 0.0f,
};
const float vao_col[]=
{
//      r   g    b
1.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,
0.0f,0.0f,1.0f,
};
//---------------------------------------------------------------------------
void vao_init()
{
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);

glBindVertexArray(vao[0]);
glBindBuffer(GL_ARRAY_BUFFER,vbo[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);

glBindBuffer(GL_ARRAY_BUFFER,vbo[1]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
}
//---------------------------------------------------------------------------
void vao_exit()
{
glDeleteVertexArrays(4,vao);
glDeleteBuffers(4,vbo);
}
//---------------------------------------------------------------------------
void vao_draw(GLuint mode)
{
void *p=NULL;
glBindVertexArray(vao[0]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawArrays(mode,0,3);
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------
//--- end. ---------------------------------------------------------------------
//------------------------------------------------------------------------------

Если вы не хотите использовать GLSL, вы должны немного изменить код на что-то вроде этого:

//tetraeder
#define V_SIZ 12
#define I_SIZ 6
GLfloat tet_verts[V_SIZ] = { \
-0.5f, -1.0f, -0.86f, \
-0.5f, -1.0f, 0.86f, \
1.0f, -1.0f, 0.0f, \
0.0f, 1.0f, 0.0f};

GLushort tet_index = {3, 0, 1, 2, 3, 0};void init_buffers() {
glGenBuffersARB(1, &vertex_buf);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, V_SIZ*sizeof(GLfloat), tet_verts, GL_STATIC_DRAW_ARB); //upload data

glGenBuffersARB(1, &index_buf);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buf);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, I_SIZ*sizeof(GLushort), tet_index, GL_STATIC_DRAW_ARB); //upload data

return;
}

void draw_buffers() {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
glVertexPointer(3, GL_FLOAT, 0, 0); //3 is xyz, last 0 ("pointer") is offset in vertex-array

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buf);

glEnableClientState(GL_VERTEX_ARRAY);

//use indexing
glDrawElements(GL_TRIANGLE_STRIP, I_SIZ, GL_UNSIGNED_SHORT, 0); //last 0 is offset in element-array

return;
}

void deinit_buffers() {
glDeleteBuffersARB(1, &vertex_buf);
glDeleteBuffersARB(1, &index_buf);

return;
}

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

0

По вопросам рекламы [email protected]