diff --git a/cont/base/springcontent/shaders/GLSL/ParticleGeneratorTemplate.glsl b/cont/base/springcontent/shaders/GLSL/ParticleGeneratorTemplate.glsl index ad40a7f1c9..a96219fdff 100644 --- a/cont/base/springcontent/shaders/GLSL/ParticleGeneratorTemplate.glsl +++ b/cont/base/springcontent/shaders/GLSL/ParticleGeneratorTemplate.glsl @@ -2,6 +2,7 @@ uniform ivec2 arraySizes; uniform vec4 frameInfo; // gs->frameNum, globalRendering->timeOffset, gu->modGameTime, prevSyncedFrame +uniform vec3 windVec; // vec * speed uniform vec3 camPos; uniform vec3 camDir[3]; // right, up, forward diff --git a/cont/base/springcontent/shaders/GLSL/Particles/SmokeParticleGenerator.lua b/cont/base/springcontent/shaders/GLSL/Particles/SmokeParticleGenerator.lua new file mode 100644 index 0000000000..8238e13160 --- /dev/null +++ b/cont/base/springcontent/shaders/GLSL/Particles/SmokeParticleGenerator.lua @@ -0,0 +1,39 @@ +return { + EarlyExit = +[[ + int syncedTime = int(frameInfo.x - createFrame); + float currTime = syncedTime + frameInfo.y; + float age = ageRate * syncedTime; + if (age >= 1.0) + return; +]], + MainCode = +[[ + bool doUpdate = (frameInfo.x > frameInfo.w); + if (doUpdate) { + pos += speed; + pos += windVec * age * 0.05; + size += sizeExpansion; + size += ((startSize - size) * 0.2 * float(size < startSize)); + + SavePos(pos); + SaveSize(size); + } + + float alpha = (1.0 - age); + color *= alpha; + + SetCurrentAnimation(animParams, currTime); + vec3 drawPos = pos + speed * frameInfo.y; + float drawSize = size + sizeExpansion * frameInfo.y; + + // rotParams do we need it? + + AddEffectsQuadCamera( + drawOrder, + animParams, + drawPos, vec2(drawSize), texCoord, + color + ); +]] +} \ No newline at end of file diff --git a/rts/Rendering/CMakeLists.txt b/rts/Rendering/CMakeLists.txt index 1382ab2733..997b3fd1a7 100644 --- a/rts/Rendering/CMakeLists.txt +++ b/rts/Rendering/CMakeLists.txt @@ -71,6 +71,7 @@ set(sources_engine_Rendering "${CMAKE_CURRENT_SOURCE_DIR}/Env/Particles/Generators/MuzzleFlameParticleGenerator.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Env/Particles/Generators/NanoParticleGenerator.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Env/Particles/Generators/SimpleParticleGenerator.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Env/Particles/Generators/SmokeParticleGenerator.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GL/FBO.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GL/StreamBuffer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GL/GeometryBuffer.cpp" diff --git a/rts/Rendering/Env/Particles/Classes/SmokeProjectile.cpp b/rts/Rendering/Env/Particles/Classes/SmokeProjectile.cpp index 14d140138e..97e6134df8 100644 --- a/rts/Rendering/Env/Particles/Classes/SmokeProjectile.cpp +++ b/rts/Rendering/Env/Particles/Classes/SmokeProjectile.cpp @@ -9,6 +9,7 @@ #include "Rendering/GlobalRendering.h" #include "Rendering/Env/Particles/ProjectileDrawer.h" #include "Rendering/GL/RenderBuffers.h" +#include "Rendering/Env/Particles/Generators/ParticleGeneratorHandler.h" #include "Rendering/Textures/TextureAtlas.h" #include "Sim/Misc/Wind.h" #include "Sim/Projectiles/ExpGenSpawnableMemberInfo.h" @@ -67,6 +68,28 @@ CSmokeProjectile::CSmokeProjectile( useAirLos |= ((pos.y - CGround::GetApproximateHeight(pos.x, pos.z, false)) > 10.0f); alwaysVisible |= (owner == nullptr); + + auto& pg = ParticleGeneratorHandler::GetInstance().GetGenerator(); + pgOffset = pg.Add({ + .pos = pos, + .size = size, + .startSize = startSize, + .sizeExpansion = sizeExpansion, + .ageRate = ageSpeed, + .speed = speed, + .createFrame = createFrame, + .animParams = animParams, + .color = SColor{color, color, color, 1.0f}, + .rotParams = rotParams, + .drawOrder = drawOrder, + .texCoord = *projectileDrawer->GetSmokeTexture(textureNum) + }); +} + +CSmokeProjectile::~CSmokeProjectile() +{ + auto& pg = ParticleGeneratorHandler::GetInstance().GetGenerator(); + pg.Del(pgOffset); } diff --git a/rts/Rendering/Env/Particles/Classes/SmokeProjectile.h b/rts/Rendering/Env/Particles/Classes/SmokeProjectile.h index 0a8e7fe6c9..f9aff8e350 100644 --- a/rts/Rendering/Env/Particles/Classes/SmokeProjectile.h +++ b/rts/Rendering/Env/Particles/Classes/SmokeProjectile.h @@ -23,6 +23,7 @@ class CSmokeProjectile : public CProjectile float sizeExpansion, float color ); + ~CSmokeProjectile() override; void Update() override; void Draw() override; @@ -32,16 +33,16 @@ class CSmokeProjectile : public CProjectile static bool GetMemberInfo(SExpGenSpawnableMemberInfo& memberInfo); +public: + float size; private: float color; float age; float ageSpeed; -public: - float size; -private: float startSize; float sizeExpansion; int textureNum; + size_t pgOffset; }; #endif /* SMOKE_PROJECTILE_H */ diff --git a/rts/Rendering/Env/Particles/Generators/ParticleGenerator.h b/rts/Rendering/Env/Particles/Generators/ParticleGenerator.h index f09d2f113b..04836de0b1 100644 --- a/rts/Rendering/Env/Particles/Generators/ParticleGenerator.h +++ b/rts/Rendering/Env/Particles/Generators/ParticleGenerator.h @@ -21,6 +21,7 @@ #include "Game/GlobalUnsynced.h" #include "lua/LuaParser.h" #include "Sim/Misc/GlobalSynced.h" +#include "Sim/Misc/Wind.h" // to not repeat in derived classes #include "Rendering/Textures/TextureAtlas.h" @@ -142,6 +143,7 @@ inline void ParticleGenerator::UpdateCommonUn ); shader->SetUniform("frameInfo", currFrame, globalRendering->timeOffset, gu->modGameTime, prevFrame); + shader->SetUniform3v("windVec", &envResHandler.GetCurrentWindVec().x); shader->SetUniform3v("camPos", &camera->GetPos().x); shader->SetUniform3v("camDir[0]", &camera->GetRight().x); @@ -433,6 +435,7 @@ inline Shader::IProgramObject* ParticleGeneratorSetUniform("arraySizes", 0, 0); shader->SetUniform("frameInfo", 0.0f, 0.0f, 0.0f, 0.0f); + shader->SetUniform("windVec", 0.0f, 0.0f, 0.0f); shader->SetUniform("camPos", 0.0f, 0.0f, 0.0f); shader->SetUniform("camDir[0]", 0.0f, 0.0f, 0.0f); shader->SetUniform("camDir[1]", 0.0f, 0.0f, 0.0f); diff --git a/rts/Rendering/Env/Particles/Generators/ParticleGeneratorHandler.h b/rts/Rendering/Env/Particles/Generators/ParticleGeneratorHandler.h index 892f97201f..ba15c4bbe2 100644 --- a/rts/Rendering/Env/Particles/Generators/ParticleGeneratorHandler.h +++ b/rts/Rendering/Env/Particles/Generators/ParticleGeneratorHandler.h @@ -28,6 +28,7 @@ #include "MuzzleFlameParticleGenerator.h" #include "NanoParticleGenerator.h" #include "SimpleParticleGenerator.h" +#include "SmokeParticleGenerator.h" namespace Shader { struct IProgramObject; @@ -103,7 +104,8 @@ class ParticleGeneratorHandler { MuzzleFlameParticleGenerator, NanoParticleGenerator, // skipped shields and repulsor - SimpleParticleGenerator + SimpleParticleGenerator, + SmokeParticleGenerator >; std::unique_ptr generators; diff --git a/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.cpp b/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.cpp new file mode 100644 index 0000000000..a5f5ecbbf5 --- /dev/null +++ b/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.cpp @@ -0,0 +1,19 @@ +#include "SmokeParticleGenerator.h" + +CR_BIND(SmokeParticleData, ) +CR_REG_METADATA(SmokeParticleData, +( + CR_MEMBER(pos), + CR_MEMBER(size), + CR_MEMBER(startSize), + CR_MEMBER(sizeExpansion), + CR_MEMBER(ageRate), + CR_IGNORED(unused), + CR_MEMBER(speed), + CR_MEMBER(createFrame), + CR_MEMBER(animParams), + CR_MEMBER(color), + CR_MEMBER(rotParams), + CR_MEMBER(drawOrder), + CR_MEMBER(texCoord) +)) \ No newline at end of file diff --git a/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.h b/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.h new file mode 100644 index 0000000000..c4021a1595 --- /dev/null +++ b/rts/Rendering/Env/Particles/Generators/SmokeParticleGenerator.h @@ -0,0 +1,40 @@ +#pragma once + +#include "ParticleGenerator.h" + +struct SmokeParticleData { + CR_DECLARE_STRUCT(SmokeParticleData) + float3 pos; + float size; + + float startSize; + float sizeExpansion; + float ageRate; + float unused; + + float3 speed; + int32_t createFrame; + + float3 animParams; + SColor color; + + float3 rotParams; + int32_t drawOrder; + + AtlasedTexture texCoord; + + int32_t GetMaxNumQuads() const { return 1 * (texCoord != AtlasedTexture::DefaultAtlasTexture); } + void Invalidate() { + texCoord = AtlasedTexture::DefaultAtlasTexture; + } +}; +static_assert(sizeof(SmokeParticleData) % 16 == 0); + +class SmokeParticleGenerator : public ParticleGenerator { + friend class ParticleGenerator; +public: + SmokeParticleGenerator() {} + ~SmokeParticleGenerator() {} +protected: + bool GenerateCPUImpl() { return false; } +};