Я как бы застрял на логике текстуры SDL2. Для меня они бессмысленны, так как вы не можете привлечь их.
В моей программе у меня есть несколько поверхностей (или что мы поверхности, прежде чем я переключился на SDL2), который я просто сдвинул вместе, чтобы сформировать слои. Теперь, кажется, мне нужно создать несколько рендеров и текстур, чтобы создать тот же эффект, так как SDL_RenderCopy
принимает указатель текстуры
Не только это, но все Рендереры должны выходить из окна, которое я понимаю, но все же меня немного портит.
Все это кажется чрезвычайно громоздким и медленным. Я что-то пропустил? Есть ли способ рисовать непосредственно на текстуру? В чем смысл текстур, и могу ли я иметь несколько (если не сотни) визуализаторов вместо поверхностей?
SDL_Texture
объекты хранятся как можно ближе к памяти видеокарты и, следовательно, могут быть легко ускорены вашим графическим процессором. Увеличение производительности может сильно повлиять на изменение размера, альфа-смешивание, сглаживание и почти любую сложную вычислительную операцию. Если вашей программе требуется запускать пиксельную логику для ваших текстур, вам рекомендуется временно преобразовать ваши текстуры в поверхности. Достижение обходного пути с потоковыми текстурами также возможно.
редактировать:
Поскольку этот ответ привлекает большое внимание, я хотел бы проработать мое предложение.
Если вы предпочитаете использовать Texture -> Surface -> Texture
Рабочий процесс для применения вашей операции с пикселем, убедитесь, что вы кэшируете свою окончательную текстуру, если вам не нужно пересчитывать ее на каждом цикле рендеринга. Текстуры в этом решении созданы с SDL_TEXTUREACCESS_STATIC
флаг.
Потоковые текстуры (флаг создания SDL_TEXTUREACCESS_STREAMING
) рекомендуется для случаев использования, когда источником данных пикселей является сеть, устройство, сервер фреймов или какой-либо другой источник, который находится за пределами полного охвата приложений SDL, и когда очевидно, что кэширование кадров из источника неэффективно или не будет работать.
Можно визуализировать поверх текстур, если они созданы с SDL_TEXTUREACCESS_TARGET
флаг. Это ограничивает источник операции рисования другими текстурами, хотя это может быть тем, что вам нужно в первую очередь. «Текстуры как цели рендеринга» — одна из новейших и наименее широко поддерживаемых функций SDL2.
Информация о ботанике для любопытных читателей:
Из-за особенностей реализации SDL первые два метода зависят от операций чтения и копирования на уровне приложения, хотя они оптимизированы для предлагаемых сценариев и достаточно быстры для приложений реального времени.
Копирование данных с уровня приложения почти всегда происходит медленно по сравнению с последующей обработкой на графическом процессоре. Если ваши требования более строгие, чем те, которые может предоставить SDL, и ваша логика не зависит от какого-либо внешнего источника данных пикселей, было бы разумно выделить необработанные текстуры OpenGL, нарисованные на ваших поверхностях SDL, и применить шейдеры (Логика ГПУ) им.
Шейдеры написаны на GLSL, языке, который компилируется в сборку GPU. Аппаратное / GPU ускорение фактически относится к коду, распараллеленному на ядрах графического процессора, и использование шейдеров является предпочтительным способом достижения этого для целей рендеринга.
Внимание! Использование необработанных текстур и шейдеров OpenGL в сочетании с функциями и структурами рендеринга SDL может привести к неожиданным конфликтам или потере гибкости, обеспечиваемой библиотекой.
TLDR;
Рендеринг и обработка текстур происходит быстрее, чем поверхностей, хотя их изменение иногда может быть затруднительным.
Создавая текстуру SDL2 как тип STREAMING, можно заблокировать и разблокировать всю текстуру или только область пикселей для выполнения прямых операций с пикселями. Необходимо предварительно создать поверхность SDL2 и связать ее с блокировкой-разблокировкой следующим образом:
SDL_Surface surface = SDL_CreateSurface(..);
SDL_LockTexture(texture, &rect, &surface->pixels, &surface->pitch);
// paint into surface pixels
SDL_UnlockTexture(texture);
Ключ заключается в том, что если вы рисуете текстуру большего размера, а рисунок является инкрементным (например, график данных в режиме реального времени), обязательно блокируйте и разблокируйте фактическую область для обновления. В противном случае операции будут медленными с интенсивным копированием памяти.
Я испытал разумную производительность, и модель использования не слишком сложна для понимания.
В SDL2 можно выполнять рендеринг вне экрана / рендеринг непосредственно в текстуру. Используемая функция:
int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);
Это работает только в том случае, если средство визуализации включает SDL_RENDERER_TARGETTEXTURE.