什么是SDL渲染器?


103

我从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文档和一些书上也有所查找。但是所有这些都假定我知道这些定义。

Answers:


196

SDL_Window

SDL_Window 是包含有关窗口本身的所有信息的结构:大小,位置,全屏,边框等。


SDL_Renderer

SDL_Renderer是处理所有渲染的结构。它与a绑定在一起,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_Textures和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使用软件渲染(通过CPU)而SDL_Texture使用硬件渲染(通过GPU)。


SDL_Rect

SDL中最简单的结构。它仅包含四个短裤。x, y保持位置w, h,保持宽度和高度。

重要的是要注意这0, 0是SDL的左上角。因此,较高的y值表示较低的值,并且右下角将具有坐标x + w, y + h


您可以在我的博客上阅读有关SDL2的更多信息


1
那么,当您调用SDL_RenderPresent时,是使用该渲染器及其上载的所有设置和纹理,并使其在绑定到的Window上渲染此信息?
prcastro 2014年

3
@olevegard,很好的答案。为了澄清SDL_Texture和SDL_Surface之间的区别,我要强调指出,使用GPU进行SDL_Texture渲染,而使用SDL_Surface使用软件重做,效率较低,但可以自由操作像素信息。另外,很棒的博客,我一定会读的:)
Fabio Picchi 2015年

我相信“这将清除上面设置的绘制颜色的渲染目标”这一说法是正确的,但我无法理解该声明中的“清除”一词。该文档始终使用此短语。您能否在这里解释“清除”的确切含义?它是用渲染器的当前绘制颜色表示“绘画”(分类)吗?
纳瓦兹

有什么理由要SDL_Surface用完SDL_Renderer吗?
Stevoisiak

最佳答案有一些不准确之处,SDL_Renderer也可能会绑定到表面,而不仅是绑定到窗口,请检查链接:wiki.libsdl.org/SDL_CreateSoftwareRenderer
dmitro

9

可以将其SDL_Window视为物理像素,并且SDL_Renderer可以将其存储为设置/上下文。

因此,您创建了一堆资源,并将其挂在渲染器上。然后准备好后,告诉渲染器将它们放在一起并将结果发送到窗口。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.