SDL入门学习续-在SDL中使用OpenGL

       配置好SDL之后,就想在SDL中使用openGL,原以为会像在GLFW中那样简单的,实际上确花费了一整个下午不断查看文档,实例才搞定问题。

总结如下:

1)SDL对OpenGL进行了部分的封装,一些OpenGL的函数需要用SDL来实现,而不是像GLFW中那样直接用;

2)SDL的事件机制花费了一些时间来理解;

3)在处理OpenGL窗口大小变化的时候,需要先调用SDL_SetVideoMode才可以得到正确结果。

最终基本实现了一个opengl的小型框架,包括一些简单的事件处理。

代码:

/***************************************************************************** Copyright: 2012, ustc All rights reserved. contact:[email protected] File name: main.c Description:using opengl in SDL. Author:Silang Quan Version: 1.0 Date: 2012.12.01 *****************************************************************************/ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT =800; const int SCREEN_BPP = 32; SDL_Surface *screen; //Whether the window is windowed or not bool windowed; //Whether the window is fine bool windowOK; void quit( int code ) {     SDL_Quit( );     /* Exit program. */     exit( code ); } void toggle_fullscreen() { 	//If the screen is windowed 	if( windowed == true ) 	{ 		//Set the screen to fullscreen 		screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL|SDL_RESIZABLE| SDL_FULLSCREEN );  		//If there's an error 		if( screen == NULL ) 		{ 			windowOK = false; 			return; 		}  		//Set the window state flag 		windowed = false; 	} 	//If the screen is fullscreen 	else if( windowed == false ) 	{ 		//Window the screen 		screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL|SDL_RESIZABLE );  		//If there's an error 		if( screen == NULL ) 		{ 			windowOK = false; 			return; 		}  		//Set the window state flag 		windowed = true; 	} } void handleKeyEvent( SDL_keysym* keysym ) {     switch( keysym->sym ) 	{     case SDLK_ESCAPE:         quit( 0 );         break;     case SDLK_SPACE:         break;     case SDLK_F1: 		toggle_fullscreen(); 		break;     default:         break;     } } 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 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_VIDEORESIZE: 			//Handle resize event             screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,                                       SDL_OPENGL|SDL_RESIZABLE);             if ( screen )             {                 resizeGL(screen->w, screen->h);             }             break;         }     } }  void initSDL(int width,int height,int bpp,int flags) {     // First, initialize SDL's video subsystem.     if( SDL_Init( SDL_INIT_VIDEO ) < 0 )     {         fprintf( stderr, "Video initialization failed: %s\n",                  SDL_GetError( ) );         quit( 1 );     }     atexit(SDL_Quit); 	//Set some Attribute of OpenGL in SDL     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );      //Set the video mode     screen= SDL_SetVideoMode( width, height, bpp,flags);     if(!screen )     {         fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) );         quit( 1 );     windowed=false; 	} 	else windowed=true;     resizeGL(screen->w, screen->h);     //Set caption     SDL_WM_SetCaption( "OpenGL Test", NULL ); } 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_SwapBuffers( ); } 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 ); } int main( int argc, char* argv[] ) {  	// Color depth in bits of our window. 	int flags= SDL_OPENGL|SDL_RESIZABLE; 	//Set the SDL 	initSDL(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,flags); 	//Set the OpenGL 	initGL(SCREEN_WIDTH, SCREEN_HEIGHT );      //main loop     while(true) 	{         /* Process incoming events. */         handleEvents( );         /* Draw the screen. */         renderGL( );     }     return 0; } 



编译命令:

 g++ main.c -o mian -lSDL -lglut -lGLU 

#in opensuse g++ main.c -o main -lSDL -lGL -lGLU


SDLOpenGLFramework

这里给一个C++写的OpenGL编程框架。

https://github.com/SilangQuan/SDLOpenGLFramework


SDL英文教程-http://lazyfoo.net/

你可能感兴趣的:(SDL入门学习续-在SDL中使用OpenGL)