如果我使用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实现!),但这自然是特定于案例的。 想绘制一个简单的矩形? 传统的glBegin
和glEnd
方法可能就足够了。 想绘制一个精灵? 您必须先将它发送到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