Правильный способ создания объектов в OpenGL? - PullRequest
1 голос
/ 28 февраля 2011

Я действительно новичок в opengl, и сейчас я изучаю основы. У меня вопрос высокого уровня. Если я хочу создать объект, скажем, столбец, в котором есть все варианты?

  1. Импорт 3D-сетки из любой внешней программы (например, 3DStudio) и загрузка ее в opengl
  2. Создание 6 полигонов с использованием glVertex3f
  3. переизбыток? (Я видел glutSolidCube, но ничего похожего на glutSolidColumn)

Мои вопросы:

А) Есть ли другой способ сделать это?

B) Как правильно создавать обычные объекты / анимированные объекты в opengl, если вы НЕ используете сетку 3DStudio?

C) Правильно ли этот код для создания столбца в 2)? (В таком случае я постараюсь параметризовать его, используя переменные x, y, z, чтобы иметь столбец для заданного этажа плитка с заданной высотой)

//Column
//Wall
glBegin(GL_POLYGON); 
    glVertex3f(150.0f, 250.0f,50);   // x1, y1 - top-left corner    
    glVertex3f(50.0f, 250.0f,50);   // x2, y1 - top-right corner
    glVertex3f(50.0f, 50.0f,50);        // x2, y2 - bottom-right corner
    glVertex3f(150.0f, 50.0f,50);    // x1, y2 - bottom-left corner

glEnd( );

//Wall
glBegin(GL_POLYGON); 
    glVertex3f(50.0f,  250.0f,0);   // x1, y1 - top-left corner 
    glVertex3f(150.0f, 250.0f,0);  // x2, y1 - top-right corner
    glVertex3f(150.0f, 50.0f,0);   // x2, y2 - bottom-right corner
    glVertex3f(50.0f,  50.0f,0);    // x1, y2 - bottom-left corner
glEnd( );

//Wall
glBegin(GL_POLYGON);
    glVertex3f(150.0f, 250.0f,0);       // x1, y1 - top-left corner 
    glVertex3f(150.0f, 250.0f,50.0f);   // x2, y1 - top-right corner
    glVertex3f(150.0f, 50.0f,50.0f);        // x2, y2 - bottom-right corner
    glVertex3f(150.0f, 50.0f,0);    // x1, y2 - bottom-left corner
glEnd( );

//Wall
glBegin(GL_POLYGON);
    glVertex3f(50.0f, 250.0f,50);       // x1, y1 - top-left corner 
    glVertex3f(50.0f, 250.0f,0);    // x2, y1 - top-right corner
    glVertex3f(50.0f, 50.0f,0);     // x2, y2 - bottom-right corner
    glVertex3f(50.0f, 50.0f,50);    // x1, y2 - bottom-left corner
glEnd( );

//Floor
glBegin(GL_POLYGON);
    glVertex3f(50.0f, 50.0f, 0);        // x1, y1 - top-left corner 
    glVertex3f(50.0f, 50.0f, 50);   // x2, y1 - top-right corner
    glVertex3f(0, 50.0f, 50);       // x2, y2 - bottom-right corner
    glVertex3f(0, 50.0f, 0);    // x1, y2 - bottom-left corner
glEnd( );

//Ceiling
glBegin(GL_POLYGON);
    glVertex3f(50.0f, 250.0f, 0);       // x1, y1 - top-left corner 
    glVertex3f(50.0f, 250.0f, 50);  // x2, y1 - top-right corner
    glVertex3f(0, 250.0f, 50);      // x2, y2 - bottom-right corner
    glVertex3f(0, 250.0f, 0);    // x1, y2 - bottom-left corner
glEnd( );

Ответы [ 2 ]

5 голосов
/ 28 февраля 2011

Это зависит от вашего правильного определения. Чтобы ответить один за другим:

  1. это был бы самый нормальный способ; однако OpenGL - это только библиотека рендеринга, и вы должны предоставить код для загрузки интересующих вас форматов файлов;
  2. glVertex3f - плохой выбор; см. экспозицию ниже;
  3. GLUT не является частью OpenGL, но да - есть множество сторонних библиотек, которые могут рисовать примитивные объекты для вас. GLUT один.

Re: вызовы glVertex3f и glBegin / glEnd. В настоящее время они хороши, когда вы изучаете, как простой способ позволить вам исследовать другие части конвейера рендеринга. Тем не менее, они устарели и неоптимальны, поэтому вы не захотите стать постоянными. Из-за этого они не реплицируются в OpenGL ES или WebGL.

Существует какая-либо стоимость, связанная с любым обменом данными между процессором и графическим процессором. Чем больше данных вы передаете в сообщении, тем выше стоимость. Однако даже небольшие вызовы стоят довольно дорого из-за временной синхронизации, требуемой между двумя асинхронными и параллельными устройствами.

Таким образом, glBegin / glVertex3f / glEnd являются плохими, поскольку все данные хранятся в ЦП и передаются в драйвер по частям посредством множества вызовов. В качестве первого шага вы, вероятно, захотите переключиться на использование glVertexPointer (для предоставления всех данных вершин за один шаг) и либо glDrawArrays, либо glDrawElements (чтобы выполнить эквивалент всех вызовов glBegin / glEnd за один шаг). Оттуда вы можете перейти к хранению данных на GPU, а не на CPU через объекты массива вершин.

4 голосов
/ 28 февраля 2011

Существует только один способ визуализации объекта и несколько способов добраться до него.Один из способов - описать многоугольник для каждой (видимой) грани объекта.

В OpenGL 1.x это означает glBegin, glVertex, glEnd.

В OpenGL 2.x это означает glVertexPointer, glDrawArrays (но способ 1.x все еще работает)

В OpenGL 3.x это означает создание объекта буфера вершин, его связывание и glDrawArrays (методы 1.x и 2.x работают только в режиме совместимости).

Вспомогательные функции, такие как glutSolidCube или библиотека для загрузки сетки модели, используют эти же методы внутренне.

...