这里用一个例子来说明SDL2.0 加上Opengl来绘画、并贴上纹理。这里要加载的库文件为SDL2.0、SDL2_image、glut、glu不同平台对应加载的库可能不一样。例如Windows有32位和64位加载的glut库为glut32.lib 和glut.l.lib。请读者自己取搭建。废话不多说源码贴上。
#include
#include
#include
#include
#include
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
bool g_window_flage = true;
bool g_render_quad = true;
/*Initialize opengl*/
void InitializeOpengl()
{
GLenum error = GL_NO_ERROR;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
error = glGetError();
if( error != GL_NO_ERROR )
{
/printf(" Initiailizie OpenGl is fail.Error: %s \n", gluErrorString( error ));
exit(0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
error = glGetError();
if( error != GL_NO_ERROR )
{
printf(" Initiailizie OpenGl is fail.Error: %s \n", gluErrorString( error ));
exit(0);
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
error = glGetError();
if( error != GL_NO_ERROR)
{
printf(" Initiailizie OpenGl is fail.Error: %s \n", gluErrorString( error ));
exit(0);
}
glEnable(GL_TEXTURE_2D);
}
void OpenglDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
if(g_render_quad)
{
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0);
glVertex2f(-0.5f, -0.5f);
glTexCoord2f(1.0, 1.0);
glVertex2f(0.5f, -0.5f);
glTexCoord2f(1.0, 0.0);
glVertex2f(0.5f, 0.5f);
glTexCoord2f(0.0, 0.0);
glVertex2f(-0.5f, 0.5f);
glEnd();
}
}
void EventDeal()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
g_window_flage = false;
break;
case SDLK_r:
g_render_quad = ! g_render_quad;
break;
}
}
}
int main()
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "SDL Initialize is fail" << std::endl;
exit(1);
}
if(IMG_INIT_PNG != IMG_Init(IMG_INIT_PNG))
{
std::cout << "SDL image initialize is fail" << std::endl;
}
//use opengl 2.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window *window = SDL_CreateWindow("SDL-Opengl One", 200,200,WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if(NULL == window)
{
printf("Create Window is fail.Error:%s \n",SDL_GetError());
exit(0);
}
SDL_GLContext gcontext = SDL_GL_CreateContext(window);
if(NULL == gcontext)
{
printf("Create SDL_Context is fail.Error: %s \n", SDL_GetError());
exit(0);
}
InitializeOpengl();
SDL_Surface* background = IMG_Load("empress.png");
SDL_Surface *image_sur = SDL_ConvertSurfaceFormat(background, SDL_PIXELFORMAT_ABGR8888 /*SDL_PIXELFORMAT_RGBA8888*/ /*SDL_PIXELFORMAT_ARGB8888*/, 0);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image_sur->w, image_sur->h, GL_RGBA/*GL_ABGR_EXT*/, GL_UNSIGNED_BYTE, image_sur->pixels);
SDL_FreeSurface(background);
if(SDL_GL_SetSwapInterval(1) < 0)
{
printf(" Warnning: unable to set VSync! Error: %s \n", SDL_GetError());
}
while(g_window_flage)
{
OpenglDisplay();
EventDeal();
SDL_GL_SwapWindow(window);
SDL_Delay(40);
}
return 0;
}
代码说明:我在寻找的时候也是在想为什么不用SDL_Texture创建纹理然后在使用呢,根据官方的文档描述
You need a renderer to create a SDL_Texture, therefore you can only use this function with an implicit OpenGL context from SDL_CreateRenderer(), not with your own OpenGL context. If you need control over your OpenGL context, you need to write your own texture-loading methods.
说加载一个SDL_Texture 需要一个SDL_Renderer在使用的时候。意思就是说官方没有做一个SDL_Texture 与Opengl联合使用的功能他们有各自一套的渲染过程。所以你如果想用那么你就得自己取写。所以用SDL_Texture的梦想破裂了。
第二、就是纹理的位置,SDL在加载像素的时候是以左上角为纹理的起点而Opengl则是以坐下角为起点,所以要把y作弊旋转个180度上下颠倒一下。