Moving 2D Sprite: SO on my previous post i showed you the code to display a 2D sprite using OpenGl with SDL. Now i’ll show how to move a 2D Sprite using opengl with sdl. There will be some minor changes in the code and rest will be the same.

I’ll write the new changes in black and bold and rest are the same as in previous code on my previous post.

Here is the full code:


#include "SDL.h"

#include "SDL_image.h"

#include "SDL_opengl.h"

#include <stdio.h>

GLuint texture=NULL; //this is a handle to our texture object

GLenum texture_format=NULL;

GLint nofcolors;

SDL_Event event;

bool LEFT=false;

bool RIGHT=false;

float x=100.0,y=100.0;

int loadImage()

{

SDL_Surface *surface; // this surface will tell us the details of the image

if ( (surface = IMG_Load("flower.png")) ) {

// Check that the image's width is a power of 2

if ( (surface->w & (surface->w - 1)) != 0 ) {

printf("warning: image.bmp's width is not a power of 2\n");

}

// Also check if the height is a power of 2

if ( (surface->h & (surface->h - 1)) != 0 ) {

printf("warning: image.bmp's height is not a power of 2\n");

}

//get number of channels in the SDL surface

nofcolors=surface->format->BytesPerPixel;

//contains an alpha channel

if(nofcolors==4)

{

if(surface->format->Rmask==0x000000ff)

texture_format=GL_RGBA;

else

texture_format=GL_BGRA;

}

else if(nofcolors==3) //no alpha channel

{

if(surface->format->Rmask==0x000000ff)

texture_format=GL_RGB;

else

texture_format=GL_BGR;

}

else

{

printf("warning: the image is not truecolor...this will break ");

}

// Have OpenGL generate a texture object handle for us

glGenTextures( 1, &texture );

// Bind the texture object

glBindTexture( GL_TEXTURE_2D, texture );

// Set the texture's stretching properties

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

glTexImage2D( GL_TEXTURE_2D, 0, nofcolors, surface->w, surface->h, 0,

texture_format, GL_UNSIGNED_BYTE, surface->pixels );

}

else {

printf("SDL could not load image.bmp: %s\n", SDL_GetError());

SDL_Quit();

return 1;

}

// Free the SDL_Surface only if it was successfully created

if ( surface ) {

SDL_FreeSurface( surface );

}

}

void drawImage()

{

// Clear the screen before drawing

glClear( GL_COLOR_BUFFER_BIT );

glTranslatef( x, y, 0 );

// Bind the texture to which subsequent calls refer to

glBindTexture( GL_TEXTURE_2D, texture );

glBegin( GL_QUADS );

// Top-left vertex (corner)

glTexCoord2i( 0, 0 );

glVertex3f( 100, 100, 0 );

// Bottom-left vertex (corner)

glTexCoord2i( 1, 0 );

glVertex3f( 228, 100, 0 );

// Bottom-right vertex (corner)

glTexCoord2i( 1, 1 );

glVertex3f( 228, 228, 0 );

// Top-right vertex (corner)

glTexCoord2i( 0, 1 );

glVertex3f( 100, 228, 0 );

glEnd();

glLoadIdentity();

SDL_GL_SwapBuffers();

}

int init()

{

SDL_Surface *screen;

// Slightly different SDL initialization

if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {

printf("Unable to initialize SDL: %s\n", SDL_GetError());

return 1;

}

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL|SDL_FULLSCREEN);

if ( !screen ) {

printf("Unable to set video mode: %s\n", SDL_GetError());

return 1;

}

}

void init_GL()

{

// Set the OpenGL state after creating the context with SDL_SetVideoMode

glClearColor( 0, 0, 0, 0 );

glEnable( GL_TEXTURE_2D ); // Need this to display a texture

glViewport( 0, 0, 640, 480 );

glMatrixMode( GL_PROJECTION );

glLoadIdentity();

glOrtho( 0, 640, 480, 0, -1, 1 );

glMatrixMode( GL_MODELVIEW );

glLoadIdentity();

}

void clean_up()

{

glDeleteTextures( 1, &texture );

SDL_Quit();

}

int main(int argc, char *argv[])

{

//Make sure the program waits for a quit

bool quit = false;

init();

init_GL();

loadImage();

drawImage();

while( quit == false )

{

if( SDL_PollEvent( &event ) )

{

//If a key was pressed

if( event.type == SDL_KEYDOWN )

{

switch( event.key.keysym.sym )

{

case SDLK_LEFT:

LEFT=true;

break;

case SDLK_RIGHT:

RIGHT=true;

break;

case SDLK_ESCAPE:

quit=true;

break;

}

}

//If a key was released

else if( event.type == SDL_KEYUP )

{

switch( event.key.keysym.sym )

{

case SDLK_LEFT:

LEFT=false;

break;

case SDLK_RIGHT:

RIGHT=false;

break;

}

}

}

if(LEFT==true){

x-=2;

drawImage();

}

else if(RIGHT==true){

x+=2;

drawImage();

}

}

clean_up();

return 0;

}

In above code i have used two bool variable(LEFT and RIGHT) and two float variables(x and y) to store the position of ┬ásprite. In the main function inside the loop we are taking the key input from the user. So when the user press left arrow key “LEFT bool variable is assigned TRUE” and when user releases the left arrow key ” LEFT bool variable is assigned FALSE”. Same applies for pressing right arrow key. So in this code :

if(LEFT==true){

x-=2;

drawImage();

}

else if(RIGHT==true){

x+=2;

drawImage();

}

when left arrow key is pressed “LEFT bool variable becomes TRUE” and x position of sprite is incremented by 2. Then we draw the sprite again. And when left arrow key is released “LEFT bool variable becomes FALSE” which means x position of sprite should not be updated. Same concept applies for moving right.

Now we have code to update the x and y position of ┬ásprite. But how to render the sprite with updated x and y coordinates. This is done by gTranslatef(x,y,z) function. It translates the position of sprite. So we’ll be updating x and y to move the sprite, and z will be zero. So in this code:

void drawImage()

{

// Clear the screen before drawing

glClear( GL_COLOR_BUFFER_BIT );

glTranslatef( x, y, 0 );

// Bind the texture to which subsequent calls refer to

glBindTexture( GL_TEXTURE_2D, texture );

glBegin( GL_QUADS );

// Top-left vertex (corner)

glTexCoord2i( 0, 0 );

glVertex3f( 100, 100, 0 );

// Bottom-left vertex (corner)

glTexCoord2i( 1, 0 );

glVertex3f( 228, 100, 0 );

// Bottom-right vertex (corner)

glTexCoord2i( 1, 1 );

glVertex3f( 228, 228, 0 );

// Top-right vertex (corner)

glTexCoord2i( 0, 1 );

glVertex3f( 100, 228, 0 );

glEnd();

glLoadIdentity();

SDL_GL_SwapBuffers();

}

when we update the position of x and y then we call the above function where we have included new code glTranslatef(x,y,z) which will make the sprite to be drawn in given x.y and z location.

So thats it. I hope this will give u some pretty basic idea. Now you can write your own code for moving 2d Sprite.

Gracias.