I'm am learning SDL2, but I am also using the imgui library that is using OpenGL calls. From what I read on various blogs online, I can't easily mix SDL2 renderer and opengl calls; I either use one or the other.
Most of the tutorials I've read use the renderer, so I do not quite understand how to use SDL2 without the renderer for drawing primitives, or drawing sprites.
Take this for example: http://lazyfoo.net/tutorials/SDL/11_clip_rendering_and_sprite_sheets/index.php
He creates the sdl renderer:
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
Which he then uses to render images:
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 );
}
He then calls his render()
to draw images from a 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 );
I understand what is happening, but now that I can't use the sdl renderer, how do I accomplish the same? Can I not use any SDL2 drawing functions now? Do I only use raw opengl calls, and only use SDL for keyboard bindings?
Basically, I do not understand how to use SDL2 for drawing things (like in the sprite example) if I cannot use the SDL Renderer
since it seems incompatible with the gui library I'm using, which uses opengl calls for rendering.
SDL has the ability to create and use OpenGL contexts on several platforms(Linux/X11, Win32, BeOS, MacOS Classic/Toolbox, Mac OS X, FreeBSD/X11 and Solaris/X11). This allows you to use SDL's audio, event handling, threads and times in your OpenGL applications (a function often performed by GLUT).
SDL is a platform-independent API for everything else relevant to the game development, and also provides an initialization procedure for OpenGL (which OpenGL itself does not provide, so you needed to use platform-specific APIs like WGL and AGL or later standards like EGL).
If you want a lot of fancy effects and sprites on the screen at once, use OpenGL because it supports shaders and is hardware accelerated. If your game is simple and doesn't need a lot of effects or sprites, stick with SDL, especially if it's your first game. SDL isn't hardware accelerated, but it's much easier to use.
Yes, SDL uses the GPU for 2D rendering if it can. Ok awesome.
Can I not use any SDL2 drawing functions now? Do I only use raw opengl calls, and only use SDL for keyboard bindings?
Correct.
In order to use OpenGL API directly, the SDL window must be created with the flag SDL_WINDOW_OPENGL
, as well as a new OpenGL context for it:
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);
If successful, one would simply perform calls to OpenGL like in any other context handler. That same website linked in the question provides tutorials for using OpenGL with SDL 2, both legacy and modern. Note that none of the two involve creating an SDL renderer. In fact, using it would be inappropriate since the two APIs are meant to be mutually exclusive: you should either use one or the other. This answer makes a quick explanation for why you should not mix them.
Nevertheless, there are ways to achieve the same output from certain SDLRenderer calls using OpenGL (since the same renderer has an OpenGL implementation!), but this will naturally be case specific. Want to draw a simple rectangle? The legacy glBegin
and glEnd
approach might suffice. Want to draw a sprite? You'll have to send it to the OpenGL device's memory first. Once you know the ropes around OpenGL, making a suitable wrapper layer is often appropriate.
If you want to use existing libraries that rely on OpenGL, replacing other drawing procedures to use this API (or utility libraries such as GLU) is the right way to go.
Also note that the SDL renderer does not have to rely on OpenGL (it may use Direct3D on Windows).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With