From a524cfdd2756ac945040ca9bed576fb2f68f8c9f Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Sun, 16 May 2010 21:44:32 +0200 Subject: Imported project. --- .gitignore | 5 + Makefile | 21 ++++ SConstruct | 22 ++++ bullet.cpp | 26 +++++ bullet.h | 20 ++++ bullet_fragment.glsl | 11 ++ bullet_vertex.glsl | 14 +++ foo.png | Bin 0 -> 1435 bytes foo2.png | Bin 0 -> 1024 bytes main.cpp | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++ shader.cpp | 91 ++++++++++++++++ shader.h | 51 +++++++++ texture.cpp | 29 ++++++ texture.h | 14 +++ texturesdl.cpp | 17 +++ texturesdl.h | 8 ++ vector.cpp | 47 +++++++++ vector.h | 36 +++++++ 18 files changed, 699 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 SConstruct create mode 100644 bullet.cpp create mode 100644 bullet.h create mode 100644 bullet_fragment.glsl create mode 100644 bullet_vertex.glsl create mode 100644 foo.png create mode 100644 foo2.png create mode 100644 main.cpp create mode 100644 shader.cpp create mode 100644 shader.h create mode 100644 texture.cpp create mode 100644 texture.h create mode 100644 texturesdl.cpp create mode 100644 texturesdl.h create mode 100644 vector.cpp create mode 100644 vector.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8015c2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.swp +*.o +.sconf_temp +.sconsign.dblite +config.log diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2e0fd63 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +CC = g++ +CFLAGS = -Wall -g $(shell sdl-config --cflags) +LDFLAGS = $(shell sdl-config --libs) -lGL -lGLU# -lGLcore +TARGET = foo +OBJECTS = shader.o main.o + +all: $(TARGET) + +$(TARGET): $(SHADERHEADERS) $(OBJECTS) + $(CC) $(LDFLAGS) -o $@ $^ + +main.o: $(SHADERHEADERS) + +%.o: %.cpp + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.cpp %.h + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(TARGET) $(OBJECTS) $(SHADERHEADERS) diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..ce1b818 --- /dev/null +++ b/SConstruct @@ -0,0 +1,22 @@ +AddOption('--release', action = 'store_true') + +env = Environment() + +conf = Configure(env) +for lib in ('GL', 'GLU', 'SDL', 'SDL_image'): + if not conf.CheckLib(lib): + print 'Could not find %s' % lib + Exit(1) +env = conf.Finish() + +if GetOption('release'): + env.Append(CCFLAGS = ['-O2']) +else: + env.Append(CCFLAGS = ['-Wall', '-g']) + +env.ParseConfig('sdl-config --cflags --libs') +env.ParseConfig('pkg-config --cflags --libs ftgl') + +env.Program('foo', Glob('*.cpp')) + +# vim: syn=python diff --git a/bullet.cpp b/bullet.cpp new file mode 100644 index 0000000..b7df9fb --- /dev/null +++ b/bullet.cpp @@ -0,0 +1,26 @@ +#include "bullet.h" + +Bullet::Bullet() { +} + +Bullet::Bullet(const Vector3& pos, const Vector3& direction, float radius) { + this->pos = pos; + this->direction = direction; + this->radius = radius; +} + +Bullet::Bullet(const Bullet& b) { + pos = b.pos; + direction = b.direction; + radius = b.radius; +} + +Bullet& Bullet::operator=(const Bullet& b) { + pos = b.pos; + direction = b.direction; + radius = b.radius; + return *this; +} + +Bullet::~Bullet() { +} diff --git a/bullet.h b/bullet.h new file mode 100644 index 0000000..23a4a3f --- /dev/null +++ b/bullet.h @@ -0,0 +1,20 @@ +#ifndef _BULLET_H_ +#define _BULLET_H_ + +#include "vector.h" + +class Bullet { + public: + Vector3 pos; + Vector3 direction; + float radius; + + Bullet(); + Bullet(const Vector3& pos, const Vector3& direction, float radius); + Bullet(const Bullet& b); + ~Bullet(); + + Bullet& operator=(const Bullet& b); +}; + +#endif diff --git a/bullet_fragment.glsl b/bullet_fragment.glsl new file mode 100644 index 0000000..3bd7717 --- /dev/null +++ b/bullet_fragment.glsl @@ -0,0 +1,11 @@ +varying mat4 v_tex_rot; +uniform sampler2D tex; + +void main() { + vec2 l_uv = gl_PointCoord; + const vec2 l_offset = vec2(0.5, 0.5); + l_uv -= l_offset; + l_uv = vec2(v_tex_rot * vec4(l_uv, 0.0, 1.0)); + l_uv += l_offset; + gl_FragColor = vec4(texture2D(tex, l_uv)) * gl_Color; +} diff --git a/bullet_vertex.glsl b/bullet_vertex.glsl new file mode 100644 index 0000000..0843be2 --- /dev/null +++ b/bullet_vertex.glsl @@ -0,0 +1,14 @@ +varying mat4 v_tex_rot; + +void main() { + vec4 l_position = gl_Vertex; + vec2 l_direction = normalize(vec2(l_position.z, l_position.w)); + v_tex_rot = mat4(l_direction.x, l_direction.y, 0.0, 0.0, + -l_direction.y, l_direction.x, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + l_position.z = 0.0; + l_position.w = 1.0; + gl_FrontColor = gl_Color; + gl_Position = gl_ModelViewProjectionMatrix * l_position; +} diff --git a/foo.png b/foo.png new file mode 100644 index 0000000..c87d1f1 Binary files /dev/null and b/foo.png differ diff --git a/foo2.png b/foo2.png new file mode 100644 index 0000000..7673659 Binary files /dev/null and b/foo2.png differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..51ef1c2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,287 @@ +#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(); +} diff --git a/shader.cpp b/shader.cpp new file mode 100644 index 0000000..04aa031 --- /dev/null +++ b/shader.cpp @@ -0,0 +1,91 @@ +#include +#include "shader.h" + +bool GLBaseShader::shader_source(const char *filename) { + std::ifstream inf(filename, std::ios_base::in); + if(!inf.is_open()) { + std::cerr << "Failed to load shader " << filename << std::endl; + return false; + } + inf.seekg(0, std::ios_base::end); + int length = inf.tellg(); + inf.seekg(0, std::ios_base::beg); + char *buffer = new char[length]; + inf.read(buffer, length); + inf.close(); + + glShaderSource(shader, 1, (const GLchar**)&buffer, &length); + print_check_ogl_error(); + delete[] buffer; + glCompileShader(shader); + print_check_ogl_error(); + int p; + glGetShaderiv(shader, GL_COMPILE_STATUS, &p); + if(p == 0) { + std::cerr << "Failed to compile shader:" << std::endl; + char log[0xffff]; + int size; + glGetShaderInfoLog(shader, 0xffff, &size, (GLchar*)&log); + std::cerr << log << std::endl; + } + return shader; +} + +bool GLBaseShader::shader_source(std::string& filename) { + return shader_source(filename.c_str()); +} + +GLBaseShader::GLBaseShader(GLenum type) { + shader = glCreateShader(type); +} + +GLShaderProgram::GLShaderProgram() { + program = glCreateProgram(); +} + +bool GLShaderProgram::attach(GLBaseShader& shader) { + glAttachShader(program, shader.shader); + return !print_check_ogl_error(); +} + +bool GLShaderProgram::detach(GLBaseShader& shader) { + glDetachShader(program, shader.shader); + return !print_check_ogl_error(); +} + +bool GLShaderProgram::link() { + glLinkProgram(program); + bool error = print_check_ogl_error(); + int p; + glGetProgramiv(program, GL_LINK_STATUS, &p); + if(p == 0) { + std::cerr << "Failed to link program:" << std::endl; + char log[0xffff]; + int size; + glGetProgramInfoLog(program, 0xffff, &size, (GLchar*)&log); + printf(log); + } + return !error && p; +} + +bool GLShaderProgram::use() { + if(!glIsProgram(program)) program = glCreateProgram(); + glUseProgram(program); + return !print_check_ogl_error(); +} + +void GLShaderProgram::remove() { + glDeleteProgram(program); +} + +void print_ogl_error(GLenum error) { + unsigned char *buf = (unsigned char*)gluErrorString(error); + std::cerr << "OpenGL: " << buf << std::endl; +} + +bool print_check_ogl_error() { + GLenum error = glGetError(); + if(error != GL_NO_ERROR) + print_ogl_error(error); + return error != GL_NO_ERROR; +} diff --git a/shader.h b/shader.h new file mode 100644 index 0000000..d2ec9d4 --- /dev/null +++ b/shader.h @@ -0,0 +1,51 @@ +#ifndef _SHADER_H_ +#define _SHADER_H_ + +#include +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +class GLBaseShader { + friend class GLShaderProgram; + + protected: + bool shader_source(const char *filename); + bool shader_source(std::string& filename); + unsigned int shader; + public: + GLBaseShader(GLenum); +}; + +class GLVertexShader : public GLBaseShader { + public: + GLVertexShader() : GLBaseShader(GL_VERTEX_SHADER) {}; + GLVertexShader(const char *s) : GLBaseShader(GL_VERTEX_SHADER) { shader_source(s); }; + GLVertexShader(std::string& s) : GLBaseShader(GL_VERTEX_SHADER) { shader_source(s); }; +}; + +class GLFragmentShader : public GLBaseShader { + public: + GLFragmentShader() : GLBaseShader(GL_FRAGMENT_SHADER) {}; + GLFragmentShader(const char *s) : GLBaseShader(GL_FRAGMENT_SHADER) { shader_source(s); }; + GLFragmentShader(std::string& s) : GLBaseShader(GL_FRAGMENT_SHADER) { shader_source(s); }; +}; + +class GLShaderProgram { + protected: + unsigned int program; + public: + GLShaderProgram(); + + bool attach(GLBaseShader&); + bool detach(GLBaseShader&); + bool link(); + bool use(); + void remove(); +}; + +void print_ogl_error(GLenum); +bool print_check_ogl_error(); + +#endif diff --git a/texture.cpp b/texture.cpp new file mode 100644 index 0000000..ca9d8e7 --- /dev/null +++ b/texture.cpp @@ -0,0 +1,29 @@ +#ifndef __APPLE__ +#include +#include +#else +#include +#include +#endif +#include +#include "texture.h" +#include + +unsigned int Texture::tex() { + return texture; +} + +void Texture::build() { + if(!data) { + throw(std::runtime_error("No texture data")); + } + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + if(byte_per_pixel == 4) { + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + } else if(byte_per_pixel == 3) { + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); + } +} diff --git a/texture.h b/texture.h new file mode 100644 index 0000000..14e500f --- /dev/null +++ b/texture.h @@ -0,0 +1,14 @@ +#ifndef _TEXTURE_H_ +#define _TEXTURE_H_ +class Texture { + public: + unsigned int tex(); + protected: + void build(); + unsigned char* data; + unsigned int width; + unsigned int height; + unsigned int byte_per_pixel; + unsigned int texture; +}; +#endif // _TEXTURE_H_ diff --git a/texturesdl.cpp b/texturesdl.cpp new file mode 100644 index 0000000..8e112ef --- /dev/null +++ b/texturesdl.cpp @@ -0,0 +1,17 @@ +#include +#include +#include +#include "texturesdl.h" + +TextureSDL::TextureSDL(const char* filename) { + SDL_Surface* image = IMG_Load(filename); + + width = image->w; + height = image->h; + byte_per_pixel = image->format->BytesPerPixel; + data = (unsigned char*)image->pixels; + + build(); + + SDL_FreeSurface(image); +} diff --git a/texturesdl.h b/texturesdl.h new file mode 100644 index 0000000..6b2eff2 --- /dev/null +++ b/texturesdl.h @@ -0,0 +1,8 @@ +#ifndef _TEXTURESDL_H_ +#define _TEXTURESDL_H_ +#include "texture.h" +class TextureSDL : public Texture { + public: + TextureSDL(const char* filename); +}; +#endif // _TEXTURESDL_H_ diff --git a/vector.cpp b/vector.cpp new file mode 100644 index 0000000..f2ce8d7 --- /dev/null +++ b/vector.cpp @@ -0,0 +1,47 @@ +#include "vector.h" + +Vector3::Vector3() { + x = y = z = 0; +} + +Vector3::Vector3(float p1, float p2, float p3) { + x = p1; + y = p2; + z = p3; +} + +Vector3::Vector3(const Vector3& v) { + x = v.r; + y = v.y; + z = v.z; +} + +Vector3& Vector3::operator=(const Vector3& v) { + x = v.r; + y = v.y; + z = v.z; + return *this; +} + +Vector4::Vector4() : Vector3() { + w = 0; +} + +Vector4::Vector4(float p1, float p2, float p3, float p4) : Vector3(p1, p2, p3) { + w = p4; +} + +Vector4::Vector4(const Vector4& v) { + x = v.r; + y = v.y; + z = v.z; + w = v.w; +} + +Vector4& Vector4::operator=(const Vector4& v) { + x = v.r; + y = v.y; + z = v.z; + w = v.w; + return *this; +} diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..3c590c3 --- /dev/null +++ b/vector.h @@ -0,0 +1,36 @@ +#ifndef _VECTOR_H_ +#define _VECTOR_H_ + +class Vector3 { + public: + union { + float x, r; + }; + union { + float y, g; + }; + union { + float z, b; + }; + + Vector3(); + Vector3(float p1, float p2, float p3); + Vector3(const Vector3& v); + + Vector3& operator=(const Vector3& v); +}; + +class Vector4 : public Vector3 { + public: + union { + float w, a; + }; + + Vector4(); + Vector4(float p1, float p2, float p3, float p4); + Vector4(const Vector4& v); + + Vector4& operator=(const Vector4& v); +}; + +#endif -- cgit v1.2.3