Wiki
Tutoriales Programacion SDL
Contenidos
SDL (Simple DirectMedia Layer)
¿Qué es SDL?
Para aquellos que no lo sepáis, viene a ser el DirectX libre; provee de un sistema de administración de entrada/salida, sonido, fuentes truetype, servicio de red, gráficos 2D y por supuesto, interacción con OpenGL para 3D etc... . Lo bueno, es que además de ser OpenSource, es multiplataforma (Windows, GNU/Linux y OSX que yo sepa).
La mayoría de los que hemos intentado entrar en el mundillo scener a través de la parte de programación, nos hemos encontrado con el escollo que supone la creación de una ventana y su correspondiente unión a un contexto de render OpenGL; que aunque algunos IDEs traen el código en una plantilla lista para usar, siempre es un engorro. Con SDL disponemos de un método sencillo y consistente de hacer esto; además, tener a nuestra disposición (si queremos) reproducción de música y captura de eventos de teclado (las demos que se presentan a concurso suelen tener que poder pararse, pulsando la tecla ESC) siempre es una ventaja.
Inicializando SDL
Aunque se utilice OpenGL para el 3D, el resto (eventos de entrada/salida, audio, 2D...). Se sigue manejando de forma normal con SDL.
Sin más preámbulos, vamos al meollo de la cuestión; y no veo mejor forma de comenzar que un buen filete de código ;) .
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include "SDLTest.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BPP 32
int sdl_load();
int opengl_init();
int show ( square* sqre);
void handle_input(SDL_Event event, square *sqre);
void move(square *sqre);
int main (int argc, char** argv){
SDL_Event event;
int quit;
quit = 0;
square sqre;
sqre.x = 0;
sqre.y = 0;
sqre.xSpeed = 0;
sqre.ySpeed = 0;
if (sdl_load() == 0){
printf("SDL Inicializado correctamente");
}else{
printf("Error Inicializando SDL");
SDL_Quit();
return 1;
}
/* Bucle principal y captura de eventos e/s */
while(quit == 0){
while ( SDL_PollEvent ( &event ) ){
handle_input(event, &sqre);
if ( event.type == SDL_QUIT )
quit = 1;
}
move(&sqre);
glClear ( GL_COLOR_BUFFER_BIT );
if( show (&sqre) != 0){
printf("Error displaying quad");
}
SDL_GL_SwapBuffers ();
}
SDL_Quit();
//getchar();
return 0;
}int sdl_load (){
/*
* Estas 3 funciones devuelven valores de error
* que deberian ser comprobados. Aunque para este ejemplo
* yo no lo haga por ahorrar código
*/
if( SDL_Init ( SDL_INIT_EVERYTHING ) < 0){
printf("Error Iniciando SDL %s\n",SDL_GetError());
return 1;
}
if ( SDL_SetVideoMode ( SCREEN_WIDTH, SCREEN_HEIGHT, BPP, SDL_OPENGL ) == NULL ){
printf("Error Iniciando el modo de video %s\n",SDL_GetError());
return 1;
}
if ( opengl_init() > 0 ){
printf("Error Iniciando OpenGL\n");
return 1;
}
return 0;
}
int opengl_init (){
glClearColor ( 0, 0, 0, 0 );
glMatrixMode ( GL_PROJECTION );
glLoadIdentity ();
glOrtho ( 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1 );
/*Iniciamos la matriz de modelo*/
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity ();
if ( glGetError() != GL_NO_ERROR )
return 1;
return 0;
}
int show ( square* sqre){
/* Como siempre que dibujamos usando OpenGl
* iniciamos un bloque glBegin / glEnd
*/
glTranslated (sqre->x, sqre->y, 0);
glBegin ( GL_QUADS );
glColor4f ( 1.0, 1.0, 1.0, 1.0 );
glVertex3f ( 0, 0, 0 );
glVertex3f ( 20, 0, 0 );
glVertex3f ( 20, 20, 0 );
glVertex3f ( 0, 20, 0 );
glEnd();
glLoadIdentity ();
return 0;
}void move(square *sqre)
{
//Move the square left or right
sqre->x += sqre->xSpeed;
//If the square went too far
if( ( sqre->x < 0 ) || ( sqre->x + 20 > SCREEN_WIDTH ) )
{
//Move back
sqre->x -= sqre->xSpeed;
}
//Move the square up or down
sqre->y += sqre->ySpeed;
//If the square went too far
if( ( sqre->y < 0 ) || ( sqre->y + 20 > SCREEN_HEIGHT ) )
{
//Move back
sqre->y -= sqre->ySpeed;
}
}void handle_input(SDL_Event event, square *sqre)
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: sqre->ySpeed -= 20 / 2; break;
case SDLK_DOWN: sqre->ySpeed += 20 / 2; break;
case SDLK_LEFT: sqre->xSpeed -= 20 / 2; break;
case SDLK_RIGHT: sqre->xSpeed += 20 / 2; break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: sqre->ySpeed -= 20 / 2; break;
case SDLK_DOWN: sqre->ySpeed -= 20 / 2; break;
case SDLK_LEFT: sqre->xSpeed -= 20 / 2; break;
case SDLK_RIGHT: sqre->xSpeed -= 20 / 2; break;
}
}
}Aviso: Este tutorial no está terminado.
Esta página es el resultado del esfuerzo de los siguientes autores. El número entre paréntesis corresponde a la cantidad de versiones con las que cada usuario ha contribuido:
cybrid (5)