added working particle engine. needs improvement.
This commit is contained in:
parent
a5ff1bc20d
commit
61a7f6f9ba
7 changed files with 457 additions and 201 deletions
|
@ -13,12 +13,15 @@ set(GAME_SRC
|
|||
renderer.cpp
|
||||
renderer_polygon_2d/renderer_polygon_2d.cpp
|
||||
renderer_polygon_3d/renderer_polygon_3d.cpp
|
||||
renderer_polygon_3d/polygon_model.cpp
|
||||
renderer_polygon_3d/particle_batch.cpp
|
||||
renderer_ray_tracer/renderer_ray_tracer.cpp
|
||||
|
||||
network/session.cpp
|
||||
|
||||
util.cpp
|
||||
game.cpp
|
||||
|
||||
state/object.cpp
|
||||
state/explosion.cpp
|
||||
state/trace.cpp
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#define QUICK_TEST
|
||||
//#define QUICK_TEST
|
||||
|
||||
Game::Game()
|
||||
{
|
||||
|
@ -44,12 +44,12 @@ bool Game::cycle(float dt)
|
|||
acc += dt;
|
||||
total += dt;
|
||||
|
||||
float spawnInterval = 1.0;
|
||||
float spawnInterval = 0.1;
|
||||
while (acc > spawnInterval) {
|
||||
acc -= spawnInterval;
|
||||
|
||||
float angle = 360.0 * util::randf_0_1();
|
||||
float speed = 0.005;
|
||||
float speed = 0.01;
|
||||
|
||||
m_state->players.back()->addCommand(new game::SetSpeedCommand(speed));
|
||||
m_state->players.back()->addCommand(new game::ShootCommand(angle));
|
||||
|
|
181
game/renderer_polygon_3d/particle_batch.cpp
Normal file
181
game/renderer_polygon_3d/particle_batch.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include "particle_batch.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace endofthejedi {
|
||||
ParticleBatch::ParticleBatch(size_t numParticles, float particleSize)
|
||||
: m_numParticles(numParticles)
|
||||
, m_particleRadius(particleSize)
|
||||
{
|
||||
std::cout<<"[ParticleBatch] create for " << numParticles << " num particles" << std::endl;
|
||||
|
||||
size_t s = m_numParticles*4;
|
||||
|
||||
m_data_velocity.resize(s);
|
||||
m_data_position.resize(s);
|
||||
m_data_kind.resize(s);
|
||||
m_data_max_age.resize(s);
|
||||
|
||||
std::string vss_particles =
|
||||
"#version 120\n"
|
||||
"varying vec3 vertex;\n"
|
||||
"uniform float time;\n"
|
||||
"uniform float size;\n"
|
||||
"uniform vec2 velocity;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec3 p = size*gl_Vertex.xyz;\n"
|
||||
//" vec3 p = gl_Vertex.xyz;\n"
|
||||
" p.xy += velocity*time;\n"
|
||||
" gl_Position = vec4(p, 1.0);\n"
|
||||
" vertex = p;\n"
|
||||
"}\n"
|
||||
;
|
||||
|
||||
std::string fss_particles =
|
||||
"#version 120\n"
|
||||
"varying vec3 vertex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
|
||||
"}\n"
|
||||
;
|
||||
|
||||
m_shader.init();
|
||||
m_shader.load(vss_particles.c_str(), GL_VERTEX_SHADER);
|
||||
m_shader.load(fss_particles.c_str(), GL_FRAGMENT_SHADER);
|
||||
}
|
||||
|
||||
ParticleBatch::~ParticleBatch()
|
||||
{
|
||||
// TODO: find out if stuff must be deallocated
|
||||
}
|
||||
|
||||
void ParticleBatch::setParticle(size_t index, const glm::vec2 &p, const glm::vec2 &v, float kind, float maxAge)
|
||||
{
|
||||
if (index >= m_numParticles) {
|
||||
return;
|
||||
}
|
||||
|
||||
//std::cout<<"[ParticleBatch] setParticle " << index << std::endl;
|
||||
|
||||
// 4 for use as tri / quad
|
||||
const static glm::vec2 triangles[4] = {
|
||||
glm::vec2( 1.0f, -1.0f),
|
||||
glm::vec2( 1.0f, 1.0f),
|
||||
glm::vec2(-1.0f, 1.0f),
|
||||
glm::vec2(-1.0f, -1.0f),
|
||||
};
|
||||
|
||||
|
||||
for (size_t i=0; i<4; i++) {
|
||||
const size_t data_index = 4*index+i;
|
||||
|
||||
m_data_position[data_index] = p + triangles[i];
|
||||
|
||||
m_data_velocity[data_index] = v;
|
||||
m_data_kind[data_index] = kind;
|
||||
m_data_max_age[data_index] = maxAge;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleBatch::bind()
|
||||
{
|
||||
//std::cout<<"[ParticleBatch] bind" << std::endl;
|
||||
|
||||
for (size_t i=0; i<4; i++) {
|
||||
//std::cout<<"vbo #" << i << ": " << m_data_vbos[i] << std::endl;
|
||||
glEnableVertexAttribArray(i);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbos[i]);
|
||||
|
||||
// TODO: i or index? at first argument?
|
||||
glVertexAttribPointer(
|
||||
i,
|
||||
dataSizeForIndex(i),
|
||||
GL_FLOAT, // Data is floating point type
|
||||
GL_FALSE, // No fixed point scaling
|
||||
0, // stride: no
|
||||
NULL); // No offset
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleBatch::upload()
|
||||
{
|
||||
std::cout<<"[ParticleBatch] upload" << std::endl;
|
||||
|
||||
glGenBuffers(4, m_data_vbos); // Generate buffer
|
||||
|
||||
for (size_t i=0; i<4; i++) {
|
||||
glEnableVertexAttribArray(i);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbos[i]);
|
||||
|
||||
// fill buffer with the loaded mesh position data
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER, // Buffer target
|
||||
dataSizeForIndex(i) * 4 * m_numParticles * sizeof(float), // Buffer data size
|
||||
dataSourceForIndex(i), // Buffer data pointer
|
||||
GL_STATIC_DRAW); // Usage - Data never changes;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleBatch::render()
|
||||
{
|
||||
//std::cout<<"[ParticleBatch] render " << std::endl;
|
||||
|
||||
m_shader.bind();
|
||||
|
||||
static float time = 0.0f;
|
||||
time += 1.0/50.0;
|
||||
|
||||
glUniform1f(m_shader.location("time"), time);
|
||||
glUniform1f(m_shader.location("size"), m_particleRadius);
|
||||
glUniform2f(m_shader.location("velocity"), m_data_velocity[0].x, m_data_velocity[0].y);
|
||||
|
||||
bind();
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4*m_numParticles);
|
||||
|
||||
#if 0
|
||||
glBegin(GL_QUADS);
|
||||
for (size_t index=0; index<m_numParticles; index++) {
|
||||
for (int i=0; i<4; i++) {
|
||||
glm::vec2 p = m_data_position[index] + triangles[i];
|
||||
//glColor3f(1.0, 0.0, 0.0);
|
||||
glVertex2f(p.x, p.y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
size_t ParticleBatch::dataSizeForIndex(int i)
|
||||
{
|
||||
switch(i) {
|
||||
case 0:
|
||||
case 1:
|
||||
return 2;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
std::cerr << "bad" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *ParticleBatch::dataSourceForIndex(int i)
|
||||
{
|
||||
switch(i) {
|
||||
case 0: return (void *) m_data_position.data();
|
||||
case 1: return (void *) m_data_velocity.data();
|
||||
case 2: return (void *) m_data_kind.data();
|
||||
case 3: return (void *) m_data_max_age.data();
|
||||
default:
|
||||
std::cerr << "bad" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
44
game/renderer_polygon_3d/particle_batch.hpp
Normal file
44
game/renderer_polygon_3d/particle_batch.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include "glclasses.hpp"
|
||||
|
||||
namespace endofthejedi {
|
||||
class ParticleBatch {
|
||||
public:
|
||||
ParticleBatch(size_t numParticles, float particleRadius);
|
||||
|
||||
// deallocate opengl stuff on destroy
|
||||
~ParticleBatch();
|
||||
|
||||
size_t numParticles() const { return m_numParticles; }
|
||||
|
||||
void setParticle(size_t index, const glm::vec2 &p, const glm::vec2 &v, float kind, float maxAge);
|
||||
|
||||
void bind();
|
||||
void upload();
|
||||
void render();
|
||||
|
||||
Shader *shader() { return &m_shader; }
|
||||
|
||||
private:
|
||||
size_t dataSizeForIndex(int i);
|
||||
void *dataSourceForIndex(int i);
|
||||
|
||||
private:
|
||||
size_t m_numParticles;
|
||||
GLuint m_data_vbos[4];
|
||||
|
||||
std::vector<glm::vec2> m_data_position;
|
||||
std::vector<glm::vec2> m_data_velocity;
|
||||
std::vector<float> m_data_kind;
|
||||
std::vector<float> m_data_max_age;
|
||||
|
||||
float m_particleRadius;
|
||||
|
||||
Shader m_shader;
|
||||
};
|
||||
}
|
|
@ -10,7 +10,8 @@
|
|||
#include <epoxy/gl.h>
|
||||
#include <epoxy/glx.h>
|
||||
|
||||
class PolygonModel {
|
||||
namespace endofthejedi {
|
||||
class PolygonModel {
|
||||
public:
|
||||
PolygonModel(const std::string &filename) : m_filename(filename)
|
||||
{
|
||||
|
@ -225,5 +226,5 @@ class PolygonModel {
|
|||
|
||||
GLuint m_vbo_id_position;
|
||||
GLuint m_vbo_id_normal;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
|
||||
#include "polygon_model.hpp"
|
||||
|
||||
namespace endofthejedi {
|
||||
void RendererPolygon3d::setup()
|
||||
{
|
||||
|
@ -20,6 +18,21 @@ namespace endofthejedi {
|
|||
addModel("../data/mesh/planet_12.stl", &m_planetModel);
|
||||
addModel("../data/mesh/ship.stl", &m_shipModel);
|
||||
|
||||
size_t n = 10;
|
||||
|
||||
m_particles = new ParticleBatch(n, 0.01);
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
m_particles->setParticle(
|
||||
i,
|
||||
glm::vec2(i/(float) n, 0.0),
|
||||
glm::vec2(1.0, 1.0),
|
||||
0.0,
|
||||
0.0);
|
||||
}
|
||||
|
||||
m_particles->upload();
|
||||
|
||||
std::string vss_simple =
|
||||
"#version 120\n"
|
||||
"varying vec3 vertex;\n"
|
||||
|
@ -81,6 +94,8 @@ namespace endofthejedi {
|
|||
|
||||
void RendererPolygon3d::render(const game::State *state)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
m_state = state;
|
||||
|
||||
m_shader.bind();
|
||||
|
@ -91,6 +106,8 @@ namespace endofthejedi {
|
|||
renderShips();
|
||||
renderMissiles();
|
||||
|
||||
//renderParticles();
|
||||
|
||||
//glColor3f(1.0, 0.0, 0.0);
|
||||
//glBegin(GL_QUADS);
|
||||
//glVertex2f(-1.0f, -1.0f);
|
||||
|
@ -100,6 +117,12 @@ namespace endofthejedi {
|
|||
//glEnd();
|
||||
}
|
||||
|
||||
void RendererPolygon3d::renderParticles()
|
||||
{
|
||||
//m_particles->bind();
|
||||
m_particles->render();
|
||||
}
|
||||
|
||||
void RendererPolygon3d::renderPlanets()
|
||||
{
|
||||
m_planetModel->bind();
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#include "state/ship.hpp"
|
||||
#include "state/explosion.hpp"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include "particle_batch.hpp"
|
||||
#include "polygon_model.hpp"
|
||||
|
||||
class PolygonModel;
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace endofthejedi {
|
||||
|
||||
|
@ -27,6 +28,7 @@ namespace endofthejedi {
|
|||
void renderPlanets();
|
||||
void renderMissiles();
|
||||
void renderShips();
|
||||
void renderParticles();
|
||||
|
||||
void addModel(const std::string &filename, PolygonModel **dest);
|
||||
|
||||
|
@ -52,5 +54,7 @@ namespace endofthejedi {
|
|||
|
||||
// for accessing
|
||||
const game::State *m_state;
|
||||
|
||||
ParticleBatch *m_particles;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue