Что такое модуль рендеринга SDL?

104

Я начинаю с SDL2 и не могу понять, что такое SDL_Renderer.

Что это? Что оно делает? В чем разница между SDL_Renderer, SDL_Window, SDL_Surface и SDL_Texture и как они связаны?

У меня были проблемы с этим, когда я пытался понять этот вводный код:

#include <iostream>
#include <SDL2/SDL.h>

int main()
{
    /* Starting SDL */
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Create a Window */
    SDL_Window *window = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Create a Render */
    SDL_Renderer *render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (render == nullptr) {
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Load bitmap image */
    SDL_Surface *bmp = SDL_LoadBMP("./Tutorial/res/Lesson1/hello.bmp");
    if (bmp == nullptr) {
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Upload surface to render, and then, free the surface */
    SDL_Texture *texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);
    if (texture == nullptr){
        std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Draw the render on window */
    SDL_RenderClear(render); // Fill render with color
    SDL_RenderCopy(render, texture, NULL, NULL); // Copy the texture into render
    SDL_RenderPresent(render); // Show render on window

    /* Wait 2 seconds */
    SDL_Delay(5000);

    /* Free all objects*/
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(render);
    SDL_DestroyWindow(window);

    /* Quit program */
    SDL_Quit();
    return 0;
}

Я использовал учебник Twinklebear (предложенный на SDL Wiki), а также просмотрел документацию SDL Wiki и некоторые книги. Но все они предполагают, что я знаю эти определения.

Prcastro
источник

Ответы:

197

SDL_Window

SDL_Window это структура, которая содержит всю информацию о самом Окне: размер, положение, полноэкранный режим, границы и т. д.


SDL_Renderer

SDL_Renderer- это структура, которая обрабатывает весь рендеринг. Он привязан к объекту, SDL_Windowпоэтому может отображаться только в нем SDL_Window. Он также отслеживает настройки, связанные с рендерингом. Есть несколько важных функций, связанных сSDL_Renderer

  • SDL_SetRenderDrawColor(renderer, r, g, b, a);
    Это устанавливает цвет для очистки экрана (см. Ниже)

  • SDL_RenderClear(renderer);
    Это очищает цель рендеринга с указанным выше цветом рисования.

  • SDL_RenderCopy(
    Вероятно, это функция, которую вы будете использовать чаще всего, она используется для рендеринга SDL_Textureи имеет следующие параметры:

    • SDL_Renderer* renderer,
      Средство визуализации, которое вы хотите использовать для визуализации.
    • SDL_Texture* texture,
      Текстура, которую вы хотите визуализировать.
    • const SDL_Rect* srcrect, Часть текстуры, которую вы хотите визуализировать, NULL, если вы хотите визуализировать всю текстуру
    • const SDL_Rect* dstrect)
      Где вы хотите визуализировать текстуру в окне. Если ширина и высота этого SDL_Rectменьше или больше, чем размеры самой текстуры, текстура будет растянута в соответствии с этимSDL_Rect
  • SDL_RenderPresent(renderer);
    Другие функции SDL_Render * рисуют скрытую цель. Эта функция возьмет все это и отобразит в окне, привязанном к рендереру.

SDL_Texture и SDL_Surface

SDL_RendererОказывает SDL_Texture, который хранит информацию о точках одного элемента. Это новая версия, во SDL_Surfaceмногом такая же. Разница в основном заключается в том, что SDL_Surfaceэто просто информация о structпикселях, а SDL_Textureтакже эффективное представление пиксельных данных для конкретного драйвера.

Вы можете преобразовать SDL_Surface * в SDL_Texture, используя

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                          SDL_Surface*  surface)

После этого SDL_Surface должен быть освобожден с помощью

SDL_FreeSurface( SDL_Surface* surface )

Еще одно важное отличие заключается в том, что SDL_Surfaceиспользуется программный рендеринг (через ЦП), тогда как SDL_Textureиспользуется аппаратный рендеринг (через графический процессор).


SDL_Rect

Самая простая структура в SDL. В нем всего четыре шорта. x, yкоторый содержит позицию и w, hширину и высоту.

Важно отметить, что 0, 0это верхний левый угол SDL. Таким образом, более высокое yзначение означает более низкое, а в правом нижнем углу будет координатаx + w, y + h


Вы можете прочитать больше о SDL2 на моем блоге.

Olevegard
источник
1
Итак, что вы, когда вызываете SDL_RenderPresent, - это взять этот рендерер со всеми его настройками и текстурами, которые были загружены в него, и заставить его отображать эту информацию в окне, к которому он привязан?
prcastro 08
3
@olevegard, отличный ответ. Чтобы прояснить разницу между SDL_Texture и SDL_Surface, я хотел бы подчеркнуть, что SDL_Texture визуализирует с использованием графического процессора, а SDL_Surface использует программную обработку, которая менее эффективна, но позволяет вам свободно манипулировать информацией о пикселях. Кроме того, отличный блог, я обязательно его прочитаю :)
Фабио Пикки
Утверждение «Это очищает цель рендеринга с указанным выше цветом рисования» , я считаю правильным, но я не могу понять фразу «очищает» в этом утверждении. Документ всегда использует эту фразу. Не могли бы вы объяснить, что именно здесь означает «ясный» ? Означает ли это "рисовать" (вроде как) текущим цветом отрисовки средства визуализации?
Nawaz
Есть ли причина использовать SDL_Surfaceover SDL_Renderer?
Stevoisiak
В верхнем ответе есть некоторая неточность, SDL_Renderer также может быть привязан к поверхности, а не только к окну, пожалуйста, проверьте ссылку: wiki.libsdl.org/SDL_CreateSoftwareRenderer
dmitro
9

Думайте об этом SDL_Windowкак о физических пикселях SDL_Rendererи как о месте для хранения настроек / контекста.

Таким образом, вы создаете кучу ресурсов и вешаете их на рендерер; а затем, когда все будет готово, вы говорите рендереру собрать все вместе и отправить результаты в окно.

шерстяная звезда
источник