GPUParticles: Got PointEmitter to draw something at last.
Still WIP, uses a #ifdef to disable it but I wanted to keep a working commit somewhere in case I mess up somewhere. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14829 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
681f095140
commit
4c725ac8f4
12
data/shaders/particle.frag
Normal file
12
data/shaders/particle.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 130
|
||||
in float lifetime;
|
||||
|
||||
out vec3 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
color = vec3(
|
||||
(lifetime < 33.) ? 1. : 0.,
|
||||
(lifetime < 67. && lifetime >= 34.) ? 1. : 0.,
|
||||
(lifetime > 68.) ? 1. : 0.);
|
||||
}
|
13
data/shaders/particle.vert
Normal file
13
data/shaders/particle.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 130
|
||||
in vec3 position;
|
||||
in float lf;
|
||||
uniform mat4 matrix;
|
||||
|
||||
out float lifetime;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_PointSize = 10.;
|
||||
gl_Position = matrix * vec4(position, 1.0);
|
||||
lifetime = lf;
|
||||
}
|
20
data/shaders/pointemitter.vert
Normal file
20
data/shaders/pointemitter.vert
Normal file
@ -0,0 +1,20 @@
|
||||
#version 130
|
||||
uniform int dt;
|
||||
uniform vec3 source;
|
||||
uniform int duration;
|
||||
|
||||
in vec3 particle_position;
|
||||
in float lifetime;
|
||||
in vec4 particle_velocity;
|
||||
|
||||
out vec3 new_particle_position;
|
||||
out float new_lifetime;
|
||||
out vec4 new_particle_velocity;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : vec3(0., 0., 0.);
|
||||
new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration);
|
||||
new_particle_velocity = particle_velocity;
|
||||
gl_Position = vec4(0.);
|
||||
}
|
@ -1,218 +1,326 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "gpuparticles.h"
|
||||
#include <fstream>
|
||||
#include "io/file_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include <ICameraSceneNode.h>
|
||||
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
|
||||
|
||||
|
||||
PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
|
||||
PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
|
||||
PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
|
||||
PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
||||
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
PFNGLBUFFERDATAPROC glBufferData;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||
PFNGLCREATESHADERPROC glCreateShader;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
PFNGLATTACHSHADERPROC glAttachShader;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||
PFNGLUNIFORM1FPROC glUniform1f;
|
||||
PFNGLUNIFORM3FPROC glUniform3f;
|
||||
PFNGLDELETESHADERPROC glDeleteShader;
|
||||
PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
PFNGLUNIFORM2FPROC glUniform2f;
|
||||
PFNGLUNIFORM1IPROC glUniform1i;
|
||||
PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
#endif
|
||||
|
||||
void initGL()
|
||||
{
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks");
|
||||
glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback");
|
||||
glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback");
|
||||
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback");
|
||||
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback");
|
||||
glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase");
|
||||
glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers");
|
||||
glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer");
|
||||
glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData");
|
||||
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer");
|
||||
glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader");
|
||||
glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader");
|
||||
glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource");
|
||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram");
|
||||
glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader");
|
||||
glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram");
|
||||
glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram");
|
||||
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray");
|
||||
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");
|
||||
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv");
|
||||
glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f");
|
||||
glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f");
|
||||
glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray");
|
||||
glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader");
|
||||
glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv");
|
||||
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog");
|
||||
glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
|
||||
glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f");
|
||||
glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i");
|
||||
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv");
|
||||
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog");
|
||||
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Mostly from shader tutorial
|
||||
static
|
||||
GLuint LoadShader(const char * file, unsigned type) {
|
||||
GLuint Id = glCreateShader(type);
|
||||
std::string Code;
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
if (Stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(Stream, Line))
|
||||
Code += "\n" + Line;
|
||||
Stream.close();
|
||||
}
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
printf("Compiling shader : %s\n", file);
|
||||
char const * SourcePointer = Code.c_str();
|
||||
int length = strlen(SourcePointer);
|
||||
glShaderSource(Id, 1, &SourcePointer, &length);
|
||||
glCompileShader(Id);
|
||||
|
||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
return Id;
|
||||
}
|
||||
|
||||
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) {
|
||||
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
||||
|
||||
GLuint ProgramID = glCreateProgram();
|
||||
glAttachShader(ProgramID, VertexShaderID);
|
||||
glAttachShader(ProgramID, FragmentShaderID);
|
||||
glLinkProgram(ProgramID);
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
glDeleteShader(VertexShaderID);
|
||||
glDeleteShader(FragmentShaderID);
|
||||
|
||||
return ProgramID;
|
||||
}
|
||||
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) {
|
||||
GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||
GLuint Program = glCreateProgram();
|
||||
glAttachShader(Program, Shader);
|
||||
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
glLinkProgram(Program);
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
glDeleteShader(Shader);
|
||||
return Program;
|
||||
}
|
||||
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex) {
|
||||
return static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||
}
|
||||
|
||||
void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) {
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glUniform1i(location, textureUnit);
|
||||
}
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "gpuparticles.h"
|
||||
#include <fstream>
|
||||
#include "io/file_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include <ICameraSceneNode.h>
|
||||
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
|
||||
|
||||
|
||||
PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
|
||||
PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
|
||||
PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
|
||||
PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
||||
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
PFNGLBUFFERDATAPROC glBufferData;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||
PFNGLCREATESHADERPROC glCreateShader;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
PFNGLATTACHSHADERPROC glAttachShader;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||
PFNGLUNIFORM1FPROC glUniform1f;
|
||||
PFNGLUNIFORM3FPROC glUniform3f;
|
||||
PFNGLDELETESHADERPROC glDeleteShader;
|
||||
PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
PFNGLUNIFORM2FPROC glUniform2f;
|
||||
PFNGLUNIFORM1IPROC glUniform1i;
|
||||
PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
#endif
|
||||
|
||||
void initGL()
|
||||
{
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks");
|
||||
glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback");
|
||||
glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback");
|
||||
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback");
|
||||
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback");
|
||||
glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase");
|
||||
glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers");
|
||||
glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer");
|
||||
glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData");
|
||||
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer");
|
||||
glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader");
|
||||
glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader");
|
||||
glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource");
|
||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram");
|
||||
glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader");
|
||||
glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram");
|
||||
glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram");
|
||||
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray");
|
||||
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");
|
||||
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv");
|
||||
glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f");
|
||||
glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f");
|
||||
glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray");
|
||||
glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader");
|
||||
glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv");
|
||||
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog");
|
||||
glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
|
||||
glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f");
|
||||
glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i");
|
||||
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv");
|
||||
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog");
|
||||
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");
|
||||
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Mostly from shader tutorial
|
||||
static
|
||||
GLuint LoadShader(const char * file, unsigned type) {
|
||||
GLuint Id = glCreateShader(type);
|
||||
std::string Code;
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
if (Stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(Stream, Line))
|
||||
Code += "\n" + Line;
|
||||
Stream.close();
|
||||
}
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
printf("Compiling shader : %s\n", file);
|
||||
char const * SourcePointer = Code.c_str();
|
||||
int length = strlen(SourcePointer);
|
||||
glShaderSource(Id, 1, &SourcePointer, &length);
|
||||
glCompileShader(Id);
|
||||
|
||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
return Id;
|
||||
}
|
||||
|
||||
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) {
|
||||
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
||||
|
||||
GLuint ProgramID = glCreateProgram();
|
||||
glAttachShader(ProgramID, VertexShaderID);
|
||||
glAttachShader(ProgramID, FragmentShaderID);
|
||||
glLinkProgram(ProgramID);
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
glDeleteShader(VertexShaderID);
|
||||
glDeleteShader(FragmentShaderID);
|
||||
|
||||
return ProgramID;
|
||||
}
|
||||
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) {
|
||||
GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||
GLuint Program = glCreateProgram();
|
||||
glAttachShader(Program, Shader);
|
||||
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
glLinkProgram(Program);
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
glDeleteShader(Shader);
|
||||
return Program;
|
||||
}
|
||||
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex) {
|
||||
return static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||
}
|
||||
|
||||
void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) {
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glUniform1i(location, textureUnit);
|
||||
}
|
||||
|
||||
GPUParticle::GPUParticle(scene::ISceneManager* mgr, ITexture *tex)
|
||||
: scene::ISceneNode(0, mgr, -1) {
|
||||
initGL();
|
||||
: scene::ISceneNode(0, mgr, -1) {
|
||||
initGL();
|
||||
fakemat.Lighting = false;
|
||||
fakemat.ZWriteEnable = false;
|
||||
fakemat.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
fakemat.Thickness = 200;
|
||||
fakemat.setTexture(0, tex);
|
||||
}
|
||||
|
||||
void GPUParticle::render() {
|
||||
simulate();
|
||||
draw();
|
||||
fakemat.setTexture(0, tex);
|
||||
}
|
||||
|
||||
void GPUParticle::render() {
|
||||
simulate();
|
||||
draw();
|
||||
// We need to force irrlicht to update its internal states
|
||||
irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setMaterial(fakemat);
|
||||
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();
|
||||
}
|
||||
|
||||
void GPUParticle::OnRegisterSceneNode() {
|
||||
if (IsVisible &&
|
||||
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();
|
||||
}
|
||||
|
||||
void GPUParticle::OnRegisterSceneNode() {
|
||||
if (
|
||||
(irr_driver->getRenderPass() & irr::scene::ESNRP_TRANSPARENT) == irr::scene::ESNRP_TRANSPARENT)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT);
|
||||
}
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
#define COMPONENTCOUNT 8
|
||||
|
||||
PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex,
|
||||
const core::vector3df& direction,
|
||||
u32 minParticlesPerSecond,
|
||||
u32 maxParticlesPerSecond,
|
||||
const video::SColor& minStartColor,
|
||||
const video::SColor& maxStartColor,
|
||||
u32 lifeTimeMin, u32 lifeTimeMax,
|
||||
s32 maxAngleDegrees
|
||||
// const core::dimension2df& minStartSize,
|
||||
// const core::dimension2df& maxStartSize
|
||||
) : GPUParticle(mgr, tex) {
|
||||
const char *varyings[] = {
|
||||
"new_particle_position",
|
||||
"new_lifetime",
|
||||
"new_particle_velocity",
|
||||
//"gl_SkipComponents3"
|
||||
};
|
||||
|
||||
SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3);
|
||||
loc_duration = glGetUniformLocation(SimulationProgram, "duration");
|
||||
loc_dt = glGetUniformLocation(SimulationProgram, "dt");
|
||||
loc_source = glGetUniformLocation(SimulationProgram, "source");
|
||||
loc_position = glGetAttribLocation(SimulationProgram, "particle_position");
|
||||
loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime");
|
||||
loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity");
|
||||
printf("locs are %d, %d, %d\n", loc_position, loc_lifetime, loc_velocity);
|
||||
|
||||
RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str());
|
||||
loc_matrix = glGetUniformLocation(RenderProgram, "matrix");
|
||||
count = 25;
|
||||
|
||||
float *particles = new float[COMPONENTCOUNT * count];
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
particles[COMPONENTCOUNT * i] = 0.;// getPosition().X;
|
||||
particles[COMPONENTCOUNT * i + 1] = 0.;// getPosition().Y;
|
||||
particles[COMPONENTCOUNT * i + 2] = 0.;//getPosition().Z;
|
||||
particles[COMPONENTCOUNT * i + 3] = i * 10;
|
||||
|
||||
particles[COMPONENTCOUNT * i + 4] = direction.X;
|
||||
particles[COMPONENTCOUNT * i + 5] = direction.Y;
|
||||
particles[COMPONENTCOUNT * i + 6] = direction.Z;
|
||||
|
||||
// particles[COMPONENTCOUNT * i + 8] = 100.;
|
||||
//memcpy(&particles[COMPONENTCOUNT * i + 3], &i, sizeof(float));
|
||||
}
|
||||
printf("dir is %f, %f, %f\n", direction.X, direction.Y, direction.Z);
|
||||
glGenBuffers(2, tfb_buffers);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW);
|
||||
delete [] particles;
|
||||
}
|
||||
|
||||
void PointEmitter::simulate()
|
||||
{
|
||||
glUseProgram(SimulationProgram);
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
|
||||
glVertexAttribPointer(loc_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0);
|
||||
glVertexAttribPointer(loc_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float)));
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]);
|
||||
|
||||
glUniform1i(loc_dt, 1);
|
||||
glUniform1i(loc_duration, 100);
|
||||
glUniform3f(loc_source, getPosition().X, getPosition().Y, getPosition().Z);
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glEndTransformFeedback();
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glDisable(GL_RASTERIZER_DISCARD);
|
||||
std::swap(tfb_buffers[0], tfb_buffers[1]);
|
||||
}
|
||||
|
||||
void PointEmitter::draw()
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
||||
matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
matrix *= getAbsoluteTransformation();;
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
glUseProgram(RenderProgram);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
|
||||
glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer());
|
||||
glVertexAttribPointer(glGetAttribLocation(RenderProgram, "position"), 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0);
|
||||
glVertexAttribPointer(glGetAttribLocation(RenderProgram, "lf"), 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *)(3 * sizeof(float)));
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex)
|
||||
: GPUParticle(mgr, tex)
|
||||
{
|
||||
RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str());
|
||||
loc_screenw = glGetUniformLocation(RenderProgram, "screenw");
|
||||
loc_screen = glGetUniformLocation(RenderProgram, "screen");
|
||||
loc_invproj = glGetUniformLocation(RenderProgram, "invproj");
|
||||
texloc_tex = glGetUniformLocation(RenderProgram, "tex");
|
||||
texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth");
|
||||
|
||||
const char *varyings[] = { "currentPosition" };
|
||||
SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1);
|
||||
loc_campos = glGetUniformLocation(SimulationProgram, "campos");
|
||||
loc_viewm = glGetUniformLocation(SimulationProgram, "viewm");
|
||||
RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str());
|
||||
loc_screenw = glGetUniformLocation(RenderProgram, "screenw");
|
||||
loc_screen = glGetUniformLocation(RenderProgram, "screen");
|
||||
loc_invproj = glGetUniformLocation(RenderProgram, "invproj");
|
||||
texloc_tex = glGetUniformLocation(RenderProgram, "tex");
|
||||
texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth");
|
||||
|
||||
const char *varyings[] = { "currentPosition" };
|
||||
SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1);
|
||||
loc_campos = glGetUniformLocation(SimulationProgram, "campos");
|
||||
loc_viewm = glGetUniformLocation(SimulationProgram, "viewm");
|
||||
loc_time = glGetUniformLocation(SimulationProgram, "time");
|
||||
count = 2500;
|
||||
area = 3500;
|
||||
@ -232,68 +340,68 @@ RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex)
|
||||
|
||||
texture = getTextureGLuint(tex);
|
||||
normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
|
||||
glGenBuffers(2, tfb_vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), vertices, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]);
|
||||
glGenBuffers(2, tfb_vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), vertices, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW);
|
||||
|
||||
box.addInternalPoint(vector3df((float)(-area / 2)));
|
||||
box.addInternalPoint(vector3df((float)(area / 2)));
|
||||
}
|
||||
|
||||
void RainNode::simulate() {
|
||||
glUseProgram(SimulationProgram);
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f;
|
||||
const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW);
|
||||
const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition();
|
||||
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]);
|
||||
|
||||
glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer());
|
||||
glUniform1f(loc_time, time);
|
||||
glUniform3f(loc_campos, campos.X, campos.Y, campos.Z);
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glEndTransformFeedback();
|
||||
glDisable(GL_RASTERIZER_DISCARD);
|
||||
}
|
||||
|
||||
void RainNode::draw() {
|
||||
const float screenw = (float)UserConfigParams::m_width;
|
||||
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
glUseProgram(RenderProgram);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
float screen[2] = {
|
||||
(float)UserConfigParams::m_width,
|
||||
(float)UserConfigParams::m_height
|
||||
};
|
||||
irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION);
|
||||
invproj.makeInverse();
|
||||
|
||||
bindUniformToTextureUnit(texloc_tex, texture, 0);
|
||||
bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1);
|
||||
|
||||
glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer());
|
||||
glUniform2f(loc_screen, screen[0], screen[1]);
|
||||
glUniform1f(loc_screenw, screenw);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glDisableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
void RainNode::simulate() {
|
||||
glUseProgram(SimulationProgram);
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f;
|
||||
const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW);
|
||||
const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition();
|
||||
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]);
|
||||
|
||||
glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer());
|
||||
glUniform1f(loc_time, time);
|
||||
glUniform3f(loc_campos, campos.X, campos.Y, campos.Z);
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glEndTransformFeedback();
|
||||
glDisable(GL_RASTERIZER_DISCARD);
|
||||
}
|
||||
|
||||
void RainNode::draw() {
|
||||
const float screenw = (float)UserConfigParams::m_width;
|
||||
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
glUseProgram(RenderProgram);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
float screen[2] = {
|
||||
(float)UserConfigParams::m_width,
|
||||
(float)UserConfigParams::m_height
|
||||
};
|
||||
irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION);
|
||||
invproj.makeInverse();
|
||||
|
||||
bindUniformToTextureUnit(texloc_tex, texture, 0);
|
||||
bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1);
|
||||
|
||||
glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer());
|
||||
glUniform2f(loc_screen, screen[0], screen[1]);
|
||||
glUniform1f(loc_screenw, screenw);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glDisableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
const core::aabbox3d<f32>& RainNode::getBoundingBox() const
|
||||
{
|
||||
return box;
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,77 @@
|
||||
#ifndef GPUPARTICLES_H
|
||||
#define GPUPARTICLES_H
|
||||
|
||||
#ifndef _IRR_WINDOWS_API_
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#endif
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include <ISceneManager.h>
|
||||
|
||||
void initGL();
|
||||
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path);
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex);
|
||||
void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit);
|
||||
|
||||
|
||||
class GPUParticle : public scene::ISceneNode {
|
||||
protected:
|
||||
video::SMaterial fakemat;
|
||||
virtual void simulate() = 0;
|
||||
virtual void draw() = 0;
|
||||
public:
|
||||
//GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt);
|
||||
#ifndef GPUPARTICLES_H
|
||||
#define GPUPARTICLES_H
|
||||
|
||||
#ifndef _IRR_WINDOWS_API_
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#endif
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include <ISceneManager.h>
|
||||
|
||||
void initGL();
|
||||
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path);
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex);
|
||||
void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit);
|
||||
|
||||
|
||||
class GPUParticle : public scene::ISceneNode {
|
||||
protected:
|
||||
video::SMaterial fakemat;
|
||||
virtual void simulate() = 0;
|
||||
virtual void draw() = 0;
|
||||
public:
|
||||
GPUParticle(scene::ISceneManager* mgr, ITexture *tex);
|
||||
virtual void render();
|
||||
virtual void OnRegisterSceneNode();
|
||||
};
|
||||
virtual void render();
|
||||
virtual void OnRegisterSceneNode();
|
||||
};
|
||||
|
||||
class PointEmitter : public GPUParticle
|
||||
{
|
||||
protected:
|
||||
GLuint SimulationProgram, RenderProgram;
|
||||
GLuint loc_duration, loc_source, loc_dt, loc_matrix;
|
||||
GLuint loc_position, loc_velocity, loc_lifetime;
|
||||
GLuint tfb_buffers[2];
|
||||
unsigned duration, count;
|
||||
core::vector3df direction;
|
||||
core::aabbox3d<f32> box;
|
||||
|
||||
virtual void simulate();
|
||||
virtual void draw();
|
||||
public:
|
||||
PointEmitter(
|
||||
scene::ISceneManager* mgr, ITexture *tex,
|
||||
const core::vector3df& dir,
|
||||
u32 minParticlesPerSecond,
|
||||
u32 maxParticlesPerSecond,
|
||||
const video::SColor& minStartColor,
|
||||
const video::SColor& maxStartColor,
|
||||
u32 lifeTimeMin, u32 lifeTimeMax,
|
||||
s32 maxAngleDegrees
|
||||
// const core::dimension2df& minStartSize,
|
||||
// const core::dimension2df& maxStartSize
|
||||
);
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const { return box; }
|
||||
virtual u32 getMaterialCount() const { return 1; }
|
||||
};
|
||||
|
||||
class RainNode : public GPUParticle
|
||||
{
|
||||
protected:
|
||||
GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2];
|
||||
unsigned count;
|
||||
GLuint texture, normal_and_depth;
|
||||
GLuint loc_campos, loc_viewm, loc_time;
|
||||
GLuint texture, normal_and_depth;
|
||||
GLuint loc_campos, loc_viewm, loc_time;
|
||||
GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths;
|
||||
s32 area;
|
||||
core::aabbox3d<f32> box;
|
||||
|
||||
virtual void simulate();
|
||||
virtual void simulate();
|
||||
virtual void draw();
|
||||
public:
|
||||
RainNode(scene::ISceneManager* mgr, ITexture *tex);
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
virtual u32 getMaterialCount() const { return 1; }
|
||||
};
|
||||
|
||||
#endif // GPUPARTICLES_H
|
||||
};
|
||||
|
||||
#endif // GPUPARTICLES_H
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
#include "graphics/gpuparticles.h"
|
||||
|
||||
#include <SParticle.h>
|
||||
#include <IParticleAffector.h>
|
||||
@ -436,11 +437,25 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
case EMITTER_POINT:
|
||||
{
|
||||
m_emitter = m_node->createPointEmitter(velocity,
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
#ifdef GPUPARTICLE
|
||||
0., 0.,
|
||||
#else
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
#endif
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
m_particle_type->getAngleSpread() /* angle */
|
||||
);
|
||||
#ifdef GPUPARTICLE
|
||||
PointEmitter *PE = new PointEmitter(irr_driver->getSceneManager(), m_node->getMaterial(0).getTexture(0),
|
||||
velocity,
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
m_particle_type->getAngleSpread());
|
||||
PE->setPosition(m_node->getPosition());
|
||||
irr_driver->addPerCameraNode(PE, irr_driver->getSceneManager()->getActiveCamera(), NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user