SDL2.0上手试用

前言

       个人喜好原因,写OpenGL的程序都喜欢用SDL做框架,没有Qt那么臃肿,也没有glut那么坑跌,在不失灵活性的情况下保持了自己的轻量。SDL2.0在今年很早的时候时候就发布了,几天就来好好试用一下。

      下面是SDL2主要的几点新特性:

全硬件加速
支持OpenGL3.0+
支持OpenGL ES
支持Android和iOS

跨平台支持Windows,MacOSX和LInux

修改了很多bug

...


编译安装

从官网下载最新版2.0.1的源码,解压后cd进目录,依次执行:

./autogen

./configura

make

sudu make install

一切顺利的话SDL2.0就安装编译好了。

库文件在 /usr/local/lib中

头文件在 /usr/local/include/SDL2 中。


加载显示一张图片

感觉SDL的1.2和2.0差别还是挺大的。看代码:

#include <iostream>
#include <SDL2/SDL.h>  
#include <GL/gl.h>  
#include <GL/glu.h>  
using namespace std;
int main()
{
 	//Start SDL  
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
		cout << "SDL_Init Error: " << SDL_GetError() << endl;
		return 1;
	}
	
	SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 871, 564, SDL_WINDOW_SHOWN);
	if (win == nullptr)
	{
		cout << "SDL_CreateWindow Error: " << SDL_GetError() << endl;
		return 1;
	}
	
	SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
	if (ren == nullptr)
	{
		cout << "SDL_CreateRenderer Error: " << SDL_GetError() << endl;
		return 1;
	}
	
	SDL_Surface *bmp = SDL_LoadBMP("girl.bmp");
	if (bmp == nullptr)
	{
		cout << "SDL_LoadBMP Error: " << SDL_GetError() << endl;
		return 1;
	}
	
	SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
	SDL_FreeSurface(bmp);
	if (tex == nullptr)
	{
		cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << endl;
		return 1;
	}
	
	SDL_RenderClear(ren);
	SDL_RenderCopy(ren, tex, NULL, NULL);
	SDL_RenderPresent(ren);
	
	SDL_Delay(2000);
	
	SDL_DestroyTexture(tex);
	SDL_DestroyRenderer(ren);
	SDL_DestroyWindow(win);
    //Quit SDL  
        SDL_Quit(); 
	cout<<"Hello"<<endl;
	return 1;
}

代码还是蛮简单的,先是初始化SDL,再依次 初始化Window ->初始化Render ->加载图片 -> 生成纹理 ->渲染纹理 ->释放内存,记得在当前目录放一张 girl.bmp.运行结果:




基于SDL2的OpenGL编程

相对于SDL1.2中的函数接口,SDL2改变得还是比较大的,其中的设计得会更加“现代化”一些,用起来会更加方便,以前用过SDL1.2的需要重新熟悉一下。

#include <iostream>
#include <SDL2/SDL.h>  
#include <GL/gl.h>  
#include <GL/glu.h>  
using namespace std;

const int SCREEN_WIDTH = 800;  
const int SCREEN_HEIGHT =600; 
SDL_Window *mainwindow; /* Our window handle */
SDL_GLContext maincontext; /* Our opengl context handle */

/* A simple function that prints a message, the error code returned by SDL,
 * and quits the application */
void sdldie(const char *msg)
{
    printf("%s: %s\n", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}

void quit( int code )  
{  
    SDL_Quit( );  
    /* Exit program. */  
    exit( code );  
}  

void checkSDLError(int line = -1)
{
#ifndef NDEBUG
        const char *error = SDL_GetError();
        if (*error != '\0')
        {
                printf("SDL Error: %s\n", error);
                if (line != -1)
                        printf(" + line: %i\n", line);
                SDL_ClearError();
        }
#endif
}

void initGL( int width, int height )  
{  
    float ratio = (float) width / (float) height;  
    // Our shading model--Gouraud (smooth).  
    glShadeModel( GL_SMOOTH );  
    // Set the clear color.  
    glClearColor( 0, 0, 0, 0 );  
    // Setup our viewport.  
    glViewport( 0, 0, width, height );  
    //Change to the projection matrix and set our viewing volume.  
    glMatrixMode( GL_PROJECTION );  
    glLoadIdentity();  
    gluPerspective( 60.0, ratio, 1.0, 100.0 );  
}  

void initSDL()
{
	if (SDL_Init(SDL_INIT_VIDEO) < 0) /* Initialize SDL's Video subsystem */
        sdldie("Unable to initialize SDL"); /* Or die on error */
 
    /* Request opengl 3.2 context.
     * SDL doesn't have the ability to choose which profile at this time of writing,
     * but it should default to the core profile */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
 
    /* Turn on double buffering with a 24bit Z buffer.
     * You may need to change this to 16 or 32 for your system */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
    /* Create our window centered at 512x512 resolution */
    mainwindow = SDL_CreateWindow("OpenGL in SDL2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
    if (!mainwindow) /* Die if creation failed */
        sdldie("Unable to create window");
 
    checkSDLError(__LINE__);
 
    /* Create our opengl context and attach it to our window */
    maincontext = SDL_GL_CreateContext(mainwindow);
    checkSDLError(__LINE__);
 
    /* This makes our buffer swap syncronized with the monitor's vertical refresh */
    SDL_GL_SetSwapInterval(1);
}

void renderGL()
{
	 // Clear the color and depth buffers.  
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );  
    // We don't want to modify the projection matrix. */  
    glMatrixMode( GL_MODELVIEW );  
    glLoadIdentity( );  
    // Move down the z-axis.  
    glTranslatef( 0.0, 0.0, -5.0 );  
    //Draw a square  
    glBegin(GL_QUADS);  
    glColor3f(1.0f,0.0f,0.0f);  
    glVertex3f(-1.0f  , -1.0f  ,  1.0f  );  
    glColor3f(0.0f,1.0f,0.0f);  
    glVertex3f( 1.0f  , -1.0f  ,  1.0f  );  
    glColor3f(0.0f,0.0f,1.0f);  
    glVertex3f( 1.0f  ,  1.0f  ,  1.0f  );  
    glColor3f(1.0f,1.0f,0.0f);  
    glVertex3f(-1.0f  ,  1.0f  ,  1.0f  );  
    glEnd();  
    SDL_GL_SwapWindow(mainwindow);
}

void resizeGL(int width,int height)  
{  
    if ( height == 0 )  
    {  
        height = 1;  
    }  
    //Reset View  
    glViewport( 0, 0, (GLint)width, (GLint)height );  
    //Choose the Matrix mode  
    glMatrixMode( GL_PROJECTION );  
    //reset projection  
    glLoadIdentity();  
    //set perspection  
    gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );  
    //choose Matrix mode  
    glMatrixMode( GL_MODELVIEW );  
    glLoadIdentity();  
    
}  

void handleKeyEvent( SDL_Keysym* keysym )  
{  
    switch( keysym->sym )  
    {  
    case SDLK_ESCAPE:  
        quit( 0 );  
        break;  
    case SDLK_SPACE:  
     cout<<"Space"<<endl;
        break;  
    default:  
        break;  
    }  
} 

void handleEvents()  
{  
    // Our SDL event placeholder.  
    SDL_Event event;  
    //Grab all the events off the queue.  
    while( SDL_PollEvent( &event ) ) {  
        switch( event.type ) {  
        case SDL_KEYDOWN:  
            // Handle key Event  
            handleKeyEvent( &event.key.keysym );  
            break;  
        case SDL_QUIT:  
            // Handle quit requests (like Ctrl-c).  
            quit( 0 );  
            break;  
        case SDL_WINDOWEVENT:  
      		if(event.window.event == SDL_WINDOWEVENT_RESIZED)
        	{
            	if ( mainwindow )  
            	{  
            		int tmpX,tmpY;
            		SDL_GetWindowSize(mainwindow,&tmpX,&tmpY);
                	resizeGL(tmpX, tmpY); 
               	 	
            	}  
        	}
        	SDL_GL_SwapWindow(mainwindow);
            break;  
        }  
    }  
} 

/* Our program's entry point */
int main(int argc, char *argv[])
{
 	initSDL();
	initGL(SCREEN_WIDTH, SCREEN_HEIGHT);
	renderGL( );  
	while(true)
	{
		/* Process incoming events. */  
        handleEvents( );  
        /*Render scene*/
        renderGL(); 
	}
 
    return 0;
}

需要说明的时候__LINE__这个宏,它主要是用来调试的,表示当前的代码行数,

用下面的命令来编译:

g++ test.cpp -o test -lSDL2 -lGL -lGLU -std=c++11

运行结果:



编译运行Android中的SDL2

注:最好在Ubuntu 下来进行交叉编译,测试过Opensuse,未果。

在SDL的源码文件夹中有相应的android工程模板 android-project.

首先是交叉编译。

1.创建android-project/jni/SDL文件夹

2.将SDL源码目录下的src 和include文件夹还有Android.mk拷贝到刚才创建的目录

3.在 android-project/jni/src 中创建main.c

这里从手机里面加载一张图片来显示。

#include "SDL.h"

int main(int argc, char* argv[])
{
 	//Start SDL  
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
		return 1;
	}
	
	SDL_Window *win = SDL_CreateWindow("Hello World!", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_SHOWN);

	
	SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);

	
	SDL_Surface *bmp = SDL_LoadBMP("/sdcard/boss.bmp");

	
	SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
	SDL_FreeSurface(bmp);
	
	SDL_RenderClear(ren);
	SDL_RenderCopy(ren, tex, NULL, NULL);
	SDL_RenderPresent(ren);
	
	SDL_Delay(2000);
	
	SDL_DestroyTexture(tex);
	SDL_DestroyRenderer(ren);
	SDL_DestroyWindow(win);
	
    //Quit SDL  
    SDL_Quit(); 
	return 1;
}

修改src/Android.mk文件,将YourSourceHere.c改为main.c.

4.在手机的sdcard根目录下面放一个boss.bmp,待会加载。

5.终端cd进android-project,执行

$NDK_ROOT/ndk-build

编译正常的话可以得到下面的结果:



6.用eclipse将项目导入,运行,得到结果:



参考

在Eclipse中配置SDL2.0 for Android - http://adolfans.github.io/sdltutorialcn/blog/2013/04/23/set-up-sdl2-for-android-in-eclipse/


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值