Arhn - архитектура программирования

Методы анимации 2D Sprite с OpenGL

В настоящее время я пытаюсь настроить анимацию 2D-спрайтов с помощью OpenGL 4. Например, я разработал плавно вращающийся мяч с помощью Gimp. Там около 32 кадров (8 кадров в 4 ряда).

Я стремлюсь создать атлас спрайтов в 2D-текстуре и хранить данные спрайтов в буферах (VBO). Мой прямоугольник спрайта всегда будет одним и тем же (т.е. rect(0,0,32,32)) , но мои координаты текстуры будут меняться каждый раз, когда увеличивается индекс кадра.

Интересно, как изменить координаты.

  1. Поскольку тайлы спрайтов хранятся в нескольких строках, кажется, что ими сложно управлять в шейдере.
  2. Измените координату текстуры спрайта в буфере с помощью glBufferSubData() ?

Я провел много времени с OpenGL 1.x... и вернулся к OpenGL несколько месяцев назад и понял, что многое изменилось. Я попробую несколько вариантов, но ваши предложения и опыт приветствуются.


Ответы:


1

Поскольку тайлы спрайтов хранятся в нескольких строках, кажется, что ими сложно управлять в шейдере.

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

Однако почему вы вообще храните отдельные кадры в сетке mxn? Теперь вы можете хранить их только в одной строке. Однако в современном GL у нас есть массив текстур. По сути, это набор независимых 2D-слоев одинакового размера. Вы просто получаете к ним доступ по 3D-координате, где третья координата — это слой от o до n-1. Это идеально подходит для вашего варианта использования и устранит любые проблемы с фильтрацией текстур/просвечиванием на границах, а также будет хорошо работать с мипмаппингом (если вам это нужно). Когда были введены массивы текстур, минимальное количество слоев, которое должна поддерживать реализация, составляло 64 (в настоящее время оно намного выше), поэтому 32 кадра будет проще простого даже для старых графических процессоров.

02.01.2015

2

Вы можете сделать это миллионом способов, но я собираюсь предложить наивное решение:

Создайте VBO с 32 (квадраты кадра) * 2 (треугольники на квадрат кадра) * 3 (вершины треугольника) * 5 (x, y, z, u, v на вершину) = 960 поплавков пространства. Заполните его вершинами всех ваших спрайтов по схеме 2 треугольника на кадр.

Теперь, согласно документам glDrawArrays, вы можете указать, где вы start и как долго вы рендерите. Используя это, вы можете указать следующее:

int indicesPerFrame = 960/32;
int indexToStart = indicesPerFrame*currentBallFrame;
glDrawArrays( GL_TRIANGLES, indexToStart, indicesPerFrame);

Нет необходимости изменять VBO. Теперь, с моей точки зрения, рендерить 32 кадра по одному кадру за раз — это излишество. Есть лучшие решения этой проблемы, но это самое простое для изучения OpenGL4.

02.01.2015
  • спасибо сержант Хейл. Это часть решений, которые я планировал реализовать :) 02.01.2015

  • 3

    В OpenGL 2.1 я использую ваш второй вариант:

    void setActiveRegion(int regionIndex)
    {
        UVs.clear();
    
        int numberOfRegions = (int) textureSize / spriteWidth;
    
        float uv_x = (regionIndex % numberOfRegions)/numberOfRegions;
        float uv_y = (regionIndex / numberOfRegions)/numberOfRegions;
    
        glm::vec2 uv_up_left    = glm::vec2( uv_x                     , uv_y );
        glm::vec2 uv_up_right   = glm::vec2( uv_x+1.0f/numberOfRegions, uv_y );
        glm::vec2 uv_down_right = glm::vec2( uv_x+1.0f/numberOfRegions, (uv_y + 1.0f/numberOfRegions) );
        glm::vec2 uv_down_left  = glm::vec2( uv_x                     , (uv_y + 1.0f/numberOfRegions) );
    
    
        UVs.push_back(uv_up_left   );
        UVs.push_back(uv_down_left );
        UVs.push_back(uv_up_right  );
    
        UVs.push_back(uv_down_right);
        UVs.push_back(uv_up_right);
        UVs.push_back(uv_down_left);
    
        glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
        glBufferSubData(GL_ARRAY_BUFFER, 0, UVs.size() * sizeof(glm::vec2), &UVs[0]);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    }
    

    Источник: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-11-2d-text/

    Он реализовал его для рендеринга 2D-текста, но это та же концепция!

    Надеюсь помог!

    09.02.2017
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..