Aros/开发者/SDL
SDL_Init
SDL_SetVideoMode
SDL_Surface
SDL_Rect
SDL_PollEvent
SDL_EventType
SDL_FreeSurface
SDL_Quit
许多SDL游戏通过轮询(即持续读取)事件队列来工作。
https://wiki.libsdl.org/SDL_PollEvent
示例代码展示了丑陋的while(1) { SDL_PollEvent(...); }。
它会占用任何CPU资源。
更好的主循环是使用SDL_WaitEvent/SDL_WaitEventTimeout。
https://wiki.libsdl.org/SDL_WaitEvent https://wiki.libsdl.org/SDL_WaitEventTimeout
至少,这些调用不应该占用所有CPU。
#include <SDL/SDL.h>
#include "Application.h"
//Extern'd in Application.h; Used as forefront to access everything we create =D
Application* pApp;
int main(int args, char* argv[])
{
//Create the application on the heap for actual use
pApp = new Application();
//Initialize the application. If something fails, return -1 (I like -1 for errors)
if(pApp->Init() != true)
{
return -1;
}
//This should successfully run our application
//Should go through Input, Logic, and Rendering
pApp->Run();
//This will clean up everything, deallocating dynamically allocated memory
//Uninitializing SDL, etc.
pApp->Quit();
//Out of habit, I always check to make sure a pointer has a value (other than NULL)
//Before I deallocate it. I also ALWAYS set it to NULL immediately after.
//Good habit to get into because it is preventative for memory leaks
if(pApp)
{
delete pApp;
pApp = NULL;
}
//Lastly, end the application, returning 0 to indicate that nothing went wrong
return 0;
}
#ifndef APPLICATION_H_INCLUDED
#define APPLICATION_H_INCLUDED
#include <SDL/SDL.h>
class Application
{
private:
//We'll keep adding here as we go along
bool m_bDone;
public:
Application();
~Application();
bool Init();
void Run();
void TakeInput(SDL_Event* pEvent);
void Update();
void Render();
void Quit();
};
//We'll use this global pointer to access things like the window later on
extern Application* pApp;
#endif // APPLICATION_H_INCLUDED
#include "Application.h"
Application::Application()
{
//Standard constructor we'll use to initialize variables with default values
//The program just started, we certainly are not done yet!
m_bDone = false;
}
Application::~Application()
{
//Here, we'll deallocate any dynamically allocated memory we may have missed
}
bool Application::Init()
{
//Initialize SDL and return false if anything goes wrong
//We'll add more initializations here for anything else we use
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
return false;
}
//Lastly return true to indicate that the initialization was successful
return true;
}
void Application::Run()
{
//This function implements our loop
//Any calls that should be made each frame should be put in this loop
//the m_bDone variable will track whether the program is ready to exit
while(!m_bDone)
{
m_bDone = true;
}
}
void Application::TakeInput(SDL_Event* pEvent)
{
//We'll use this function to take input from the user and act upon it
}
void Application::Update()
{
//This is where all the magic happens!
//After receiving input, this is where we act on that input
//and actually make things happen =D
}
void Application::Render()
{
//Here, we will draw our images to the screen
}
void Application::Quit()
{
//Uninitialize SDL, we'll also deallocate any memory we dynamically allocate
SDL_Quit();
}
game loop
while( SDL_PollEvent( &event ) )
{
myHero.handle_input();
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
myHero.move( blahbox );
//Set the camera
myHero.set_camera();
handle_input()
if( event.type == SDL_KEYDOWN )
{
if( SDLK_LEFT ) { xForce -= HERO_WIDTH / 2; }
if( SDLK_RIGHT ){ xForce += HERO_WIDTH / 2; }
}
else if( event.type == SDL_KEYUP )
{
if( SDLK_LEFT ) { xForce = 0; }
if( SDLK_RIGHT ) { xForce = 0; }
}
move()
void Hero::move(SDL_Rect blahbox)
{
//Move the dot left or right
if( xForce != 0 ) { xAcc = xForce / HERO_MASS; }
if( xForce == 0 ) { xVel = xAcc = 0; }
xVel = xVel + xAcc;
box.x = box.x + xVel;
//If the dot went too far to the left or right or touched a wall
if( ( box.x < 0 ) || ( box.x + HERO_WIDTH > LEVEL_WIDTH ) || check_collision( box, blahbox) )
{
//move back
box.x = box.x - xVel;
}
}
what i was going for is force is applied when a key is pressed,
acceleration = Force / Mass
Velocity = Velocity + Acceleration
etc...
/* Here's the include */
#include "SDL.h"
SDL_Surface* screen;
void startGame()
{
/* Load my picture */
SDL_Surface* pic = SDL_LoadBMP("mypic.bmp");
/* Here's where I'll draw it */
SDL_Rect destRect;
if(pic != NULL)
{
destRect.x = screen->w/2 - pic->w/2;
destRect.y = screen->h/2 - pic->h/2;
}
/* Here are two rectangles */
/* I initialize rect.x, rect.y, rect.w, and rect.h all at once */
SDL_Rect rect1 = {40, 40, 300, 200};
SDL_Rect rect2 = {200, 100, 160, 160};
/* Start the main loop */
SDL_Event event;
Uint8 done = 0;
while (!done)
{
/* Check for events */
while (SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
done = 1;
}
if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_ESCAPE)
{
done = 1;
}
}
}
/* Clear the screen */
SDL_FillRect(screen, NULL, 0x000000);
/* Red rectangle */
SDL_FillRect(screen, &rect1, SDL_MapRGB(screen->format, 200, 0, 0));
/* White rectangle */
SDL_FillRect(screen, &rect2, SDL_MapRGB(screen->format, 255, 255, 255));
/* Draw my picture */
SDL_BlitSurface(pic, NULL, screen, &destRect);
/* Send all this to the monitor */
SDL_Flip(screen);
}
/* Free up the picture memory */
SDL_FreeSurface(pic);
return;
}
int main(int argc, char *argv[])
{
/* Initialize SDL */
if( SDL_Init(SDL_INIT_VIDEO) < 0 )
return 0;
/* Initialize the screen surface */
screen = SDL_SetVideoMode(400, 300, 32, SDL_SWSURFACE);
if ( screen == NULL )
return 0;
/* Now do whatever we want! */
startGame();
SDL_Quit();
return 0;
}
如果SDL失败
if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
{
fprintf(stderr, "Failed to initialize SDL. [%s]\n", SDL_GetError());
exit(1);
}
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
if( screen == NULL )
{
fprintf(stderr, "Failed to set video mode. [%s]\n", SDL_GetError());
exit(1);
}
SDL_Event evt;
bool done = false;
while( !done )
{
while( SDL_PollEvent( &evt ) )
{
switch( evt.type )
{
case SDL_QUIT:
done = true;
break;
case SDL_KEYUP:
if( evt.key.keysym.sym == SDLK_ESCAPE )
done = true;
break;
default:
break;
}
}
}
#include <sdl.h>
int main( int argc, char **argv)
{
SDL_Event evt;
bool done = false;
// initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
{
fprintf(stderr, "Failed to initialize SDL. [%s]\n", SDL_GetError());
exit(1);
}
// create a software surface/window
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
if( screen == NULL )
{
fprintf(stderr, "Failed to set video mode. [%s]\n", SDL_GetError());
exit(1);
}
// main game loop
while( !done )
{
// check for events generated from SDL
while( SDL_PollEvent( &evt ) )
{
switch( evt.type )
{
case SDL_QUIT:
done = true;
break;
case SDL_KEYUP:
if( evt.key.keysym.sym == SDLK_ESCAPE )
done = true;
break;
default:
break;
}
}
}
SDL_Quit();
return 0;
}
Uint32 color1 = SDL_MapRGB(screen->format, 0x00, 0x00, 0xFF); Uint32 color2 = SDL_MapRGB(screen->format, 0x00, 0xFF, 0x00); Uint32 currentColor = color1;
case SDL_KEYUP:
if( evt.key.keysym.sym == SDLK_ESCAPE )
done = true;
else if( evt.key.keysym.sym == SDLK_SPACE )
{
currentColor = ( currentColor == color1 ) ? color2 : color1;
SDL_FillRect( screen, NULL, currentColor);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
break;
case SDL_KEYDOWN: printf( "KEYDOWN: %c\n", evt.key.keysym.unicode); break;
//SDL_Mixer
#include <SDL/SDL_mixer.h>
//
Mix_Chuck* effect1;
Mix_Chuck* effect2;
Mix_Music* music;
Mix_OpenAudio(22050,MIX_DEFAULT_FORMAT,2,4096);
music=Mix_LoadMUS("sound.wav");
effect1=Mix_LoadWAV("sound.wav");
effect2=Mix_LoadWAV("sound2.wav");
screen=SDL_SetVideoMode(x,y,res,SDL_SWSURFACE);
//in events loop
Mix_PlayMusic(music-1);
case SDL_KEYDOWN:
switch(event.key,keysym.sym)
{
case SDLK_1:
Mix_PlayChannel(-1,effect1,0);
case SDLK_1:
Mix_PlayChannel(-1,effect2,0);
}
//close
Mix_FreeChuck(effect2);
Mix_FreeChuck(effect1);
Mix_FreeMusic(music);
Mix_CloseAudio;
SDL_QUIT();
//This program is made by thecplusplusguy from YouTube for demonstration purposes.
//Feel free to read, learn, or modify the source as you wish, LGPL licence, I guess.
//http://www.youtube.com/user/thecplusplusguy
//keep this header comment for advertisement :)
//compile in case of Windows normally, in case of Linux normally as well, so:
//g++ particle.cpp -lSDL
//Code::blocks: build and run
#include <SDL/SDL.h>
#include <iostream>
#include <vector> //to store the particles (I like std::vector :D)
#include <cstdlib> //for the random numbers
#include <ctime>
class particle{ //represent 1 particle
float x,y,xvel,yvel; //position && speed
Uint32 endTime; //death time
Uint8 color; //color
public:
particle(float X,float Y,float Xvel,float Yvel,int life,Uint8 Color);
void move();
void show();
bool isDead(); //true if the particle dead else false
};
particle::particle(float X,float Y,float Xvel,float Yvel,int life,Uint8 Color)
{
//initialize the variables, nothing new
x=X;
y=Y;
xvel=Xvel;
yvel=Yvel;
endTime=SDL_GetTicks()+life; //the end time, is the current time + the time, while the particle lives
color=Color;
}
void particle::move()
{
//move
x+=xvel;
y+=yvel;
//if it is outside of the screen, set it back to the edge of the screen
if(x<0)
x=0;
if(y<0)
y=0;
if(x>SDL_GetVideoSurface()->w)
x=SDL_GetVideoSurface()->w-1;
if(y>SDL_GetVideoSurface()->h)
y=SDL_GetVideoSurface()->h-1;
}
void particle::show()
{
//just set the pixel to the current color at the current position (pixel manipulation tutorial)
Uint8* pixels=(Uint8*)SDL_GetVideoSurface()->pixels;
Uint8* pixel=pixels+(int)y*SDL_GetVideoSurface()->pitch+(int)x;
*pixel=color;
}
bool particle::isDead()
{
//read above, what it does
return (SDL_GetTicks()>=endTime || x==0 || y==0 || x==SDL_GetVideoSurface()->w-1 || y==SDL_GetVideoSurface()->h-1);
}
//the particle engine will store all of the particle, and their initialize position
class particleEngine{
std::vector<particle*> particles; //this vector represent all of the particle
int x,y,maxparticle;
public:
particleEngine(int maxpart,int X, int Y);
~particleEngine(); //need for deallocate allocated space
void refresh(); //move && show the particles
};
particleEngine::particleEngine(int maxpart,int X, int Y)
{
x=X;
y=Y;
maxparticle=maxpart;
for(int i=0;i<maxparticle;i++) //create maxparticle number of particles with random values both for position, velocity, life, color
particles.push_back(new particle(x+rand()%6-3,y+rand()%6-3,rand()%10+(float)rand()/(float)RAND_MAX-5,rand()%10+(float)rand()/(float)RAND_MAX-5,500+rand()%1000,rand()%255));
}
particleEngine::~particleEngine()
{
//deallocate all reserved memory
for(int i=0;i<maxparticle;i++)
delete particles[i];
}
void particleEngine::refresh()
{
for(int i=0;i<maxparticle;i++)
{
if(particles[i]->isDead()) //if dead
{
delete particles[i]; //delete the earlier one and create a new
particles[i]=new particle(x+rand()%6-3,y+rand()%6-3,rand()%10+(float)rand()/(float)RAND_MAX-5,rand()%10+(float)rand()/(float)RAND_MAX-5,500+rand()%2000,rand()%255);
}else{ //else
particles[i]->move(); //move && show
particles[i]->show();
}
}
}
int main(int argc,char** argv)
{
//this should be familiar to you
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen;
screen=SDL_SetVideoMode(640,480,8,SDL_SWSURFACE);
bool running=true;
const int FPS=30; //make the FPS bigger, for quicker animation
Uint32 start;
srand(time(0)); //seed the random number generator
particleEngine ps(5000,screen->w/2,screen->h/2); //create the particles
while(running)
{
start=SDL_GetTicks();
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
}
}
SDL_FillRect(screen,&screen->clip_rect,SDL_MapRGB(screen->format,0x00,0x00,0x00)); //clear the screen
//logic
ps.refresh(); //refresh the particles
SDL_Flip(screen);
if(1000/FPS>SDL_GetTicks()-start)
SDL_Delay(1000/FPS-(SDL_GetTicks()-start));
}
SDL_Quit();
return 0;
}
libSDL.a libSDL_gfx.a libSDLGL.a libSDL_image.a libSDL_mixer.a libSDL_net.a libSDL_sound.a libSDL_ttf.a
SDL使用基于事件的输入。所有SDL应用程序都自行处理事件。因此,每个SDL应用程序在AROS上启动一个繁忙循环,尽可能多地占用CPU时间。似乎SDL软件编写得也不好,大部分代码使用事件轮询(而不是等待事件)和小延迟,例如此处。似乎许多程序员根本不在乎SDL游戏即使在空闲状态下是否消耗100%的CPU时间。
st=SDL_GetAppState(); if ((st==SDL_APPACTIVE) || (! st) ) SDL_Delay(1000) else SDL_Delay(0) PollEvents... ...
SDL中的颜色通常存储在Uint32变量中。此类型(以及其他类型)由SDL定义,以便您可以确保在每个不同的平台/操作系统上获得精确的32位,而不是模棱两可的“unsigned int”。在32位表面上,每个颜色分量获得8位。如果我这样写一个十六进制常量:0x50a600ff,并且像素格式为ARGB,那么我的分量将是alpha = 0x50(80),red = 0xa6(166),green = 0x00(0),blue = 0xff(255)。在那里您可以看到颜色分量范围从0到255(256个值)。这些分量可以分别存储在Uint8变量中。
SDL使用计算机图形的标准坐标轴。点(0,0)位于屏幕的左上角。x坐标向右增加,y坐标向下增加。这确实有一个小的副作用,即坐标系是左手系(角度按顺时针方向测量)。
将某些内容包装在您自己的函数中是值得的。例如,您可以编写一个将图像绘制到屏幕上的函数,只需传入表面指针和坐标即可。发现将键盘和操纵杆处理都包装到一个函数中非常容易,因此我的游戏接受任一输入方法作为特定玩家的输入,并且使用它的代码很简洁。
旧式OpenGL 1.1 - 立即模式:glBegin()、glEnd()、glVertex()等
新式OpenGL 2 3 4 - 顶点数组
glColor() - 即使经常与立即模式一起使用,这对于为后续要绘制的顶点设置常量颜色也是可以的。
glNormal()、glTexCoord() - 与glColor()类似,尽管设置这些为常量值的情况很少见。
glTranslate()、glLoadMatrix()、glMultMatrix()等 - 这些是进行变换的方式。
glMatrixMode() - 用于更改要应用更改的矩阵。不要在每一帧都执行glFrustum()、glOrtho()、gluPerspective()或类似操作(除非其参数发生更改)。在大多数情况下,这属于您的重塑函数。
NOTE: all of the previous functionality is deprecated, and done quite differently in "modern" OpenGL
glEnableClientState()、glVertexPointer()(以及法线、纹理坐标、颜色的等效项)、glDrawArrays()、glDrawElements() - 虽然已弃用,但“理念”通常与现代OpenGL相同(但使用的函数不同)。为OpenGL提供指向元素的指针,它将绘制这些元素。当然,在可能的情况下,您希望使用VBO(将数据上传到显存)。如果您希望将代码也编译到已支持它的平台上,可以使用一些#ifdef来做到这一点。
GL_POINTS、GL_LINES、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN - 这些仍然存在于每个OpenGL(或OpenGL ES)实现中。随意使用。
注意:所有先前功能(立即模式除外)都适用于OpenGL ES1。OpenGL ES2广泛使用着色器,并且如果不使用大量#ifdef或类似方法,则无法编写既适用于TinyGL或OpenGL1又适用于OpenGL ES2的代码,假设您执行的操作比使用指定颜色清除屏幕更复杂。
GL_QUADS、GL_QUAD_STRIP、GL_POLYGON - 避免使用。已弃用,并且OpenGL ES1和ES2中都没有。改用索引的GL_TRIANGLES或GL_TRIANGLE_STRIP。
http://www.amigacoding.de/index.php?topic=456.0
http://www.amigacoding.de/index.php?topic=494.0
使用纹理图集的VBO(顶点缓冲对象)(使用纹理数组创建一个包含所有纹理的大纹理)- 为每个纹理图集使用多个VBO -
着色器
更优化地使用OpenGL状态机。切换着色器和纹理通常比实际绘制调用开销更大,因此必须以最小化这种切换的方式设计代码,例如,在切换到另一个着色器和/或纹理之前,执行所有需要特定着色器和纹理的绘制调用。
http://forum.unity3d.com/threads/63149-After-playing-minecraft...
光照
阴影
反射
凹凸/视差贴图
避免以下内容
//pcguy
#include <iostream>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
void init()
{
glClearColor(0.0,0.0,0.0,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,640.0/480.0,1.0,500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(0.0,2.0,-5.0);
glVertex3f(-2.0,-2.0,-5.0);
glVertex3f(2.0,-2.0,-5.0);
glEnd();
}
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
bool running=true;
Uint32 start;
SDL_Event event;
init();
while(running)
{
start=SDL_GetTicks();
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
}
}
display();
SDL_GL_SwapBuffers();
if(1000/30>(SDL_GetTicks()-start))
SDL_Delay(1000/30-(SDL_GetTicks()-start));
}
SDL_Quit();
return 0;
}
int main( int argc, char **argv)
{
// graphics properties
const int width = 640; // width of the game window
const int height = 480; // height of the game window
const float fov = 45.0f; // field of view (degrees)
const float nearClip = 1.0f; // near clip plane (don't set to zero)
const float farClip = 100.0f; // far clip plane
// initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
{
fprintf(stderr, "Failed to initialize SDL. [%s]\n", SDL_GetError());
exit(1);
}
// set desired OpenGL attributes prior to selecting a video mode
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); // use 16 bits for depth buffer
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // enable double buffering
// create an OpenGL surface/window
SDL_Surface *screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
if( screen == NULL )
{
fprintf(stderr, "Failed to set video mode. [%s]\n", SDL_GetError());
exit(1);
}
// initialize OpenGL
if( SetupOpenGL( width, height, fov, nearClip, farClip) == -1 )
{
fprintf( stderr, "Failed to setup OpenGL.\n" );
exit(1);
}
// main game loop
bool done = false;
while( !done )
{
RenderScene();
if( ProcessInput() )
done = true;
}
SDL_Quit();
return 0;
}
int SetupOpenGL( int width, int height, float fov, float nearClip, float farClip )
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
float ar = (GLfloat)width / height; // display aspect ratio
// setup projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ar, nearClip, farClip);
// setup model view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// setup depth buffer
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// misc. GL settings
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glViewport( 0, 0, width, height );
return 0;
}
void RenderScene( void )
{
// render everything for the current frame
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// move off center so the quad is visible
glTranslatef(-1.0f, 0.0f, -5.0f);
// draw quad as red
glColor3f( 1.0f, 0.0, 0.0 );
// render the quad
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
// update display
SDL_GL_SwapBuffers();
}
bool ProcessInput( void )
{
// runs the input processing loop
// returns true if any input has requested the application to exit
SDL_Event evt;
bool exitFlag = false;
// check for events generated from SDL
while( SDL_PollEvent( &evt ) )
{
switch( evt.type )
{
case SDL_QUIT:
exitFlag = true;
break;
case SDL_KEYUP:
if( evt.key.keysym.sym == SDLK_ESCAPE )
exitFlag = true;
break;
default:
break;
}
}
return exitFlag;
}
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <sdl.h>
#include <sdl_opengl.h>
// function prototypes
int SetupOpenGL( int width, int height, float fov, float nearClip, float farClip );
void RenderScene( void );
bool ProcessInput( void );
int main( int argc, char **argv)
{
// graphics properties
const int width = 640; // width of the game window
const int height = 480; // height of the game window
const float fov = 45.0f; // field of view (degrees)
const float nearClip = 1.0f; // near clip plane (don't set to zero)
const float farClip = 100.0f; // far clip plane
// initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) == -1 )
{
fprintf(stderr, "Failed to initialize SDL. [%s]\n", SDL_GetError());
exit(1);
}
// set desired OpenGL attributes prior to selecting a video mode
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); // use 16 bits for depth buffer
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // enable double buffering
// create an OpenGL surface/window
SDL_Surface *screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
if( screen == NULL )
{
fprintf(stderr, "Failed to set video mode. [%s]\n", SDL_GetError());
exit(1);
}
// initialize OpenGL
if( SetupOpenGL( width, height, fov, nearClip, farClip) == -1 )
{
fprintf( stderr, "Failed to setup OpenGL.\n" );
exit(1);
}
// main game loop
bool done = false;
while( !done )
{
RenderScene();
if( ProcessInput() )
done = true;
}
SDL_Quit();
return 0;
}
int SetupOpenGL( int width, int height, float fov, float nearClip, float farClip )
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
float ar = (GLfloat)width / height; // display aspect ratio
// setup projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ar, nearClip, farClip);
// setup model view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// setup depth buffer
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// misc. GL settings
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glViewport( 0, 0, width, height );
return 0;
}
void RenderScene( void )
{
// render everything for the current frame
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// move off center so the quad is visible
glTranslatef(-1.0f, 0.0f, -5.0f);
// draw quad as red
glColor3f( 1.0f, 0.0, 0.0 );
// render the quad
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
// update display
SDL_GL_SwapBuffers();
}
bool ProcessInput( void )
{
// runs the input processing loop
// returns true if any input has requested the application to exit
SDL_Event evt;
bool exitFlag = false;
// check for events generated from SDL
while( SDL_PollEvent( &evt ) )
{
switch( evt.type )
{
case SDL_QUIT:
exitFlag = true;
break;
case SDL_KEYUP:
if( evt.key.keysym.sym == SDLK_ESCAPE )
exitFlag = true;
break;
default:
break;
}
}
return exitFlag;
}
//
//
//
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//position of light source
float pos[]={-2.0,2.0,3.0,1.0};
glLightfv(GL_LIGHT0,GL_POSITION,pos);
//diffused
float dif[]={1.0,1.0,1.0,1.0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
//ambient light
float amb[]={0.2,0.2,0.2,1.0};
glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
//http://www.youtube.com/user/thecplusplusguy
//load animation main.cpp
#include "functions.h"
#include "objloader.h"
#include "text.h"
float angle=0.0;
int cube;
objloader obj;
bool mousein=false;
coordinate spherecenter(0.0,0.0,0.0);
coordinate raystart(0.0,0.0,0.0);
text* tex;
std::vector<unsigned int> frames;
int curframe=0;
void init()
{
glClearColor(0.5,0.5,0.5,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,640.0/480.0,1.0,500.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
cube=obj.load("test10.obj");
std::vector<unsigned int> chars;
char tmp[40];
for(int i=0;i<26;i++)
{
sprintf(tmp,"font/%d.obj",i);
unsigned int tmp2=obj.load(tmp);
chars.push_back(tmp2);
}
tex=new text(0.9,0.8,chars);
// cube=loadObject("test.obj");
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float col[]={1.0,1.0,1.0,1.0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,col);
initskybox();
loadAnimation(frames,"anim/anim",250,obj);
}
coordinate p1(-5.0,5.0,-5.0);
coordinate p2(5.0,5.0,-5.0);
coordinate p3(5.0,-5.0,-5.0);
coordinate p4(-5.0,-5.0,-5.0);
/*
*/
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Control(0.2,0.2,mousein);
drawSkybox(50.0);
UpdateCamera();
float pos[]={-1.0,1.0,-2.0,1.0};
glLightfv(GL_LIGHT0,GL_POSITION,pos);
// glTranslatef(0.0,0.0,-4.0);
// glRotatef(angle,1,1,1);
glDisable(GL_LIGHTING);
// if(raysphere(spherecenter.x,spherecenter.y,spherecenter.z,0.0,0.0,1.0,raystart.x, raystart.y,raystart.z,1.0))
if(rayplane(0.0,0.0,1.0,raystart.x,raystart.y,raystart.z,0.0,0.0,-1.0,p1,p2,p3,p4))
glColor3f(1.0,0.0,0.0);
else
glColor3f(1.0,1.0,1.0);
//xs+t*xd
glBegin(GL_LINES);
glVertex3f(raystart.x,raystart.y,raystart.z);
glVertex3f(raystart.x+100*0,raystart.y+100*0,raystart.z+100*-1);
glEnd();
glBegin(GL_QUADS);
glVertex3f(-5.0,5.0,-5.0);
glVertex3f(5.0,5.0,-5.0);
glVertex3f(5.0,-5.0,-5.0);
glVertex3f(-5.0,-5.0,-5.0);
glColor3f(0,0,0);
glVertex3f(-10.0,0.0,-10.0);
glVertex3f(-10.0,-5.0,10.0);
glVertex3f(10.0,-5.0,10.0);
glVertex3f(10.0,0.0,-10.0);
glEnd();
glEnable(GL_LIGHTING);
glCallList(cube);
tex->drawText(coordinate(10,0,0),coordinate(angle,0,0),"HELLO\nWORLD\nFROM\nOPENGL");
glTranslatef(-20,0,0);
glCallList(frames[curframe]);
curframe++;
if(curframe>249)
curframe=0;
std::cout << curframe << std::endl;
glColor3f(1.0,1.0,1.0);
}
coordinate p5(-10.0,0,-10.0);
coordinate p6(-10.0,-5.0,10.0);
coordinate p7(10.0,-5.0,10.0);
coordinate p8(10.0,0,-10.0);
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
bool running=true;
Uint32 start;
SDL_Event event;
init();
bool b[4]={0,0,0,0};
while(running)
{
start=SDL_GetTicks();
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
case SDL_MOUSEBUTTONDOWN:
mousein=true;
SDL_ShowCursor(SDL_DISABLE);
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_p)
{
mousein=false;
SDL_ShowCursor(SDL_ENABLE);
break;
}
if(event.key.keysym.sym==SDLK_ESCAPE)
{
running=false;
break;
}
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=1;
break;
case SDLK_LEFT:
b[1]=1;
break;
case SDLK_DOWN:
b[2]=1;
break;
case SDLK_RIGHT:
b[3]=1;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=0;
break;
case SDLK_LEFT:
b[1]=0;
break;
case SDLK_DOWN:
b[2]=0;
break;
case SDLK_RIGHT:
b[3]=0;
break;
}
break;
}
}
if(b[0])
raystart.y+=0.3;
if(b[1])
raystart.x-=0.3;
if(b[2])
raystart.y-=0.3;
if(b[3])
raystart.x+=0.3;
display();
SDL_GL_SwapBuffers();
angle+=0.5;
if(angle>360)
angle-=360;
coordinate cameraPos=camPos();
if(spheresphere(cameraPos,2.0,coordinate(0,0,0),1.0))
std::cout << "collision\n";
sphereplane(cameraPos,coordinate(0,0,1),p1,p2,p3,p4,2.0);
sphereplane(cameraPos,coordinate(0,0.9701425,0.242535625),p5,p6,p7,p8,2.0);
moveTo(cameraPos);
if(1000/30>(SDL_GetTicks()-start))
SDL_Delay(1000/30-(SDL_GetTicks()-start));
}
SDL_Quit();
killskybox();
delete tex;
return 0;
}
//http://www.youtube.com/user/thecplusplusguy
//watch the video for explonation
//ray-sphere and ray-plane collision detection.
//if you find a bug, let me know
#include "functions.h"
#include "objloader.h"
float angle=0.0;
int cube;
objloader obj;
bool mousein=false;
coordinate spherecenter(0.0,0.0,0.0);
coordinate raystart(0.0,0.0,0.0);
void init()
{
glClearColor(0.5,0.5,0.5,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,640.0/480.0,1.0,500.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
cube=obj.load("test10.obj");
// cube=loadObject("test.obj");
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float col[]={1.0,1.0,1.0,1.0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,col);
initskybox();
}
coordinate p1(-5.0,5.0,-5.0);
coordinate p2(5.0,5.0,-5.0);
coordinate p3(5.0,-5.0,-5.0);
coordinate p4(-5.0,-5.0,-5.0);
/*
*/
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Control(0.2,0.2,mousein);
drawSkybox(50.0);
UpdateCamera();
float pos[]={-1.0,1.0,-2.0,1.0};
glLightfv(GL_LIGHT0,GL_POSITION,pos);
// glTranslatef(0.0,0.0,-4.0);
// glRotatef(angle,1,1,1);
glDisable(GL_LIGHTING);
// if(raysphere(spherecenter.x,spherecenter.y,spherecenter.z,0.0,0.0,1.0,raystart.x, raystart.y,raystart.z,1.0))
if(rayplane(0.0,0.0,1.0,raystart.x,raystart.y,raystart.z,0.0,0.0,-1.0,p1,p2,p3,p4))
glColor3f(1.0,0.0,0.0);
else
glColor3f(1.0,1.0,1.0);
//xs+t*xd
glBegin(GL_LINES);
glVertex3f(raystart.x,raystart.y,raystart.z);
glVertex3f(raystart.x+100*0,raystart.y+100*0,raystart.z+100*-1);
glEnd();
glBegin(GL_QUADS);
glVertex3f(-5.0,5.0,-5.0);
glVertex3f(5.0,5.0,-5.0);
glVertex3f(5.0,-5.0,-5.0);
glVertex3f(-5.0,-5.0,-5.0);
glEnd();
glEnable(GL_LIGHTING);
glCallList(cube);
glColor3f(1.0,1.0,1.0);
}
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
bool running=true;
Uint32 start;
SDL_Event event;
init();
bool b[4]={0,0,0,0};
while(running)
{
start=SDL_GetTicks();
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
case SDL_MOUSEBUTTONDOWN:
mousein=true;
SDL_ShowCursor(SDL_DISABLE);
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_p)
{
mousein=false;
SDL_ShowCursor(SDL_ENABLE);
break;
}
if(event.key.keysym.sym==SDLK_ESCAPE)
{
running=false;
break;
}
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=1;
break;
case SDLK_LEFT:
b[1]=1;
break;
case SDLK_DOWN:
b[2]=1;
break;
case SDLK_RIGHT:
b[3]=1;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=0;
break;
case SDLK_LEFT:
b[1]=0;
break;
case SDLK_DOWN:
b[2]=0;
break;
case SDLK_RIGHT:
b[3]=0;
break;
}
break;
}
}
if(b[0])
raystart.y+=0.3;
if(b[1])
raystart.x-=0.3;
if(b[2])
raystart.y-=0.3;
if(b[3])
raystart.x+=0.3;
display();
SDL_GL_SwapBuffers();
angle+=0.5;
if(angle>360)
angle-=360;
if(1000/30>(SDL_GetTicks()-start))
SDL_Delay(1000/30-(SDL_GetTicks()-start));
}
SDL_Quit();
killskybox();
return 0;
}