Как сделать так, чтобы шаг за шагом отображалась анимация в openGL?

Как сделать пошаговое отображение анимации в openGL ??

Я делаю проект принтера reprap, чтобы прочитать файл GCode и интерпретировать его в графический.
теперь мне сложно сделать пошаговую анимацию рисования всего объекта.
Мне нужно нарисовать много коротких линий, чтобы составить целый объект.
например:

|-----|
|     |
|     |
|-----|

квадрат состоит из множества коротких линий, и каждая строка генерируется кодом, подобным следующему:

glPushMatrix();
.....
for(int i=0; i< instruction[i].size(),i++)
{  ....
glBegin(GL_LINES);
glVertex3f(oldx, oldy, oldz);
glVertex3f(x, y, z);
glEnd();
}
glPopMatrix();

Теперь я хочу сделать пошаговую анимацию, чтобы показать, как сделан этот квадрат. Я пытался обновлять экран каждый раз, когда рисуется новая линия, но она не работает, сразу появляется весь квадрат. Кто-нибудь знает, как это сделать?

1

Решение

Типичные реализации OpenGL помещают в очередь большое количество вызовов, чтобы объединить их в пакеты активности для оптимального использования доступной пропускной способности связи и временных ресурсов графического процессора.

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

Другой подход, который я рекомендую, заключается в использовании отдельного буфера для инкрементного рисования и постоянного обновления основного кадрового буфера из этого. Ключевыми предметами являются Объект буфера кадра а также Render To Texture.

Сначала вы создаете FBO (множество учебных пособий и ответы на StackOverflow). FBO — это, по сути, абстракция, к которой вы можете подключить целевые буферы, такие как текстуры или рендеринг-буферы, и которые могут быть связаны как назначение вызовов при рисовании.

Так как решить вашу проблему с ними? Во-первых, вы не должны делать анимацию, задерживая цикл рисования. У этого есть несколько причин, но главная проблема заключается в том, что вы теряете интерактивность программы. Вместо этого вы поддерживаете (глобальный) счетчик, на котором вы находитесь. Давайте назовем это step:

int step = 0;

Затем в вашей функции рисования вы должны поэтапно: 1) Обновление текстуры 2) Обновление экрана

Первая фаза состоит в связывании вашего объекта кадрового буфера как цели рендеринга. Чтобы это работало, целевая текстура должна быть свободной

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, animFBO);
glViewport(0, 0, fbo.width, fbo.height);
set_animFBO_projection();

Хитрость заключается в том, что вы очищаете animFBO только один раз, а именно после создания, а затем никогда больше. Теперь вы рисуете свои линии в соответствии с шагом анимации

draw_lines_for_step(step);

и увеличить счетчик шагов (можно сделать это как составной оператор, но это более явно)

step++;

После обновления анимации FBO самое время обновить экран. Сначала уберите animFBO

glBindFramebuffer(GL_FRAMEBUFFER, 0);

Теперь мы находимся в основном экранном фреймбуфере

glViewport(0, 0, window.width, window.height);
set_window_projection(); //most likely a glMatrixMode(GL_PROJECTION); glOrtho(0, 1, 0, 1, -1, 1);

Теперь свяжите прикрепленную текстуру FBO и нарисуйте ее в полный квад квадрата

glBindTexture(GL_TEXTURE_2D, animFBOTexture);
draw_full_viewport_textured_quad();

Наконец, сделайте замену буфера, чтобы показать итерацию шага анимации

SwapBuffers();
0

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

Вы должны вызывать метод SwapBuffer после каждого вызова draw.
Убедитесь, что вы не завинчиваете стек матрицы, и вам, вероятно, понадобится что-то, чтобы «приостановить» рендеринг, как точка останова.

0

Если вы хотите, чтобы строки появлялись одна за другой, и вам не нужно придирчиво относиться к эффективности или хорошему стилю программирования, попробуйте что-то вроде:

(в вашем обычном рисовании)

if (timer > 100)
{

//draw the next line

timer = 0;

}

else

timer++;

//draw all the other lines (you have to remember wich one already appeared)

//for example using a boolean array "lineDrawn[10]"

Таймер — это целое число, которое говорит вам, как часто вы рисуете сцену. Если вы увеличите его, то при запуске программы на экране будет происходить медленнее.

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

-> множество учебных пособий довольно везде, например

http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/

Удачи тебе!

PS: я думаю, что вы сделали почти то же самое, но без таймера. Вот почему все было нарисовано так быстро, что вы подумали, что оно появилось одновременно.

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