SDL2.0与opengl的混合使用,绘图和纹理的加载。

这里用一个例子来说明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度上下颠倒一下。

你可能感兴趣的:(图形学习)