summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--particle.cpp51
-rw-r--r--particle.h66
-rw-r--r--scene.cpp83
-rw-r--r--scene.h5
-rw-r--r--shaders/selection_fragment.glsl10
-rw-r--r--shaders/selection_vertex.glsl15
-rw-r--r--textures/circle.pngbin0 -> 2106 bytes
-rw-r--r--vector.h2
8 files changed, 229 insertions, 3 deletions
diff --git a/particle.cpp b/particle.cpp
new file mode 100644
index 0000000..9e0b130
--- /dev/null
+++ b/particle.cpp
@@ -0,0 +1,51 @@
+#include "particle.h"
+
+#include <cmath>
+
+float SelectionParticle::t = 0;
+
+SelectionParticle::SelectionParticle() {
+ init(t += .1);
+}
+
+SelectionParticle::SelectionParticle(const SelectionParticle& p) {
+ pos = p.pos;
+ vel = p.vel;
+ alpha = p.alpha;
+ decay = p.decay;
+}
+
+void SelectionParticle::init(float seed) {
+ pt = seed;
+ speed = .0005 + fmodf(seed, .001);
+ speed = .001 + fmodf(seed, .002);
+ alpha = 1.0;
+ decay = 0.001 * ((rand() % 5 + 5) / 20.0);
+ pos = Vector3(cosf(rand()), 0, sinf(rand()));
+ //pos = Vector3(cosf(seed), 0, sinf(seed));
+ //p.pos = src;
+ //p.pos.x *= ((rand() % 20 + 10) /
+ vel = Vector3(cosf(rand()), 10, sinf(rand()));
+ vel /= vel.length();// * ((rand() % 10 + 5) / 10);
+}
+
+void SelectionParticle::update(unsigned int steps, vec4f *v) {
+ pt += speed * steps;
+ alpha -= decay * steps;
+ if(alpha <= 0) {
+ init(t += 0.1);
+ return;
+ } else {
+ pos += vel * (steps / 1000.0);
+ pos.y += vel.y * (steps / 1000.0);
+ //it->vel += Vector3(0, -.1, 0) * (steps / 1000.0);
+ }
+ //update(steps);
+ //vec4f *v = &vertices[i];
+ //v->x = pos.x * cosf(t * (i+1) / 800);
+ v->x = pos.x * cosf(pt);
+ v->y = pos.y;
+ //v->z = pos.z * sinf(t * (i+1) / 800);
+ v->z = pos.z * sinf(pt);
+ v->w = alpha;
+}
diff --git a/particle.h b/particle.h
new file mode 100644
index 0000000..433b557
--- /dev/null
+++ b/particle.h
@@ -0,0 +1,66 @@
+#ifndef PARTICLE_H
+#define PARTICLE_H
+
+#include "vector.h"
+
+#include <list>
+
+struct vec4f {
+ float x, y, z, w;
+};
+
+class SelectionParticle {
+ public:
+ Vector3 pos;
+ float alpha;
+ float decay;
+ static float t;
+ float pt;
+ float speed;
+ Vector3 vel;
+
+ SelectionParticle();
+ SelectionParticle(const SelectionParticle& p);
+
+ void init(float seed);
+ void update(unsigned int steps, vec4f *v);
+};
+
+template<class T>
+class ParticleGroup {
+ public:
+ T *particles;
+ vec4f *vertices;
+ unsigned int num;
+ unsigned int count;
+ Vector3 src;
+ Vector3 dir;
+
+ ParticleGroup(Vector3 src, Vector3 dir, unsigned int count) {
+ srand(time(NULL));
+ this->src = src;
+ this->dir = dir;
+ this->num = count;
+ this->count = 0;
+ T::t = 0;
+ particles = new T[count];
+ vertices = new vec4f[count];
+ };
+ ~ParticleGroup() {
+ delete[] particles;
+ delete[] vertices;
+ }
+
+ void update(unsigned int steps) {
+ if(count < num) {
+ particles[count].init(T::t += 0.1);
+ count++;
+ }
+ for(unsigned int i = 0; i < count; i++) {
+ T *p = &particles[i];
+ p->update(steps, &vertices[i]);
+ }
+ }
+};
+
+#endif
diff --git a/scene.cpp b/scene.cpp
index f994627..0c31bc8 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -39,11 +39,20 @@ Scene::Scene() {
glUniform1i(markloc, 3);
glUseProgram(0);
+ GLFragmentShader selection_fragment("shaders/selection_fragment.glsl");
+ GLVertexShader selection_vertex("shaders/selection_vertex.glsl");
+ selection_program.attach(selection_fragment);
+ selection_program.attach(selection_vertex);
+ selection_program.link();
+
+ selection_particles = NULL;
+
/* load textures */
grass_texture = load_texture("textures/zooboing-366-grass.jpg");
rock_texture = load_texture("textures/zooboing-825-stone-modified.jpg");
soil_texture = load_texture("textures/zooboing-469-sand-modified.jpg");
marker_texture = load_texture("textures/cross.png");
+ circle_texture = load_texture("textures/circle.png");
/* load heightmap */
SDL_Surface *hm = IMG_Load("heightmap.png");
@@ -200,8 +209,11 @@ void Scene::events() {
case SDL_BUTTON_RIGHT:
if(dialog)
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
- else
+ else {
show_selection = false;
+ delete selection_particles;
+ selection_particles = NULL;
+ }
break;
case SDL_BUTTON_WHEELUP:
if(dialog)
@@ -397,6 +409,71 @@ void Scene::render() {
do_select = false;
selected = Vector3(px, py, pz);
show_selection = true;
+ if(selection_particles)
+ delete selection_particles;
+ selection_particles = new ParticleGroup<SelectionParticle>(selected, Vector3(0, 1, 0), 1000);
+ }
+
+ float pdist;
+ if(selection_particles && (pdist = (selected.xz() - pos.xz()).length()) < 100) {
+ Quadtree::QuadNode *node = qt->find(selected.x, selected.z);
+ selected.y = node->get_height(selected.x, selected.z);
+ selection_particles->src = selected;
+ glPushMatrix();
+ glTranslatef(selection_particles->src.x, selection_particles->src.y, selection_particles->src.z);
+ GLdouble m[16];
+ glGetDoublev(GL_MODELVIEW_MATRIX, m);
+ Vector3 up(m[0], m[4], m[8]);
+ Vector3 right(m[1], m[5], m[9]);
+ GLdouble temp[3] = {m[3], m[7], m[11]};
+ m[3] = m[12];
+ m[7] = m[13];
+ m[11] = m[14];
+ m[12] = temp[0];
+ m[13] = temp[1];
+ m[14] = temp[2];
+ m[0] = 1; m[4] = 0; m[8] = 0;
+ m[1] = 0; m[5] = 1; m[9] = 0;
+ m[2] = 0; m[6] = 0; m[10] = 1;
+ //glLoadMatrixd(m);
+ //glRotatef(yaw*180/M_PI, 0, 1, 0);
+ //glTranslatef(selection_particles->src.x, selection_particles->src.y, selection_particles->src.z);
+ //glRotatef(-yaw*180/M_PI, 0, 1, 0);
+ //glRotatef(-yaw*180/M_PI+90, 0, 1, 0);
+
+ glDepthMask(GL_FALSE);
+ selection_particles->update(steps);
+ selection_program.use();
+ GLint dist = glGetUniformLocation(selection_program.get_program(), "dist");
+ glUniform1f(dist, pdist);
+ glPointSize(100);
+ const GLfloat att[3] = {1, .01, 0};
+ glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, att);
+ glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+ glEnable(GL_POINT_SPRITE);
+ glEnable(GL_BLEND);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ //glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, circle_texture);
+ glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
+ glVertexPointer(4, GL_FLOAT, 0, selection_particles->vertices);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glDrawArrays(GL_POINTS, 0, selection_particles->count);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ //glBegin(GL_QUADS);
+ /*glBegin(GL_POINTS);
+ for(std::list<Particle>::iterator it = selection_particles->particles.begin(); it != selection_particles->particles.end(); it++) {
+ glColor4f(1, 1, 1, it->alpha);
+ glVertex3f(it->pos.x, it->pos.y, it->pos.z);
+ }
+ glEnd();*/
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glUseProgram(0);
+ glDepthMask(GL_TRUE);
+ glPopMatrix();
}
video::ortho();
@@ -413,6 +490,10 @@ void Scene::render() {
font->Render(move_str.c_str());
glTranslatef(0, -height, 0);
font->Render(selected.str().c_str());
+ if(selection_particles) {
+ glTranslatef(0, -height, 0);
+ font->Render((boost::format("particles: %d") % selection_particles->count).str().c_str());
+ }
/*if(selected) {
glTranslatef(0, height, 0);
//font->Render((boost::format("(%s %s %s %s)") % selected->a->str() % selected->b->str() % selected->c->str() % selected->d->str()).str().c_str());
diff --git a/scene.h b/scene.h
index 95ae158..f040ca8 100644
--- a/scene.h
+++ b/scene.h
@@ -6,6 +6,7 @@
#include "gl.h"
#include "shader.h"
#include "gui.h"
+#include "particle.h"
#include <FTGL/ftgl.h>
@@ -33,8 +34,12 @@ class Scene {
int sx, sy;
GLShaderProgram terrain_program;
+ GLShaderProgram selection_program;
+
+ ParticleGroup<SelectionParticle> *selection_particles;
GLuint grass_texture, rock_texture, soil_texture, marker_texture;
+ GLuint circle_texture;
Scene();
~Scene();
diff --git a/shaders/selection_fragment.glsl b/shaders/selection_fragment.glsl
new file mode 100644
index 0000000..33b6cf1
--- /dev/null
+++ b/shaders/selection_fragment.glsl
@@ -0,0 +1,10 @@
+#version 120
+
+uniform sampler2D tex;
+uniform float dist;
+
+void main() {
+ vec4 tc = texture2D(tex, gl_TexCoord[0].st);
+ gl_FragColor = tc * gl_Color * .3;
+}
+/* vim: set syn=glsl: */
diff --git a/shaders/selection_vertex.glsl b/shaders/selection_vertex.glsl
new file mode 100644
index 0000000..b5f0aa7
--- /dev/null
+++ b/shaders/selection_vertex.glsl
@@ -0,0 +1,15 @@
+#version 120
+
+uniform float dist;
+
+void main() {
+ gl_PointSize = min(200/dist * log(gl_Vertex.w+2), 200);
+ gl_FrontColor = vec4(1, gl_Vertex.w/2, 0, 1);
+
+ gl_PointSize = 100/dist * min(gl_Vertex.w+.5, 1);
+ gl_FrontColor = vec4(1, 1-log(gl_Vertex.w+1.0), 0, 1);
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1);
+}
+/* vim: set syn=glsl: */
diff --git a/textures/circle.png b/textures/circle.png
new file mode 100644
index 0000000..0baf0b2
--- /dev/null
+++ b/textures/circle.png
Binary files differ
diff --git a/vector.h b/vector.h
index 48deb87..3ca5d1f 100644
--- a/vector.h
+++ b/vector.h
@@ -1,8 +1,6 @@
#ifndef VECTOR_H
#define VECTOR_H
-#include <boost/shared_ptr.hpp>
-
#include <string>
class Vector2 {