SDL2 rendercopy больше не работает при использовании аппаратного ускоренного рендеринга - PullRequest
0 голосов
/ 04 февраля 2020

Я делаю 2D-игру с SDL2, и у меня есть некоторые проблемы с отображением карты на экране. При перемещении карта прокручивается, поэтому я решил загрузить карту порциями, чтобы я мог просто обрезать SDL_Texture в зависимости от местоположения игрока, чтобы отобразить соответствующий раздел карты на экране. Проблема заключается в том, что после однократного отображения карты во всех последующих кадрах у меня появляется черный экран или фактически экран с любым цветом рисования рендерера. Я знаю, это звучит так, как будто я вызываю SDL_RenderClear не в том месте, но потерпите меня, эта проблема сложнее.

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

Суть моего кода, связанного с SDL, такова:

Когда карта загружена, инициализируется пара плиток (или «кусков»). По мере того как вы перемещаетесь далеко, плитки будут освобождены, а новые инициализированы. Каждая плитка создает изображение (текстуру) на основе своего местоположения. (Признаюсь, я не знаю, является ли это наиболее эффективным способом, я ожидал, что это сэкономит время, когда будут готовы большие текстуры, которые нужно будет обрезать, а не рисовать все на лету). Это вызывает много переключений между целями рендеринга, потому что для каждой плитки SDL_RendererSetTarget вызывается для рендеринга непосредственно в ее текстуру, и в основном многие текстуры «вставляются» в более крупную (изображение плитки). После этого, конечно, цель рендеринга возвращается на экран.

Остальная часть процесса рендеринга довольно проста:

  • SDL_RenderClear
  • Поиск соответствующей плитки
  • SDL_RenderСкопируйте ее изображение с клипом, чтобы получить правую часть экрана и проделайте то же самое для смежных тайлов
  • Еще несколько SDL_RenderCopys для размещения спрайта игрока и некоторых других спрайтов (npcs) на экране
  • SDL_RenderPresent
  • Подождите пару миллисекунд с SDL_Delay

Окончательный результат кажется верным, потому что, как я упоминал ранее, самый первый вызов SDL_RenderPresent отображает все просто отлично. Однако каждый последующий вызов отображает экран с цветом рисунка, что означает, что якобы больше ничего не происходило между вызовом RenderClear и RenderPresent. Поэтому я думаю, что после этой первой SDL_RenderPresent SDL_Rendercopy просто больше не работает. Однако программа не обрабатывает sh, так что почти все текстуры по какой-то причине решают стать полностью прозрачными, или, может быть, они просто отображаются в подвешенном состоянии.

Я, честно говоря, понятия не имею, даже в в какой области проблема может быть ie, но я пробовал все, что мог придумать, к сожалению, пока безрезультатно. Что еще хуже, все части кода, которые я мог бы изолировать, работают нормально сами по себе ... Так что любые предложения или даже подозрения о том, в чем может быть проблема, более чем приветствуются! Может быть, я смотрю на это неправильно, и использование аппаратного рендера для таких вещей, как рендеринг текстур, просто невозможно? Кроме того, я подумал об удалении SDL и изучении OpenGL, но, поскольку это будет означать переписывание большого количества кода, я хотел сначала спросить здесь, чтобы увидеть, действительно ли нет другого решения. Наконец, вот некоторые системные характеристики, которые я пробовал, все, что я мог придумать, которые могли бы иметь отношение:

  • Я пытался создать «текстуру экрана» в качестве посредника для средства визуализации, где все RenderCopys направлены до того, как, наконец, скопировать этот файл на экран.
  • Так я создаю свой рендерер (как в учебнике Lazy Foo (https://lazyfoo.net/tutorials/SDL/43_render_to_texture/index.php) SDL_CreateRenderer (gWindow, -1 , SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYN C); я также пытался добавить флаг SDL_RENDERER_TARGETTEXTURE. Никогда не понимал, почему этого не делается в руководстве.
  • У меня есть видеокарта AMD Radeon HD 8330 * Windows 1039 *
  • Вызов SDL_GetRendererInfo показывает, что аппаратный рендерер называется direct3d, а поддерживаемые пиксельные форматы - ARGB8888, YV12 и IYUV. Всякий раз, когда я создаю текстуру, я использую исходный код в SDL_CreateTextureFromSurface, чтобы определить, какой формат использовать.
  • Поскольку у большинства моих bmp есть альфа-канал, я вызываю SDL_SetTextureBlendMode с флагом SDL_BLENDMODE_BLEND на всех текстурах. А также SDL_SetRenderDrawBlendMode с этим флагом на рендере.

1 Ответ

1 голос
/ 05 февраля 2020

Оказывается, я случайно вызывал SDL_SetWindowSize между кадрами из-за проверки логического указателя, подобного этому

if (boolean)

вместо

if (* boolean)

... Упс!

Несмотря на то, что я устанавливаю размер на одно и то же значение каждый раз, когда это делает недействительными все текстуры, созданные с помощью SDL_CreateTexture с помощью аппаратного средства визуализации. Интересно, что те, что были созданы с помощью SDL_CreateTextureFromSurface, не были затронуты. И, как я уже сказал, текстуры, созданные с помощью программного рендерера, похоже, не возражают против изменения размера окна. Я оставлю это здесь в надежде, что однажды моя глупость поможет кому-то еще.

...