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; }