From df2bd304ab752c1d680fead775967c963eaebda4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 20:56:29 +0000 Subject: [PATCH] GPUParticles: Put it in its own file Disable rain while doing ping-pong between os to get windows opengl callback git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14814 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 5 +- src/graphics/gpuparticles.cpp | 210 +++++++++++++++++++++++++++ src/graphics/gpuparticles.h | 73 ++++++++++ src/graphics/rain.cpp | 266 +--------------------------------- 4 files changed, 292 insertions(+), 262 deletions(-) create mode 100644 src/graphics/gpuparticles.cpp create mode 100644 src/graphics/gpuparticles.h diff --git a/sources.cmake b/sources.cmake index 6ed2afbdd..7ee80c697 100644 --- a/sources.cmake +++ b/sources.cmake @@ -34,6 +34,7 @@ src/graphics/camera.cpp src/graphics/CBatchingMesh.cpp src/graphics/explosion.cpp src/graphics/glow.cpp +src/graphics/gpuparticles.cpp src/graphics/hardware_skinning.cpp src/graphics/hit_sfx.cpp src/graphics/irr_driver.cpp @@ -478,8 +479,8 @@ src/modes/tutorial_world.hpp src/modes/world.hpp src/modes/world_status.hpp src/modes/world_with_rank.hpp -src/network/event.hpp src/network/client_network_manager.hpp +src/network/event.hpp src/network/game_setup.hpp src/network/network_interface.hpp src/network/network_manager.hpp @@ -636,10 +637,10 @@ src/tracks/track_object_presentation.hpp src/tracks/track_sector.hpp src/utils/aligned_array.hpp src/utils/constants.hpp +src/utils/crash_reporting.hpp src/utils/debug.hpp src/utils/helpers.hpp src/utils/interpolation_array.hpp -src/utils/crash_reporting.hpp src/utils/leak_check.hpp src/utils/log.hpp src/utils/no_copy.hpp diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp new file mode 100644 index 000000000..33260b0c3 --- /dev/null +++ b/src/graphics/gpuparticles.cpp @@ -0,0 +1,210 @@ +#if 0 +#include "graphics/irr_driver.hpp" +#include "gpuparticles.h" +#include +#include "io/file_manager.hpp" +#include "config/user_config.hpp" +#include + +void initGL() +{ +/* 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"); +#ifdef _IRR_WINDOWS_API_ + glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); +#endif + 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");*/ +} + +// 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(tex)->getOpenGLTextureName(); +} + +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, texid); + glUniform1i(location, textureUnit); +} + +GPUParticle::GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : + count(c), texture(tex), normal_and_depth(rtt) { + initGL(); + glGenBuffers(2, tfb_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); + + 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"); + } + +void GPUParticle::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 GPUParticle::render() { + 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); +} +#endif diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h new file mode 100644 index 000000000..85cb446fe --- /dev/null +++ b/src/graphics/gpuparticles.h @@ -0,0 +1,73 @@ +#if 0 +#ifndef GPUPARTICLES_H +#define GPUPARTICLES_H + +#define GL_GLEXT_PROTOTYPES 1 +#include "graphics/glwrap.hpp" +#include + +/*#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) +#else +#include +#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) +#endif + + +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; +#ifdef _IRR_WINDOWS_API_ +PFNGLACTIVETEXTUREPROC glActiveTexture; +#endif +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;*/ + +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 { +private: + unsigned count; + GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; + 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; +public: + GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt); + void simulate(); + void render(); +}; + +#endif // GPUPARTICLES_H +#endif diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index 0d794067a..07d5a4119 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -32,271 +32,17 @@ #include #include +#include "graphics/gpuparticles.h" using namespace video; using namespace scene; using namespace core; -// OPENGL PARTICLE SYSTEM -#include -#include "../source/Irrlicht/COpenGLExtensionHandler.h" -#include "io/file_manager.hpp" - -#ifdef _IRR_WINDOWS_API_ -#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) -#else -#include -#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) -#endif - - -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; -#ifdef _IRR_WINDOWS_API_ -PFNGLACTIVETEXTUREPROC glActiveTexture; -#endif -PFNGLUNIFORM2FPROC glUniform2f; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; - -void initGL() -{ - 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"); -#ifdef _IRR_WINDOWS_API_ - glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); -#endif - 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"); -} - -// Mostly from shader tutorial -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(ITexture *tex) { return static_cast(tex)->getOpenGLTextureName(); } - -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, texid); - glUniform1i(location, textureUnit); -} - -class GPUParticle { -private: - GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; - 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; - unsigned count; -public: - GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : - count(c), texture(tex), normal_and_depth(rtt) { - initGL(); - glGenBuffers(2, tfb_vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); - - 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"); - } - - void simulate() { - glUseProgram(SimulationProgram); - const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const matrix4 viewm = irr_driver->getVideoDriver()->getTransform(ETS_VIEW); - const 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 render() { - 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 }; - matrix4 invproj = irr_driver->getVideoDriver()->getTransform(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); - } -}; -// END OPENGL PARTICLE SYSTEM - // The actual rain node class RainNode: public scene::ISceneNode { private: - GPUParticle *gpupart; +// GPUParticle *gpupart; public: RainNode(scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(0, mgr, -1) @@ -326,7 +72,7 @@ public: vertices[3 * i + 1] = y; vertices[3 * i + 2] = z; } - gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); + //gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); box.addInternalPoint(vector3df((float)(-area/2))); box.addInternalPoint(vector3df((float)( area/2))); @@ -334,13 +80,13 @@ public: ~RainNode() { - delete gpupart; +// delete gpupart; } virtual void render() { - gpupart->simulate(); - gpupart->render(); +// gpupart->simulate(); +// gpupart->render(); // We need to force irrlicht to update its internal states IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setMaterial(mat);