moved drawEffect() to SparkEmitter
This commit is contained in:
parent
115cbbb7fa
commit
d2605d9108
74
Game.cpp
74
Game.cpp
@ -200,8 +200,7 @@ namespace ZL
|
|||||||
|
|
||||||
sparkTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/spark.png", CONST_ZIP_FILE));
|
sparkTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/spark.png", CONST_ZIP_FILE));
|
||||||
|
|
||||||
sparkQuad.data = CreateRect2D({ 0, 0 }, { 0.08f, 0.08f }, 0);
|
sparkEmitter.setTexture(sparkTexture);
|
||||||
sparkQuad.RefreshVBO();
|
|
||||||
|
|
||||||
renderer.InitOpenGL();
|
renderer.InitOpenGL();
|
||||||
|
|
||||||
@ -241,75 +240,6 @@ namespace ZL
|
|||||||
CheckGlError();
|
CheckGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::drawEffects()
|
|
||||||
{
|
|
||||||
if (sparkEmitter.getActiveParticleCount() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.clear();
|
|
||||||
sparkQuad.data.TexCoordData.clear();
|
|
||||||
|
|
||||||
const auto& particles = sparkEmitter.getParticles();
|
|
||||||
for (const auto& particle : particles) {
|
|
||||||
if (!particle.active) continue;
|
|
||||||
|
|
||||||
Vector3f pos = particle.position;
|
|
||||||
float size = 0.04f * particle.scale;
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 0.0f, 0.0f });
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] - size, pos.v[1] + size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 0.0f, 1.0f });
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 1.0f, 1.0f });
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 0.0f, 0.0f });
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 1.0f, 1.0f });
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData.push_back({ pos.v[0] + size, pos.v[1] - size, pos.v[2] });
|
|
||||||
sparkQuad.data.TexCoordData.push_back({ 1.0f, 0.0f });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sparkQuad.data.PositionData.empty()) return;
|
|
||||||
|
|
||||||
sparkQuad.RefreshVBO();
|
|
||||||
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
1, 1000);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sparkTexture->getTexID());
|
|
||||||
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom });
|
|
||||||
|
|
||||||
renderer.DrawVertexRenderStruct(sparkQuad);
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawShip()
|
void Game::drawShip()
|
||||||
{
|
{
|
||||||
static const std::string defaultShaderName = "default";
|
static const std::string defaultShaderName = "default";
|
||||||
@ -335,7 +265,7 @@ namespace ZL
|
|||||||
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(spaceship);
|
renderer.DrawVertexRenderStruct(spaceship);
|
||||||
|
|
||||||
drawEffects();
|
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
|
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
|
|||||||
3
Game.h
3
Game.h
@ -31,7 +31,6 @@ namespace ZL {
|
|||||||
void processTickCount();
|
void processTickCount();
|
||||||
void drawScene();
|
void drawScene();
|
||||||
void drawCubemap();
|
void drawCubemap();
|
||||||
void drawEffects();
|
|
||||||
void drawShip();
|
void drawShip();
|
||||||
void drawBoxes();
|
void drawBoxes();
|
||||||
|
|
||||||
@ -59,9 +58,7 @@ namespace ZL {
|
|||||||
std::vector<BoxCoords> boxCoordsArr;
|
std::vector<BoxCoords> boxCoordsArr;
|
||||||
std::vector<VertexRenderStruct> boxRenderArr;
|
std::vector<VertexRenderStruct> boxRenderArr;
|
||||||
|
|
||||||
//VertexRenderStruct singleSpark;
|
|
||||||
SparkEmitter sparkEmitter;
|
SparkEmitter sparkEmitter;
|
||||||
VertexRenderStruct sparkQuad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
159
SparkEmitter.cpp
159
SparkEmitter.cpp
@ -6,59 +6,127 @@
|
|||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter()
|
SparkEmitter::SparkEmitter()
|
||||||
: emissionRate(100.0f), isActive(true), buffersDirty(true), maxParticles(200) {
|
: emissionRate(100.0f), isActive(true), drawDataDirty(true), maxParticles(200) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
positionBuffer.resize(maxParticles * 4, 0.0f);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
texCoordBuffer.resize(maxParticles * 2, 0.0f);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
lastEmissionTime = std::chrono::steady_clock::now();
|
lastEmissionTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
sparkQuad.data = VertexDataStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions, float rate)
|
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions, float rate)
|
||||||
: emissionPoints(positions), emissionRate(rate), isActive(true),
|
: emissionPoints(positions), emissionRate(rate), isActive(true),
|
||||||
buffersDirty(true), maxParticles(positions.size() * 100) {
|
drawDataDirty(true), maxParticles(positions.size() * 100) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
positionBuffer.resize(maxParticles * 4, 0.0f);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
texCoordBuffer.resize(maxParticles * 2, 0.0f);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
lastEmissionTime = std::chrono::steady_clock::now();
|
lastEmissionTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
sparkQuad.data = VertexDataStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparkEmitter::setEmissionPoints(const std::vector<Vector3f>& positions) {
|
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions,
|
||||||
emissionPoints = positions;
|
std::shared_ptr<Texture> tex,
|
||||||
maxParticles = positions.size() * 100;
|
float rate)
|
||||||
|
: emissionPoints(positions), texture(tex), emissionRate(rate),
|
||||||
|
isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
positionBuffer.resize(maxParticles * 4, 0.0f);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
texCoordBuffer.resize(maxParticles * 2, 0.0f);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
buffersDirty = true;
|
lastEmissionTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
sparkQuad.data = VertexDataStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparkEmitter::updateBuffers() {
|
void SparkEmitter::setTexture(std::shared_ptr<Texture> tex) {
|
||||||
if (!buffersDirty) return;
|
texture = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparkEmitter::prepareDrawData() {
|
||||||
|
if (!drawDataDirty) return;
|
||||||
|
|
||||||
|
drawPositions.clear();
|
||||||
|
drawTexCoords.clear();
|
||||||
|
|
||||||
|
if (getActiveParticleCount() == 0) {
|
||||||
|
drawDataDirty = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size_t bufferIndex = 0;
|
|
||||||
for (const auto& particle : particles) {
|
for (const auto& particle : particles) {
|
||||||
if (particle.active) {
|
if (!particle.active) continue;
|
||||||
positionBuffer[bufferIndex * 4] = particle.position.v[0];
|
|
||||||
positionBuffer[bufferIndex * 4 + 1] = particle.position.v[1];
|
|
||||||
positionBuffer[bufferIndex * 4 + 2] = particle.position.v[2];
|
|
||||||
positionBuffer[bufferIndex * 4 + 3] = particle.scale;
|
|
||||||
|
|
||||||
texCoordBuffer[bufferIndex * 2] = 0.0f;
|
Vector3f pos = particle.position;
|
||||||
texCoordBuffer[bufferIndex * 2 + 1] = 0.0f;
|
float size = 0.04f * particle.scale;
|
||||||
|
|
||||||
bufferIndex++;
|
drawPositions.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
||||||
}
|
drawTexCoords.push_back({ 0.0f, 0.0f });
|
||||||
|
|
||||||
|
drawPositions.push_back({ pos.v[0] - size, pos.v[1] + size, pos.v[2] });
|
||||||
|
drawTexCoords.push_back({ 0.0f, 1.0f });
|
||||||
|
|
||||||
|
drawPositions.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
||||||
|
drawTexCoords.push_back({ 1.0f, 1.0f });
|
||||||
|
|
||||||
|
drawPositions.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
||||||
|
drawTexCoords.push_back({ 0.0f, 0.0f });
|
||||||
|
|
||||||
|
drawPositions.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
||||||
|
drawTexCoords.push_back({ 1.0f, 1.0f });
|
||||||
|
|
||||||
|
drawPositions.push_back({ pos.v[0] + size, pos.v[1] - size, pos.v[2] });
|
||||||
|
drawTexCoords.push_back({ 1.0f, 0.0f });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = bufferIndex; i < maxParticles; i++) {
|
drawDataDirty = false;
|
||||||
positionBuffer[i * 4] = 0.0f;
|
}
|
||||||
positionBuffer[i * 4 + 1] = 0.0f;
|
|
||||||
positionBuffer[i * 4 + 2] = 0.0f;
|
void SparkEmitter::draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight) {
|
||||||
positionBuffer[i * 4 + 3] = 0.0f;
|
if (getActiveParticleCount() == 0) {
|
||||||
texCoordBuffer[i * 2] = 0.0f;
|
return;
|
||||||
texCoordBuffer[i * 2 + 1] = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffersDirty = false;
|
if (!texture) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareDrawData();
|
||||||
|
|
||||||
|
if (drawPositions.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sparkQuad.data.PositionData = drawPositions;
|
||||||
|
sparkQuad.data.TexCoordData = drawTexCoords;
|
||||||
|
sparkQuad.RefreshVBO();
|
||||||
|
|
||||||
|
static const std::string defaultShaderName = "default";
|
||||||
|
static const std::string vPositionName = "vPosition";
|
||||||
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
|
renderer.shaderManager.PushShader(defaultShaderName);
|
||||||
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
|
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||||
|
|
||||||
|
float aspectRatio = static_cast<float>(screenWidth) / static_cast<float>(screenHeight);
|
||||||
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, aspectRatio, 1, 1000);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||||
|
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
renderer.TranslateMatrix({ 0, 0, -1.0f * zoom });
|
||||||
|
|
||||||
|
renderer.DrawVertexRenderStruct(sparkQuad);
|
||||||
|
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
|
renderer.shaderManager.PopShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparkEmitter::update(float deltaTimeMs) {
|
void SparkEmitter::update(float deltaTimeMs) {
|
||||||
@ -69,12 +137,14 @@ namespace ZL {
|
|||||||
if (isActive && elapsed >= emissionRate) {
|
if (isActive && elapsed >= emissionRate) {
|
||||||
emit();
|
emit();
|
||||||
lastEmissionTime = currentTime;
|
lastEmissionTime = currentTime;
|
||||||
|
drawDataDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anyChanged = false;
|
bool anyChanged = false;
|
||||||
for (auto& particle : particles) {
|
for (auto& particle : particles) {
|
||||||
if (particle.active) {
|
if (particle.active) {
|
||||||
Vector3f oldPosition = particle.position;
|
Vector3f oldPosition = particle.position;
|
||||||
|
float oldScale = particle.scale;
|
||||||
|
|
||||||
particle.position.v[0] += particle.velocity.v[0] * deltaTimeMs / 1000.0f;
|
particle.position.v[0] += particle.velocity.v[0] * deltaTimeMs / 1000.0f;
|
||||||
particle.position.v[1] += particle.velocity.v[1] * deltaTimeMs / 1000.0f;
|
particle.position.v[1] += particle.velocity.v[1] * deltaTimeMs / 1000.0f;
|
||||||
@ -92,7 +162,8 @@ namespace ZL {
|
|||||||
|
|
||||||
if (oldPosition.v[0] != particle.position.v[0] ||
|
if (oldPosition.v[0] != particle.position.v[0] ||
|
||||||
oldPosition.v[1] != particle.position.v[1] ||
|
oldPosition.v[1] != particle.position.v[1] ||
|
||||||
oldPosition.v[2] != particle.position.v[2]) {
|
oldPosition.v[2] != particle.position.v[2] ||
|
||||||
|
oldScale != particle.scale) {
|
||||||
anyChanged = true;
|
anyChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +171,7 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (anyChanged) {
|
if (anyChanged) {
|
||||||
buffersDirty = true;
|
drawDataDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +216,17 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (emitted) {
|
if (emitted) {
|
||||||
buffersDirty = true;
|
drawDataDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SparkEmitter::setEmissionPoints(const std::vector<Vector3f>& positions) {
|
||||||
|
emissionPoints = positions;
|
||||||
|
maxParticles = positions.size() * 100;
|
||||||
|
particles.resize(maxParticles);
|
||||||
|
drawDataDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void SparkEmitter::initParticle(SparkParticle& particle, int emitterIndex) {
|
void SparkEmitter::initParticle(SparkParticle& particle, int emitterIndex) {
|
||||||
particle.velocity = getRandomVelocity(emitterIndex);
|
particle.velocity = getRandomVelocity(emitterIndex);
|
||||||
particle.scale = 1.0f;
|
particle.scale = 1.0f;
|
||||||
@ -197,15 +275,4 @@ namespace ZL {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SparkEmitter::getActiveParticleBufferIndex(size_t particleIndex) const {
|
|
||||||
size_t activeIndex = 0;
|
|
||||||
for (size_t i = 0; i <= particleIndex; i++) {
|
|
||||||
if (particles[i].active) {
|
|
||||||
if (i == particleIndex) return activeIndex;
|
|
||||||
activeIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ZLMath.h"
|
#include "ZLMath.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "TextureManager.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
@ -14,7 +16,6 @@ namespace ZL {
|
|||||||
float maxLifeTime;
|
float maxLifeTime;
|
||||||
bool active;
|
bool active;
|
||||||
int emitterIndex;
|
int emitterIndex;
|
||||||
Vector2f texCoord;
|
|
||||||
|
|
||||||
SparkParticle() : position({ 0,0,0 }), velocity({ 0,0,0 }), scale(1.0f),
|
SparkParticle() : position({ 0,0,0 }), velocity({ 0,0,0 }), scale(1.0f),
|
||||||
lifeTime(0), maxLifeTime(1000.0f), active(false), emitterIndex(0) {
|
lifeTime(0), maxLifeTime(1000.0f), active(false), emitterIndex(0) {
|
||||||
@ -29,30 +30,34 @@ namespace ZL {
|
|||||||
float emissionRate;
|
float emissionRate;
|
||||||
bool isActive;
|
bool isActive;
|
||||||
|
|
||||||
std::vector<float> positionBuffer;
|
std::vector<Vector3f> drawPositions;
|
||||||
std::vector<float> texCoordBuffer;
|
std::vector<Vector2f> drawTexCoords;
|
||||||
bool buffersDirty;
|
bool drawDataDirty;
|
||||||
|
VertexRenderStruct sparkQuad;
|
||||||
|
std::shared_ptr<Texture> texture;
|
||||||
|
|
||||||
int maxParticles;
|
int maxParticles;
|
||||||
|
|
||||||
|
void prepareDrawData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SparkEmitter();
|
SparkEmitter();
|
||||||
SparkEmitter(const std::vector<Vector3f>& positions, float rate = 100.0f);
|
SparkEmitter(const std::vector<Vector3f>& positions, float rate = 100.0f);
|
||||||
|
SparkEmitter(const std::vector<Vector3f>& positions,
|
||||||
|
std::shared_ptr<Texture> tex,
|
||||||
|
float rate = 100.0f);
|
||||||
|
|
||||||
void setEmissionPoints(const std::vector<Vector3f>& positions);
|
void setEmissionPoints(const std::vector<Vector3f>& positions);
|
||||||
|
void setTexture(std::shared_ptr<Texture> tex);
|
||||||
|
|
||||||
void update(float deltaTimeMs);
|
void update(float deltaTimeMs);
|
||||||
void emit();
|
void emit();
|
||||||
|
|
||||||
|
void draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight);
|
||||||
|
|
||||||
const std::vector<SparkParticle>& getParticles() const;
|
const std::vector<SparkParticle>& getParticles() const;
|
||||||
size_t getActiveParticleCount() const;
|
size_t getActiveParticleCount() const;
|
||||||
|
|
||||||
const float* getPositionBuffer() const { return positionBuffer.data(); }
|
|
||||||
const float* getTexCoordBuffer() const { return texCoordBuffer.data(); }
|
|
||||||
size_t getBufferSize() const { return positionBuffer.size() / 4; }
|
|
||||||
void updateBuffers();
|
|
||||||
|
|
||||||
size_t getActiveParticleBufferIndex(size_t particleIndex) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initParticle(SparkParticle& particle, int emitterIndex);
|
void initParticle(SparkParticle& particle, int emitterIndex);
|
||||||
Vector3f getRandomVelocity(int emitterIndex);
|
Vector3f getRandomVelocity(int emitterIndex);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user