Code:
/*This source code copyrighted by Lazy Foo' Productions (2004-2012)
and may not be redistributed without written permission.*/
//The headers
#include "SDL/SDL.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include "math.h"
#include <stdio.h>
SDL_Event event;
//Event handler
float xpos = 0,ypos = 0,zpos = -5,xrot = 0,yrot = 0,zrot = 0;
//Rendering flag
bool upz=0;
int fps = 0;
GLuint tex;
GLuint LoadTexture( const char * filename, int width, int
height )
{
GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
unsigned char data2[width*height*3];
for(int i = 0; i < width * height * 3; i+=3){
data2[i] = data[i + 2];
data2[i+1] = data[i + 1];
data2[i+2] = data[i];
}
glGenTextures( 1, &texture ); //generate the texture with
glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE ); //set texture environment parameters
//here we are setting what textures to use and when. The MIN
//when the texture is near the view, and the MAG filter is which
//is far from the view.
//The qualities are (in order from worst to best)
//GL_NEAREST
//GL_LINEAR
//GL_LINEAR_MIPMAP_NEAREST
//GL_LINEAR_MIPMAP_LINEAR
//And if you go and use extensions, you can use Anisotropic
//even better quality, but this will do for now.
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );
//Here we are setting the parameter to repeat the texture
//to the edge of our shape.
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_REPEAT );
//Generate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, data2);
free( data ); //free the texture
return texture; //return whether it was successfull
}
void FreeTexture( GLuint texture )
{
glDeleteTextures( 1, &texture );
}
void ortho()
{
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 640, 0, 480);
glScalef(1, -1, 1);
glTranslatef(0, -480, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture( GL_TEXTURE_2D, tex );
glBegin(GL_QUADS);
glTexCoord2d(0.0,0.0); glVertex2f(0, 0);
glTexCoord2d(0.5,0.0); glVertex2f(64,0);
glTexCoord2d(1.0,1.0); glVertex2f(64,64);
glTexCoord2d(0.0,1.0); glVertex2f(0,64);
glEnd();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
unsigned short initGL()
{
//Initialize Projection Matrix
glViewport(0,0,640,480);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective(70.0f,(GLfloat)640/(GLfloat)480,0.1f,60.0f);
//Initialize Modelview Matrix
glMatrixMode( GL_MODELVIEW );
//Initialize clear color
glClearColor( 0.f, 0.f, 0.f, 0.f );
return 1;
}
unsigned short init()
{
//Initialize SDL
if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
{
return 0;
}
//Create Window
if( SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL ) == NULL )
{
return 0;
}
//Enable unicode
SDL_EnableUNICODE( SDL_TRUE );
//Initialize OpenGL
if( initGL() == 0 )
{
return 0;
}
//Set caption
SDL_WM_SetCaption( "OpenGL Test", NULL );
return 1;
}
void update()
{
//Clear color buffer
Uint8* key = SDL_GetKeyState(NULL);
if (key[SDLK_LEFT])
{
yrot-=2;
if(yrot==-360)
yrot=0;
}
if (key[SDLK_RIGHT])
{
yrot+=2;
if(yrot==360)
yrot=0;
}
float x=(sinf(yrot/180*3.141592654f)*0.2),z=(cosf(yrot/180*3.141592654f)*0.2);
if(key[SDLK_UP])
{
xrot-=2;
if(xrot==-92)
xrot=-90;
}
if(key[SDLK_DOWN])
{
xrot+=2;
if(xrot==92)
xrot=90;
}
if (key[SDLK_w])
{
zpos+=z;
xpos-=x;
}
if(key[SDLK_s])
{
zpos-=z;
xpos+=x;
}
if(key[SDLK_a])
{
xpos+=z;
zpos+=x;
}
if(key[SDLK_d])
{
xpos-=z;
zpos-=x;
}
if(key[SDLK_z] && xrot==-90)
{
ypos=-1;
upz=1;
}
if(key[SDLK_F1] && upz==1)
ypos-=0.1;
if(key[SDLK_F2] && upz==1)
ypos+=0.1;
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
glRotatef(xrot,1.0,0.0,0.0);
glRotatef(yrot,0.0,1.0,0.0);
glTranslatef(xpos,ypos,zpos);
glBegin(GL_QUADS);
glColor3f(1.0,1.0,0.0);
glVertex3f(-30.0,-0.5,30.0);
glVertex3f(30.0,-0.5,30.0);
glVertex3f(30.0,-0.5,-30.0);
glVertex3f(-30.0,-0.5,-30.0);
glEnd();
//Render quad
glBegin(GL_QUADS);
glColor3f(0.5,0.5,0.5);
glVertex3f(-0.5,-0.5,0.5);
glVertex3f(0.5,-0.5,0.5);
glVertex3f(0.5,0.5,0.5);
glVertex3f(-0.5,0.5,0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0);
glVertex3f(0.5,-0.5,0.5);
glVertex3f(0.5,-0.5,-0.5);
glVertex3f(0.5,0.5,-0.5);
glVertex3f(0.5,0.5,0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,1.0,0.0);
glVertex3f(-0.5,-0.5,0.5);
glVertex3f(-0.5,-0.5,-0.5);
glVertex3f(-0.5,0.5,-0.5);
glVertex3f(-0.5,0.5,0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,1.0);
glVertex3f(-0.5,-0.5,-0.5);
glVertex3f(0.5,-0.5,-0.5);
glVertex3f(0.5,0.5,-0.5);
glVertex3f(-0.5,0.5,-0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.89,0.89,0.9);
glVertex3f(-0.5,0.5,0.5);
glVertex3f(0.5,0.5,0.5);
glVertex3f(0.5,0.5,-0.5);
glVertex3f(-0.5,0.5,-0.5);
glEnd();
}
void clean_up()
{
//Quit SDL
SDL_Quit();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
}
int main( int argc, char *argv[] )
{
//Quit flag
unsigned short quit = 0;
//Initialize
if( init() == 0 )
{
return 1;
}
//The frame rate regulator
//Wait for user exit
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);
glEnable(GL_TEXTURE_2D);
glDepthFunc(GL_LEQUAL);
tex = LoadTexture("logo.bmp",64,64);
while( quit == 0 )
{
fps = SDL_GetTicks();
//Start the frame timer
//While there are events to handle
while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_QUIT )
{
quit = 1;
}
if (event.type==SDL_KEYDOWN)
{
if (event.key.keysym.sym==SDLK_ESCAPE)
quit = 1;
}
}
//Run frame update
update();
//Render frame
render();
if(upz)
ortho();
glFlush();
//Update screen
SDL_GL_SwapBuffers();
if ((SDL_GetTicks() - fps) < 33)
SDL_Delay( ( 33 ) - (SDL_GetTicks() - fps));
}
//Clean up
FreeTexture(tex);
clean_up();
return 0;
}