如果我使用opengl进行绘图,SDL渲染器是无用的吗?

我正在学习SDL2,但我也在使用使用OpenGL调用的imgui库。 从我在网上阅读的各种博客中,我无法轻松混合使用SDL2渲染器和opengl调用; 我要么使用一个或另一个。

我读过的大多数教程都使用渲染器,所以我不太了解如何在没有渲染器的情况下使用SDL2来绘制基元或绘制精灵。

以此为例:http://lazyfoo.net/tutorials/SDL/11_clip_rendering_and_sprite_sheets/index.php

他创建了sdl渲染器:

gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );

然后他用它来渲染图像:

void LTexture::render( int x, int y, SDL_Rect* clip )
{
        //Set rendering space and render to screen
        SDL_Rect renderQuad = { x, y, mWidth, mHeight };

        //Set clip rendering dimensions
        if( clip != NULL )
        {
                renderQuad.w = clip->w;
                renderQuad.h = clip->h;
        }

        //Render to screen
        SDL_RenderCopy( gRenderer, mTexture, clip, &renderQuad );
}

然后他调用他的render()从spritesheet中绘制图像:

//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );

//Render top left sprite
gSpriteSheetTexture.render( 0, 0, &gSpriteClips[ 0 ] );

//Render top right sprite
gSpriteSheetTexture.render( SCREEN_WIDTH - gSpriteClips[ 1 ].w, 0, &gSpriteClips[ 1 ] );

//Render bottom left sprite
gSpriteSheetTexture.render( 0, SCREEN_HEIGHT - gSpriteClips[ 2 ].h, &gSpriteClips[ 2 ] );

//Render bottom right sprite
gSpriteSheetTexture.render( SCREEN_WIDTH - gSpriteClips[ 3 ].w, SCREEN_HEIGHT - gSpriteClips[ 3 ].h, &gSpriteClips[ 3 ] );

//Update screen
SDL_RenderPresent( gRenderer );

我明白发生了什么,但现在我不能使用sdl渲染器,我该如何实现? 我现在不能使用任何SDL2绘图功能吗? 我是否只使用原始的opengl调用,并且只使用SDL进行键盘绑定?

基本上,我不明白如何使用SDL2来绘制事物(如在精灵示例中),因为它似乎与我正在使用的使用opengl调用进行渲染的gui库不兼容,所以我无法使用SDL Renderer


我现在不能使用任何SDL2绘图功能吗? 我是否只使用原始的opengl调用,并且只使用SDL进行键盘绑定?

正确。

为了直接使用OpenGL API,必须使用标志SDL_WINDOW_OPENGL创建SDL窗口,并为其创建一个新的OpenGL上下文:

auto window = SDL_CreateWindow("Window name",
                 SDL_WINDOWPOS_UNDEFINED,
                 SDL_WINDOWPOS_UNDEFINED,
                 width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
auto context = SDL_GL_CreateContext(window);

如果成功,可以像在其他任何上下文处理程序中一样简单地执行对OpenGL的调用。 该问题中链接的同一网站提供了使用带有SDL 2的OpenGL教程,包括传统教程和现代教程。 请注意,两者都不涉及创建SDL渲染器。 事实上,使用它是不合适的,因为这两个API意味着互相排斥:您应该使用其中一个或另一个。 这个答案对你为什么不应该混合它们做了一个快速的解释。

尽管如此,有些方法可以使用OpenGL实现某些SDLRenderer调用的相同输出(因为相同的渲染器具有OpenGL实现!),但这自然是特定于案例的。 想绘制一个简单的矩形? 传统的glBeginglEnd方法可能就足够了。 想绘制一个精灵? 您必须先将它发送到OpenGL设备的内存。 一旦你知道了围绕OpenGL的绳索,制作合适的包装层通常是合适的。 如果您想使用依赖于OpenGL的现有库,那么替换其他绘图程序以使用此API(或诸如GLU等实用程序库)是正确的选择。

另请注意,SDL渲染器不必依靠OpenGL(它可能在Windows上使用Direct3D)。


如果我理解你想知道如何在不使用SDL函数的情况下渲染到SDL屏幕,则需要使用opengl函数。 SDL支持opengl,使用SDL使用opengl渲染东西时,您必须遵循以下最小步骤:在创建窗口之前,先调用SDL_GL_SetAttribute来设置OpenGL属性,然后使用SDL_WINDOW_OPENGL标志创建窗口,之后您必须创建opengl context(每个gl应用程序都有一个)调用SDL_GL_CreateContext ,请参阅SDL Wiki以了解我提到的功能:CategoryVideo - SDL Wiki

以下是一些代码例子:

void start(SDL_Window** window, SDL_GLContext* gl){
if(SDL_Init(SDL_INIT_VIDEO) < 0){
    throw std::runtime_error(SDL_GetError());
}
//set the gl version to be loaded
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

*window = SDL_CreateWindow("Widget Tests", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL);

if(*window == nullptr){
    throw std::runtime_error(SDL_GetError());
}

//create the opengl context
*gl = SDL_GL_CreateContext(*window);

if(*gl == nullptr){
    throw std::runtime_error(SDL_GetError());
}
}

int main(){
SDL_Window* window;
SDL_GLContext gl;
...

//init sdl and opengl
start(&window, &gl);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_PROJECTION_MATRIX);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadIdentity();
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

while(running){
    while(SDL_PollEvent(&event)){
        switch(event.type){
            ...
        }
    }
    glClear(GL_COLOR_BUFFER_BIT);

    //... draw calls with opengl

    SDL_GL_SwapWindow(window);//update the window
}
}
链接地址: http://www.djcxy.com/p/67585.html

上一篇: Is SDL Renderer useless if I use opengl for drawing?

下一篇: SDL resetting glViewport