#include #include #define GL_GLEXT_PROTOTYPES #include #include #include #include #include #include #include "SDL.h" #include #include "texturesdl.h" #include "shader.h" #include "vector.h" #include "bullet.h" class BulletAdder { public: unsigned int time; Bullet bullet; BulletAdder(unsigned int time, Bullet bullet) { this->time = time; this->bullet = bullet; } bool operator<(const BulletAdder& ba) { return time < ba.time; }; }; class BulletAdderComparison { bool reverse; public: BulletAdderComparison(const bool& revparam = false) { reverse = revparam; }; bool operator()(const BulletAdder& left, const BulletAdder& right) { return (reverse ? left.time < right.time : left.time > right.time); }; }; std::list bullets; std::priority_queue, BulletAdderComparison> bullets_queue; void create_pattern1(unsigned int base) { for(int j = 0; j < 8; j++) { for(float i = 0; i < M_PI; i += 0.1) { bullets_queue.push(BulletAdder(base + j * 400 + (unsigned int)(i*100), Bullet( Vector3(50.0 + sinf(j % 2 ? M_PI_2 + i : M_PI - i + M_PI_2) * 9, 80 + cosf(M_PI_2 + i) * 10, 0), Vector3(sinf(j % 2 ? M_PI_2 + i : M_PI - i + M_PI_2) / 150.0, -0.01, 0), 5))); } } } void create_pattern2(unsigned int base) { for(float i = 0; i < M_PI * 16; i += 0.1) { bullets_queue.push(BulletAdder(base + (unsigned int)(i*40), Bullet( Vector3(50.0 + cosf(i) * 5, 50.0 + sinf(i) * 5, 0), Vector3(cosf(i) / 100.0, sinf(i) / 100.0, 0), 5))); } } void create_pattern2_2(unsigned int base) { for(float i = 0; i < M_PI * 64; i += 0.1) { bullets_queue.push(BulletAdder(base + (unsigned int)(i*40), Bullet( Vector3(50.0 + cosf(i) * 5, 50.0 + sinf(i) * 5, 0), Vector3(cosf(i + i / 50.0) / 100.0, sinf(i + i / 50.0) / 100.0, 0), 5))); } } void create_pattern3(unsigned int base) { for(float i = 0; i < 101; i++) { bullets_queue.push(BulletAdder(base + i, Bullet( Vector3(i, 90.0 - sinf(i), 0), Vector3(cosf(i) / 100.0, (-5.0 + sinf(i)) / 200.0, 0), 5))); } } void create_bullets() { create_pattern1(50); create_pattern2(9000); create_pattern3(12000); //create_pattern2_2(100); } int main() { if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError()); return 1; } SDL_Surface *surface = SDL_SetVideoMode(640, 480, 0, SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWSURFACE); if(surface == NULL) { fprintf(stderr, "Failed to set video mode: %s\n", SDL_GetError()); return 1; } SDL_Event event; bool running = true; bool paused = false; SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_POINT_SPRITE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); glClearColor(0, 0, 0, 0); glClearDepth(1); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); create_bullets(); TextureSDL texture1("foo.png"); TextureSDL texture2("foo2.png"); GLFragmentShader shader1("bullet_fragment.glsl"); GLVertexShader shader2("bullet_vertex.glsl"); GLShaderProgram program; program.attach(shader1); program.attach(shader2); program.link(); FTPixmapFont font("/usr/share/fonts/TTF/DejaVuSansMono.ttf"); font.FaceSize(12); float f = 0.0; float fps = 0.0; unsigned int lasttick = SDL_GetTicks(); unsigned int elapsed = 0; unsigned int lastframes = 0, frames = 0; while(running) { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_ESCAPE: running = false; break; case SDLK_SPACE: paused = !paused; lasttick = SDL_GetTicks(); break; default: break; } break; } } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45, 640. / 480., 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); unsigned int tick = SDL_GetTicks(); unsigned int step = tick - lasttick; lasttick = tick; if(!paused) { f += 0.0005 * step; elapsed += step; while(bullets_queue.size() && bullets_queue.top().time <= elapsed) { BulletAdder ba = bullets_queue.top(); Bullet& bullet = ba.bullet; bullets_queue.pop(); bullets.push_back(bullet); } } gluLookAt( 5 * sinf(f), 1, 5 * cosf(f), 0, 0, 0, 5 * sinf(f), 2, 5 * cosf(f)); glBegin(GL_LINES); for(int i = -10; i < 11; i++) { if(i % 5 == 0) glColor3f(1, 1, 1); else glColor3f(.5, .5, .5); glVertex3f(i, 0, -10); glVertex3f(i, 0, 10); glVertex3f(-10, 0, i); glVertex3f(10, 0, i); } glEnd(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 100, 0, 100, 0, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); program.use(); std::list::iterator it; glPointSize(16.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture2.tex()); glBegin(GL_POINTS); for(it = bullets.begin(); it != bullets.end();) { Bullet& b = (*it); if(!paused) { b.pos.x += b.direction.x * step; b.pos.y += b.direction.y * step; b.pos.z += b.direction.z * step; } glVertex4f(b.pos.x, b.pos.y, b.direction.x, b.direction.y); //glColor3f(b.color.r, b.color.g, b.color.b); /*glTexCoord2f(0, 0); glVertex3f(b.pos.x-1, b.pos.y-1, b.pos.z); glTexCoord2f(1, 0); glVertex3f(b.pos.x+1, b.pos.y-1, b.pos.z); glTexCoord2f(1, 1); glVertex3f(b.pos.x+1, b.pos.y+1, b.pos.z); glTexCoord2f(0, 1); glVertex3f(b.pos.x-1, b.pos.y+1, b.pos.z);*/ if(b.pos.x < -b.radius || b.pos.x > 100+b.radius || b.pos.y < -b.radius || b.pos.y > 100+b.radius) { it = bullets.erase(it); } else { it++; } } glEnd(); //glDisable(GL_POINT_SPRITE); glDisable(GL_TEXTURE_2D); glUseProgram(0); char s[0xff]; snprintf(s, 0xff, "Bullets: %d", (int)bullets.size()); glRasterPos2f(1, 1); font.Render(s); snprintf(s, 0xff, "Queue: %d", (int)bullets_queue.size()); glRasterPos2f(1, 1 + font.LineHeight() * (100.0 / 480.0)); font.Render(s); if(tick - lastframes >= 1000) { fps = (float)frames * ((float)(tick - lastframes) / 1000.0f); frames = 1; lastframes = tick; } else { frames++; } snprintf(s, 0xff, "FPS: %.2f", fps); glRasterPos2f(1, 1 + 2 * font.LineHeight() * (100.0 / 480.0)); font.Render(s); SDL_GL_SwapBuffers(); SDL_Delay(1); } SDL_Quit(); }