mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Render M2 glow batches as billboarded light sprites
Replace flat mesh rendering of additive/mod blend batches (blendMode >= 3) with camera-facing point sprites using a soft radial gradient texture and additive blending. Adds M2 particle emitter infrastructure (structs, shader, parsing stubs) but disables emitter parsing — the assumed 476-byte struct size is wrong for WotLK 3.3.5a, causing misaligned reads that explode RAM.
This commit is contained in:
parent
b9fdc3396d
commit
88241cbddc
5 changed files with 635 additions and 7 deletions
|
|
@ -34,6 +34,8 @@ struct M2ModelGPU {
|
|||
uint16_t textureAnimIndex = 0xFFFF; // 0xFFFF = no texture animation
|
||||
uint16_t blendMode = 0; // 0=Opaque, 1=AlphaKey, 2=Alpha, 3=Add, etc.
|
||||
uint16_t materialFlags = 0; // M2 material flags (0x01=Unlit, 0x04=TwoSided, 0x10=NoDepthWrite)
|
||||
glm::vec3 center = glm::vec3(0.0f); // Center of batch geometry (model space)
|
||||
float glowSize = 1.0f; // Approx radius of batch geometry
|
||||
};
|
||||
|
||||
GLuint vao = 0;
|
||||
|
|
@ -66,6 +68,10 @@ struct M2ModelGPU {
|
|||
bool disableAnimation = false; // Keep foliage/tree doodads visually stable
|
||||
bool hasTextureAnimation = false; // True if any batch has UV animation
|
||||
|
||||
// Particle emitter data (kept from M2Model)
|
||||
std::vector<pipeline::M2ParticleEmitter> particleEmitters;
|
||||
std::vector<GLuint> particleTextures; // Resolved GL textures per emitter
|
||||
|
||||
// Texture transform data for UV animation
|
||||
std::vector<pipeline::M2TextureTransform> textureTransforms;
|
||||
std::vector<uint16_t> textureTransformLookup;
|
||||
|
|
@ -74,6 +80,17 @@ struct M2ModelGPU {
|
|||
bool isValid() const { return vao != 0 && indexCount > 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* A single M2 particle emitted from a particle emitter
|
||||
*/
|
||||
struct M2Particle {
|
||||
glm::vec3 position;
|
||||
glm::vec3 velocity;
|
||||
float life; // current age in seconds
|
||||
float maxLife; // total lifespan
|
||||
int emitterIndex; // which emitter spawned this
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance of an M2 model in the world
|
||||
*/
|
||||
|
|
@ -100,6 +117,10 @@ struct M2Instance {
|
|||
float variationTimer = 0.0f; // Time until next variation attempt (ms)
|
||||
bool playingVariation = false;// Currently playing a one-shot variation
|
||||
|
||||
// Particle emitter state
|
||||
std::vector<float> emitterAccumulators; // fractional particle counter per emitter
|
||||
std::vector<M2Particle> particles;
|
||||
|
||||
void updateModelMatrix();
|
||||
};
|
||||
|
||||
|
|
@ -177,6 +198,11 @@ public:
|
|||
*/
|
||||
void renderSmokeParticles(const Camera& camera, const glm::mat4& view, const glm::mat4& projection);
|
||||
|
||||
/**
|
||||
* Render M2 particle emitter particles (call after renderSmokeParticles())
|
||||
*/
|
||||
void renderM2Particles(const glm::mat4& view, const glm::mat4& proj);
|
||||
|
||||
/**
|
||||
* Remove a specific instance by ID
|
||||
* @param instanceId Instance ID returned by createInstance()
|
||||
|
|
@ -260,6 +286,7 @@ private:
|
|||
GLuint loadTexture(const std::string& path);
|
||||
std::unordered_map<std::string, GLuint> textureCache;
|
||||
GLuint whiteTexture = 0;
|
||||
GLuint glowTexture = 0; // Soft radial gradient for glow sprites
|
||||
|
||||
// Lighting uniforms
|
||||
glm::vec3 lightDir = glm::vec3(0.5f, 0.5f, 1.0f);
|
||||
|
|
@ -319,6 +346,21 @@ private:
|
|||
static constexpr int MAX_SMOKE_PARTICLES = 1000;
|
||||
float smokeEmitAccum = 0.0f;
|
||||
std::mt19937 smokeRng{42};
|
||||
|
||||
// M2 particle emitter system
|
||||
GLuint m2ParticleShader_ = 0;
|
||||
GLuint m2ParticleVAO_ = 0;
|
||||
GLuint m2ParticleVBO_ = 0;
|
||||
static constexpr size_t MAX_M2_PARTICLES = 4000;
|
||||
std::mt19937 particleRng_{123};
|
||||
|
||||
float interpFloat(const pipeline::M2AnimationTrack& track, float animTime, int seqIdx,
|
||||
const std::vector<pipeline::M2Sequence>& seqs,
|
||||
const std::vector<uint32_t>& globalSeqDurations);
|
||||
float interpFBlockFloat(const pipeline::M2FBlock& fb, float lifeRatio);
|
||||
glm::vec3 interpFBlockVec3(const pipeline::M2FBlock& fb, float lifeRatio);
|
||||
void emitParticles(M2Instance& inst, const M2ModelGPU& gpu, float dt);
|
||||
void updateParticles(M2Instance& inst, float dt);
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue