GPUParticles: Implement HeightMapAffector equivalent.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14961 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
0be4825ef2
commit
5b8ca4fcd7
@ -1,6 +1,12 @@
|
||||
#version 130
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform float track_x;
|
||||
uniform float track_z;
|
||||
uniform float track_x_len;
|
||||
uniform float track_z_len;
|
||||
uniform samplerBuffer heightmap;
|
||||
uniform bool hasHeightMap;
|
||||
|
||||
in vec2 quadcorner;
|
||||
in vec2 texcoord;
|
||||
@ -15,7 +21,19 @@ void main(void)
|
||||
{
|
||||
tc = texcoord;
|
||||
lf = lifetime;
|
||||
vec4 viewpos = ViewMatrix * vec4(position, 1.0);
|
||||
vec3 newposition = position;
|
||||
|
||||
float i_as_float = clamp(256. * (position.x - track_x) / track_x_len, 0., 255.);
|
||||
float j_as_float = clamp(256. * (position.z - track_z) / track_z_len, 0., 255.);
|
||||
int i = int(i_as_float);
|
||||
int j = int(j_as_float);
|
||||
|
||||
if (hasHeightMap) {
|
||||
float h = position.y - texelFetch(heightmap, i * 256 + j).r;
|
||||
newposition.y = (h > 0.)? position.y : position.y - h;
|
||||
}
|
||||
|
||||
vec4 viewpos = ViewMatrix * vec4(newposition, 1.0);
|
||||
viewpos += size * vec4(quadcorner, 0., 0.);
|
||||
gl_Position = ProjectionMatrix * viewpos;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
PFNGLTEXBUFFERPROC glTexBuffer;
|
||||
#endif
|
||||
|
||||
static GLuint quad_buffer;
|
||||
@ -167,6 +168,7 @@ void initGL()
|
||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
|
||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
|
||||
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteVertexArrays");
|
||||
glTexBuffer = (PFNGLTEXBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glTexBuffer");
|
||||
#endif
|
||||
#if ENABLE_ARB_DEBUG_OUTPUT
|
||||
glDebugMessageCallbackARB(debugCallback, NULL);
|
||||
|
@ -70,6 +70,7 @@ extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLTEXBUFFERPROC glTexBuffer;
|
||||
#endif
|
||||
|
||||
// core::rect<s32> needs these includes
|
||||
|
@ -94,12 +94,40 @@ ParticleSystemProxy::~ParticleSystemProxy()
|
||||
{
|
||||
glDeleteBuffers(2, tfb_buffers);
|
||||
glDeleteBuffers(1, &initial_values_buffer);
|
||||
if (has_height_map)
|
||||
glDeleteBuffers(1, &heighmapbuffer);
|
||||
}
|
||||
|
||||
void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; }
|
||||
|
||||
void ParticleSystemProxy::setIncreaseFactor(float val) { size_increase_factor = val; }
|
||||
|
||||
void ParticleSystemProxy::setHeightmap(const std::vector<std::vector<float> > &hm,
|
||||
float f1, float f2, float f3, float f4) {
|
||||
track_x = f1, track_z = f2, track_x_len = f3, track_z_len = f4;
|
||||
printf("track_x is %f, track_x_len is %f, track_z is %f, track_z_len is %f\n",
|
||||
track_x, track_x_len, track_z, track_z_len);
|
||||
unsigned width = hm.size();
|
||||
unsigned height = hm[0].size();
|
||||
float *hm_array = new float[width * height];
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
hm_array[i * height + j] = hm[i][j];
|
||||
}
|
||||
}
|
||||
has_height_map = true;
|
||||
glGenBuffers(1, &heighmapbuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, heighmapbuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, width * height * sizeof(float), hm_array, GL_STATIC_DRAW);
|
||||
glGenTextures(1, &heightmaptexture);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, heighmapbuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
delete[] hm_array;
|
||||
}
|
||||
|
||||
static
|
||||
void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &lifetime, float &size, float &dirX, float &dirY, float &dirZ)
|
||||
{
|
||||
@ -243,6 +271,12 @@ GLuint ParticleSystemProxy::uniform_sourcematrix;
|
||||
GLuint ParticleSystemProxy::uniform_dt;
|
||||
GLuint ParticleSystemProxy::uniform_level;
|
||||
GLuint ParticleSystemProxy::uniform_size_increase_factor;
|
||||
GLuint ParticleSystemProxy::uniform_has_heightmap;
|
||||
GLuint ParticleSystemProxy::uniform_heightmap;
|
||||
GLuint ParticleSystemProxy::uniform_track_x;
|
||||
GLuint ParticleSystemProxy::uniform_track_x_len;
|
||||
GLuint ParticleSystemProxy::uniform_track_z;
|
||||
GLuint ParticleSystemProxy::uniform_track_z_len;
|
||||
|
||||
|
||||
GLuint ParticleSystemProxy::attrib_pos;
|
||||
@ -275,6 +309,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
|
||||
CParticleSystemSceneNode::setEmitter(emitter);
|
||||
if (!emitter || !isGPUParticleType(emitter->getType()))
|
||||
return;
|
||||
has_height_map = false;
|
||||
// Pass a fake material type to force irrlicht to update its internal states on rendering
|
||||
setMaterialType(irr_driver->getShader(ES_RAIN));
|
||||
setAutomaticCulling(0);
|
||||
@ -339,6 +374,12 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
|
||||
uniform_invproj = glGetUniformLocation(RenderProgram, "invproj");
|
||||
uniform_screen = glGetUniformLocation(RenderProgram, "screen");
|
||||
uniform_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth");
|
||||
uniform_has_heightmap = glGetUniformLocation(RenderProgram, "hasHeightMap");
|
||||
uniform_heightmap = glGetUniformLocation(RenderProgram, "heightmap");
|
||||
uniform_track_x = glGetUniformLocation(RenderProgram, "track_x");
|
||||
uniform_track_x_len = glGetUniformLocation(RenderProgram, "track_x_len");
|
||||
uniform_track_z = glGetUniformLocation(RenderProgram, "track_z");
|
||||
uniform_track_z_len = glGetUniformLocation(RenderProgram, "track_z_len");
|
||||
}
|
||||
|
||||
void ParticleSystemProxy::simulate()
|
||||
@ -380,6 +421,7 @@ void ParticleSystemProxy::simulate()
|
||||
glUniform1i(uniform_level, active_count);
|
||||
glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer());
|
||||
glUniform1f(uniform_size_increase_factor, size_increase_factor);
|
||||
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glEndTransformFeedback();
|
||||
@ -426,6 +468,18 @@ void ParticleSystemProxy::draw()
|
||||
glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer());
|
||||
glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());
|
||||
|
||||
glUniform1i(uniform_has_heightmap, has_height_map);
|
||||
if (has_height_map)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
|
||||
glUniform1i(uniform_heightmap, 2);
|
||||
glUniform1f(uniform_track_x, track_x);
|
||||
glUniform1f(uniform_track_z, track_z);
|
||||
glUniform1f(uniform_track_x_len, track_x_len);
|
||||
glUniform1f(uniform_track_z_len, track_z_len);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
|
||||
glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||
glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
|
||||
|
@ -27,18 +27,20 @@ public:
|
||||
class ParticleSystemProxy : public scene::CParticleSystemSceneNode {
|
||||
protected:
|
||||
video::SMaterial fakemat;
|
||||
GLuint tfb_buffers[2], initial_values_buffer;
|
||||
bool m_alpha_additive;
|
||||
float size_increase_factor;
|
||||
GLuint tfb_buffers[2], initial_values_buffer, heighmapbuffer, heightmaptexture;
|
||||
bool m_alpha_additive, has_height_map;
|
||||
float size_increase_factor, track_x, track_z, track_x_len, track_z_len;
|
||||
|
||||
static GLuint SimulationProgram;
|
||||
static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size;
|
||||
static GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor;
|
||||
static GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor, uniform_has_heightmap, uniform_heightmap;
|
||||
|
||||
static GLuint RenderProgram;
|
||||
static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz;
|
||||
static GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj;
|
||||
|
||||
static GLuint uniform_track_x, uniform_track_z, uniform_track_x_len, uniform_track_z_len;
|
||||
|
||||
static GLuint quad_vertex_buffer;
|
||||
|
||||
GLuint texture, normal_and_depth;
|
||||
@ -67,6 +69,7 @@ public:
|
||||
virtual void render();
|
||||
void setAlphaAdditive(bool);
|
||||
void setIncreaseFactor(float);
|
||||
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
||||
};
|
||||
|
||||
class PointEmitter : public GPUParticle
|
||||
|
@ -585,6 +585,17 @@ void ParticleEmitter::addHeightMapAffector(Track* t)
|
||||
HeightMapCollisionAffector* hmca = new HeightMapCollisionAffector(t);
|
||||
m_node->addAffector(hmca);
|
||||
hmca->drop();
|
||||
if (irr_driver->isGLSL()) {
|
||||
const Vec3* aabb_min;
|
||||
const Vec3* aabb_max;
|
||||
t->getAABB(&aabb_min, &aabb_max);
|
||||
float track_x = aabb_min->getX();
|
||||
float track_z = aabb_min->getZ();
|
||||
const float track_x_len = aabb_max->getX() - aabb_min->getX();
|
||||
const float track_z_len = aabb_max->getZ() - aabb_min->getZ();
|
||||
static_cast<ParticleSystemProxy *>(m_node)->setHeightmap(t->buildHeightMap(),
|
||||
track_x, track_z, track_x_len, track_z_len);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user