mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 20:02:40 +01:00
Implement new VisualFX system for particles etc.
- VisualFX stores data about effects like particles and lighting - Only particles initial implementation - World stores active VisualFX
This commit is contained in:
parent
d1e7dcdcd1
commit
f655e454d6
@ -19,6 +19,8 @@ class CharacterObject;
|
|||||||
class InstanceObject;
|
class InstanceObject;
|
||||||
class VehicleObject;
|
class VehicleObject;
|
||||||
|
|
||||||
|
#include <render/VisualFX.hpp>
|
||||||
|
|
||||||
struct WeaponScan;
|
struct WeaponScan;
|
||||||
|
|
||||||
class ScriptMachine;
|
class ScriptMachine;
|
||||||
@ -137,7 +139,17 @@ public:
|
|||||||
* Performs a weapon scan against things in the world
|
* Performs a weapon scan against things in the world
|
||||||
*/
|
*/
|
||||||
void doWeaponScan(const WeaponScan &scan );
|
void doWeaponScan(const WeaponScan &scan );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a new VisualFX of the given type
|
||||||
|
*/
|
||||||
|
VisualFX* createEffect(VisualFX::EffectType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immediately destoys the given effect
|
||||||
|
*/
|
||||||
|
void destroyEffect(VisualFX* effect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current hour
|
* Returns the current hour
|
||||||
*/
|
*/
|
||||||
@ -208,6 +220,12 @@ public:
|
|||||||
* AI Graph
|
* AI Graph
|
||||||
*/
|
*/
|
||||||
AIGraph aigraph;
|
AIGraph aigraph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visual Effects
|
||||||
|
* @todo Consider using lighter handing mechanism
|
||||||
|
*/
|
||||||
|
std::vector<VisualFX*> effects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomness Engine
|
* Randomness Engine
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class VisualFX;
|
||||||
class CharacterObject;
|
class CharacterObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,6 +21,7 @@ class PickupObject : public GameObject
|
|||||||
float _enableTimer;
|
float _enableTimer;
|
||||||
bool collected;
|
bool collected;
|
||||||
int _modelID;
|
int _modelID;
|
||||||
|
VisualFX* corona;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PickupObject(GameWorld* world, const glm::vec3& position, int modelID);
|
PickupObject(GameWorld* world, const glm::vec3& position, int modelID);
|
||||||
|
@ -75,64 +75,6 @@ class GameRenderer
|
|||||||
/** Internal non-descript VAOs */
|
/** Internal non-descript VAOs */
|
||||||
GLuint vao, debugVAO;
|
GLuint vao, debugVAO;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stores particle effect instance data
|
|
||||||
*/
|
|
||||||
struct FXParticle {
|
|
||||||
|
|
||||||
/** Initial world position */
|
|
||||||
glm::vec3 position;
|
|
||||||
|
|
||||||
/** Direction of particle */
|
|
||||||
glm::vec3 direction;
|
|
||||||
|
|
||||||
/** Velocity of particle */
|
|
||||||
float velocity;
|
|
||||||
|
|
||||||
/** Particle orientation modes */
|
|
||||||
enum Orientation {
|
|
||||||
Free, /** faces direction using up */
|
|
||||||
Camera, /** Faces towards the camera @todo implement */
|
|
||||||
UpCamera /** Face closes point in camera's look direction */
|
|
||||||
};
|
|
||||||
Orientation orientation;
|
|
||||||
|
|
||||||
/** Game time at particle instantiation */
|
|
||||||
float starttime;
|
|
||||||
float lifetime;
|
|
||||||
|
|
||||||
/** Texture name */
|
|
||||||
GLuint texture;
|
|
||||||
|
|
||||||
/** Size of particle */
|
|
||||||
glm::vec2 size;
|
|
||||||
|
|
||||||
/** Up direction (only used in Free mode) */
|
|
||||||
glm::vec3 up;
|
|
||||||
|
|
||||||
/** Render tint colour */
|
|
||||||
glm::vec4 colour;
|
|
||||||
|
|
||||||
/** Internal cache value */
|
|
||||||
glm::vec3 _currentPosition;
|
|
||||||
|
|
||||||
/** Constructs a particle */
|
|
||||||
FXParticle(const glm::vec3& p, const glm::vec3& d, float v,
|
|
||||||
Orientation o, float st, float lt, GLuint texture,
|
|
||||||
const glm::vec2& size, const glm::vec3& up = {0.f, 0.f, 1.f},
|
|
||||||
const glm::vec4& colour = {1.f, 1.f, 1.f, 1.f})
|
|
||||||
: position(p), direction(d), velocity(v), orientation(o),
|
|
||||||
starttime(st), lifetime(lt), texture(texture), size(size),
|
|
||||||
up(up), colour(colour), _currentPosition(p) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/** Particles in flight */
|
|
||||||
std::vector<FXParticle> _particles;
|
|
||||||
|
|
||||||
/** Camera values passed to renderWorld() */
|
/** Camera values passed to renderWorld() */
|
||||||
ViewCamera _camera;
|
ViewCamera _camera;
|
||||||
|
|
||||||
@ -153,8 +95,6 @@ public:
|
|||||||
Renderer::ShaderProgram* waterProg;
|
Renderer::ShaderProgram* waterProg;
|
||||||
Renderer::ShaderProgram* particleProg;
|
Renderer::ShaderProgram* particleProg;
|
||||||
|
|
||||||
GLuint particleProgram;
|
|
||||||
|
|
||||||
GLuint ssRectProgram;
|
GLuint ssRectProgram;
|
||||||
GLint ssRectTexture, ssRectColour, ssRectSize, ssRectOffset;
|
GLint ssRectTexture, ssRectColour, ssRectSize, ssRectOffset;
|
||||||
|
|
||||||
@ -209,11 +149,11 @@ public:
|
|||||||
void renderWheel(Model*, const glm::mat4& matrix, const std::string& name);
|
void renderWheel(Model*, const glm::mat4& matrix, const std::string& name);
|
||||||
|
|
||||||
void renderItem(InventoryItem* item, const glm::mat4& modelMatrix);
|
void renderItem(InventoryItem* item, const glm::mat4& modelMatrix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief renders all visible particles and removes expired
|
* Renders the effects (Particles, Lighttrails etc)
|
||||||
*/
|
*/
|
||||||
void renderParticles();
|
void renderEffects();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Draws the current on screen text.
|
* @brief Draws the current on screen text.
|
||||||
@ -236,9 +176,6 @@ public:
|
|||||||
/** Increases cinematic value */
|
/** Increases cinematic value */
|
||||||
void renderLetterbox();
|
void renderLetterbox();
|
||||||
|
|
||||||
/** Adds a particle to the rendering */
|
|
||||||
void addParticle(const FXParticle& particle);
|
|
||||||
|
|
||||||
Renderer* getRenderer()
|
Renderer* getRenderer()
|
||||||
{
|
{
|
||||||
return renderer;
|
return renderer;
|
||||||
|
83
rwengine/include/render/VisualFX.hpp
Normal file
83
rwengine/include/render/VisualFX.hpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "TextureData.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a scene effect: lighting, particles etc.
|
||||||
|
*/
|
||||||
|
class VisualFX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum EffectType
|
||||||
|
{
|
||||||
|
Light,
|
||||||
|
Particle,
|
||||||
|
Trail
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LightData
|
||||||
|
{
|
||||||
|
~LightData();
|
||||||
|
};
|
||||||
|
struct ParticleData
|
||||||
|
{
|
||||||
|
/** Initial world position */
|
||||||
|
glm::vec3 position;
|
||||||
|
|
||||||
|
/** Direction of particle */
|
||||||
|
glm::vec3 direction;
|
||||||
|
|
||||||
|
/** Particle orientation modes */
|
||||||
|
enum Orientation {
|
||||||
|
Free, /** faces direction using up */
|
||||||
|
Camera, /** Faces towards the camera @todo implement */
|
||||||
|
UpCamera /** Face closes point in camera's look direction */
|
||||||
|
};
|
||||||
|
Orientation orientation;
|
||||||
|
|
||||||
|
/** Game time at particle instantiation */
|
||||||
|
float starttime;
|
||||||
|
/** Number of seconds particle should exist for, negative values = forever */
|
||||||
|
float lifetime;
|
||||||
|
|
||||||
|
/** Texture name */
|
||||||
|
TextureData::Handle texture;
|
||||||
|
|
||||||
|
/** Size of particle */
|
||||||
|
glm::vec2 size;
|
||||||
|
|
||||||
|
/** Up direction (only used in Free mode) */
|
||||||
|
glm::vec3 up;
|
||||||
|
|
||||||
|
/** Render tint colour */
|
||||||
|
glm::vec4 colour;
|
||||||
|
|
||||||
|
/** Constructs a particle */
|
||||||
|
ParticleData()
|
||||||
|
: orientation(Free), starttime(0.f), lifetime(-1.f), size(1.f, 1.f),
|
||||||
|
up(0.f, 0.f, 1.f), colour(1.f, 1.f, 1.f, 1.f) { }
|
||||||
|
~ParticleData();
|
||||||
|
};
|
||||||
|
struct TrailData
|
||||||
|
{
|
||||||
|
~TrailData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @todo stop abusing unions
|
||||||
|
union {
|
||||||
|
LightData light;
|
||||||
|
ParticleData particle;
|
||||||
|
TrailData trail;
|
||||||
|
};
|
||||||
|
|
||||||
|
VisualFX(EffectType type);
|
||||||
|
~VisualFX();
|
||||||
|
|
||||||
|
EffectType getType() const { return type; }
|
||||||
|
|
||||||
|
const glm::vec3& getPosition() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EffectType type;
|
||||||
|
};
|
@ -504,6 +504,28 @@ void GameWorld::destroyQueuedObjects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VisualFX* GameWorld::createEffect(VisualFX::EffectType type)
|
||||||
|
{
|
||||||
|
auto effect = new VisualFX( type );
|
||||||
|
effects.push_back(effect);
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameWorld::destroyEffect(VisualFX* effect)
|
||||||
|
{
|
||||||
|
for( auto it = effects.begin(); it != effects.end(); )
|
||||||
|
{
|
||||||
|
if( *it == effect )
|
||||||
|
{
|
||||||
|
it = effects.erase( it );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GameWorld::doWeaponScan(const WeaponScan &scan)
|
void GameWorld::doWeaponScan(const WeaponScan &scan)
|
||||||
{
|
{
|
||||||
if( scan.type == WeaponScan::RADIUS ) {
|
if( scan.type == WeaponScan::RADIUS ) {
|
||||||
|
@ -17,6 +17,13 @@ PickupObject::PickupObject(GameWorld *world, const glm::vec3 &position, int mode
|
|||||||
_ghost->setCollisionShape(_shape);
|
_ghost->setCollisionShape(_shape);
|
||||||
_ghost->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT|btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
_ghost->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT|btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||||
|
|
||||||
|
corona = world->createEffect(VisualFX::Particle);
|
||||||
|
corona->particle.position = getPosition();
|
||||||
|
corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
|
||||||
|
corona->particle.orientation = VisualFX::ParticleData::Camera;
|
||||||
|
corona->particle.colour = glm::vec4(1.0f, 0.3f, 0.3f, 0.3f);
|
||||||
|
corona->particle.texture = engine->gameData.findTexture("coronacircle");
|
||||||
|
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +31,7 @@ PickupObject::~PickupObject()
|
|||||||
{
|
{
|
||||||
if(_ghost) {
|
if(_ghost) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
|
engine->destroyEffect(corona);
|
||||||
delete _ghost;
|
delete _ghost;
|
||||||
delete _shape;
|
delete _shape;
|
||||||
}
|
}
|
||||||
@ -64,20 +72,6 @@ void PickupObject::tick(float dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tex = engine->gameData.findTexture("coronacircle")->getName();
|
|
||||||
|
|
||||||
/// @TODO move this into rendering logic.
|
|
||||||
/*engine->renderer.addParticle({
|
|
||||||
position,
|
|
||||||
{0.f, 0.f, 1.f},
|
|
||||||
0.f,
|
|
||||||
GameRenderer::FXParticle::Camera,
|
|
||||||
engine->gameTime, dt,
|
|
||||||
tex,
|
|
||||||
{1.f, 1.f},
|
|
||||||
{}, {0.75f, 0.f, 0.f, 1.f}
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,9 +79,11 @@ void PickupObject::setEnabled(bool enabled)
|
|||||||
{
|
{
|
||||||
if( ! _enabled && enabled ) {
|
if( ! _enabled && enabled ) {
|
||||||
engine->dynamicsWorld->addCollisionObject(_ghost, btBroadphaseProxy::SensorTrigger);
|
engine->dynamicsWorld->addCollisionObject(_ghost, btBroadphaseProxy::SensorTrigger);
|
||||||
|
corona->particle.size = glm::vec2(1.5f, 1.5f);
|
||||||
}
|
}
|
||||||
else if( _enabled && ! enabled ) {
|
else if( _enabled && ! enabled ) {
|
||||||
engine->dynamicsWorld->removeCollisionObject(_ghost);
|
engine->dynamicsWorld->removeCollisionObject(_ghost);
|
||||||
|
corona->particle.size = glm::vec2(0.f, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
_enabled = enabled;
|
_enabled = enabled;
|
||||||
|
@ -71,17 +71,17 @@ void ProjectileObject::explode()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tex = engine->gameData.findTexture("explo02")->getName();
|
auto tex = engine->gameData.findTexture("explo02");
|
||||||
|
|
||||||
/*engine->renderer.addParticle({
|
auto explosion = engine->createEffect(VisualFX::Particle);
|
||||||
position,
|
explosion->particle.size = glm::vec2(exp_size);
|
||||||
{0.f, 0.f, 1.f},
|
explosion->particle.texture = tex;
|
||||||
0.f,
|
explosion->particle.starttime = engine->gameTime;
|
||||||
GameRenderer::FXParticle::Camera,
|
explosion->particle.lifetime = 0.5f;
|
||||||
engine->gameTime, 0.5f,
|
explosion->particle.orientation = VisualFX::ParticleData::Camera;
|
||||||
tex,
|
explosion->particle.colour = glm::vec4(1.0f);
|
||||||
{exp_size, exp_size}
|
explosion->particle.position = getPosition();
|
||||||
});*/
|
explosion->particle.direction = glm::vec3(0.f, 0.f, 1.f);
|
||||||
|
|
||||||
_exploded = true;
|
_exploded = true;
|
||||||
engine->destroyObjectQueued(this);
|
engine->destroyObjectQueued(this);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
const size_t skydomeSegments = 8, skydomeRows = 10;
|
const size_t skydomeSegments = 8, skydomeRows = 10;
|
||||||
|
|
||||||
@ -100,16 +101,6 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
|||||||
renderer->setProgramBlockBinding(particleProg, "SceneData", 1);
|
renderer->setProgramBlockBinding(particleProg, "SceneData", 1);
|
||||||
renderer->setProgramBlockBinding(particleProg, "ObjectData", 2);
|
renderer->setProgramBlockBinding(particleProg, "ObjectData", 2);
|
||||||
|
|
||||||
particleProgram = compileProgram(GameShaders::WorldObject::VertexShader,
|
|
||||||
GameShaders::Particle::FragmentShader);
|
|
||||||
|
|
||||||
/*uniTexture = glGetUniformLocation(particleProgram, "texture");
|
|
||||||
ubiScene = glGetUniformBlockIndex(particleProgram, "SceneData");
|
|
||||||
ubiObject = glGetUniformBlockIndex(particleProgram, "ObjectData");*/
|
|
||||||
|
|
||||||
//glUniformBlockBinding(particleProgram, ubiScene, 1);
|
|
||||||
//glUniformBlockBinding(particleProgram, ubiObject, 2);
|
|
||||||
|
|
||||||
skyProg = renderer->createShader(
|
skyProg = renderer->createShader(
|
||||||
GameShaders::Sky::VertexShader,
|
GameShaders::Sky::VertexShader,
|
||||||
GameShaders::Sky::FragmentShader);
|
GameShaders::Sky::FragmentShader);
|
||||||
@ -204,6 +195,7 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
|||||||
{-0.5f,-0.5f, 0.f, 0.f, 1.f, 1.f, 1.f}
|
{-0.5f,-0.5f, 0.f, 0.f, 1.f, 1.f, 1.f}
|
||||||
});
|
});
|
||||||
particleDraw.addGeometry(&particleGeom);
|
particleDraw.addGeometry(&particleGeom);
|
||||||
|
particleDraw.setFaceType(GL_TRIANGLE_STRIP);
|
||||||
|
|
||||||
ssRectGeom.uploadVertices(sspaceRect);
|
ssRectGeom.uploadVertices(sspaceRect);
|
||||||
ssRectDraw.addGeometry(&ssRectGeom);
|
ssRectDraw.addGeometry(&ssRectGeom);
|
||||||
@ -485,7 +477,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
|
|||||||
|
|
||||||
renderer->draw(glm::mat4(), &skyDbuff, dp);
|
renderer->draw(glm::mat4(), &skyDbuff, dp);
|
||||||
|
|
||||||
renderParticles();
|
renderEffects();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
@ -997,47 +989,43 @@ void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::renderParticles()
|
void GameRenderer::renderEffects()
|
||||||
{
|
{
|
||||||
_particles.erase( std::remove_if(_particles.begin(), _particles.end(),
|
renderer->useProgram( particleProg );
|
||||||
[&](FXParticle& p) {
|
|
||||||
if ( ( engine->gameTime - p.starttime ) > p.lifetime ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
float t = engine->gameTime - p.starttime;
|
|
||||||
p._currentPosition = p.position + (p.direction * p.velocity) * t;
|
|
||||||
return false;
|
|
||||||
}), _particles.end() );
|
|
||||||
|
|
||||||
glUseProgram( particleProgram );
|
|
||||||
glBindVertexArray( particleDraw.getVAOName() );
|
|
||||||
|
|
||||||
auto cpos = _camera.position;
|
auto cpos = _camera.position;
|
||||||
auto cfwd = glm::normalize(glm::inverse(_camera.rotation) * glm::vec3(0.f, 1.f, 0.f));
|
auto cfwd = glm::normalize(glm::inverse(_camera.rotation) * glm::vec3(0.f, 1.f, 0.f));
|
||||||
|
|
||||||
|
auto& effects = engine->effects;
|
||||||
|
|
||||||
std::sort( _particles.begin(), _particles.end(),
|
std::sort( effects.begin(), effects.end(),
|
||||||
[&](const FXParticle& a, const FXParticle& b) {
|
[&](const VisualFX* a, const VisualFX* b) {
|
||||||
return glm::distance( a._currentPosition, cpos ) > glm::distance( b._currentPosition, cpos );
|
return glm::distance( a->getPosition(), cpos ) > glm::distance( b->getPosition(), cpos );
|
||||||
});
|
});
|
||||||
|
|
||||||
for(FXParticle& part : _particles) {
|
for(VisualFX* fx : effects) {
|
||||||
glBindTexture(GL_TEXTURE_2D, part.texture);
|
// Other effects not implemented yet
|
||||||
auto& p = part._currentPosition;
|
if( fx->getType() != VisualFX::Particle ) continue;
|
||||||
|
|
||||||
|
auto& particle = fx->particle;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, particle.texture->getName());
|
||||||
|
auto& p = particle.position;
|
||||||
|
|
||||||
glm::mat4 m(1.f);
|
glm::mat4 m(1.f);
|
||||||
|
|
||||||
// Figure the direction to the camera center.
|
// Figure the direction to the camera center.
|
||||||
auto amp = cpos - p;
|
auto amp = cpos - p;
|
||||||
glm::vec3 ptc = part.up;
|
glm::vec3 ptc = particle.up;
|
||||||
|
|
||||||
if( part.orientation == FXParticle::UpCamera ) {
|
if( particle.orientation == VisualFX::ParticleData::UpCamera ) {
|
||||||
ptc = glm::normalize(amp - (glm::dot(amp, cfwd))*cfwd);
|
ptc = glm::normalize(amp - (glm::dot(amp, cfwd))*cfwd);
|
||||||
}
|
}
|
||||||
else if( part.orientation == FXParticle::Camera ) {
|
else if( particle.orientation == VisualFX::ParticleData::Camera ) {
|
||||||
ptc = amp;
|
ptc = amp;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 f = glm::normalize(part.direction);
|
glm::vec3 f = glm::normalize(particle.direction);
|
||||||
glm::vec3 s = glm::cross(f, glm::normalize(ptc));
|
glm::vec3 s = glm::cross(f, glm::normalize(ptc));
|
||||||
glm::vec3 u = glm::cross(s, f);
|
glm::vec3 u = glm::cross(s, f);
|
||||||
m[0][0] = s.x;
|
m[0][0] = s.x;
|
||||||
@ -1052,16 +1040,19 @@ void GameRenderer::renderParticles()
|
|||||||
m[3][0] =-glm::dot(s, p);
|
m[3][0] =-glm::dot(s, p);
|
||||||
m[3][1] = glm::dot(f, p);
|
m[3][1] = glm::dot(f, p);
|
||||||
m[3][2] =-glm::dot(u, p);
|
m[3][2] =-glm::dot(u, p);
|
||||||
|
m = glm::scale(glm::inverse(m), glm::vec3(particle.size, 1.f));
|
||||||
|
|
||||||
m = glm::scale(glm::inverse(m), glm::vec3(part.size, 1.f));
|
//m = glm::translate(m, p);
|
||||||
/*uploadUBO<ObjectUniformData>(
|
|
||||||
uboObject, {
|
|
||||||
m,
|
|
||||||
part.colour,
|
|
||||||
1.f, 1.f, 1.f
|
|
||||||
});*/
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
Renderer::DrawParameters dp;
|
||||||
|
dp.texture = particle.texture->getName();
|
||||||
|
dp.ambient = 1.f;
|
||||||
|
dp.colour = glm::u8vec4(particle.colour * 255.f);
|
||||||
|
dp.start = 0;
|
||||||
|
dp.count = 4;
|
||||||
|
dp.diffuse = 1.f;
|
||||||
|
|
||||||
|
renderer->drawArrays(m, &particleDraw, dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1214,7 +1205,3 @@ void GameRenderer::renderLetterbox()
|
|||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::addParticle(const FXParticle &particle)
|
|
||||||
{
|
|
||||||
_particles.push_back(particle);
|
|
||||||
}
|
|
||||||
|
@ -224,7 +224,8 @@ void main()
|
|||||||
if(c.a <= ALPHA_DISCARD_THRESHOLD) discard;
|
if(c.a <= ALPHA_DISCARD_THRESHOLD) discard;
|
||||||
float fogZ = (gl_FragCoord.z / gl_FragCoord.w);
|
float fogZ = (gl_FragCoord.z / gl_FragCoord.w);
|
||||||
float fogfac = clamp( (fogStart-fogZ)/(fogEnd-fogStart), 0.0, 1.0 );
|
float fogfac = clamp( (fogStart-fogZ)/(fogEnd-fogStart), 0.0, 1.0 );
|
||||||
outColour = mix(ambient, c * colour * Colour, 1.f);
|
vec4 tint = vec4(colour.rgb, visibility);
|
||||||
|
outColour = c * tint;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
|
|
||||||
|
64
rwengine/src/render/VisualFX.cpp
Normal file
64
rwengine/src/render/VisualFX.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <render/VisualFX.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
VisualFX::LightData::~LightData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualFX::ParticleData::~ParticleData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualFX::TrailData::~TrailData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualFX::VisualFX(VisualFX::EffectType type)
|
||||||
|
: type(type)
|
||||||
|
{
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case VisualFX::Light:
|
||||||
|
new (&light) LightData;
|
||||||
|
break;
|
||||||
|
case VisualFX::Particle:
|
||||||
|
new (&particle) ParticleData;
|
||||||
|
break;
|
||||||
|
case VisualFX::Trail:
|
||||||
|
new (&trail) TrailData;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualFX::~VisualFX()
|
||||||
|
{
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case VisualFX::Light:
|
||||||
|
light.~LightData();
|
||||||
|
break;
|
||||||
|
case VisualFX::Particle:
|
||||||
|
particle.~ParticleData();
|
||||||
|
break;
|
||||||
|
case VisualFX::Trail:
|
||||||
|
trail.~TrailData();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::vec3& VisualFX::getPosition() const
|
||||||
|
{
|
||||||
|
static glm::vec3 errorRef;
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case VisualFX::Particle:
|
||||||
|
return particle.position;
|
||||||
|
default:
|
||||||
|
return errorRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
rwengine/tests/test_VisualFX.cpp
Normal file
15
rwengine/tests/test_VisualFX.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <test_globals.hpp>
|
||||||
|
#include <render/VisualFX.hpp>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(VisualFXTests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_light_data)
|
||||||
|
{
|
||||||
|
VisualFX fx(VisualFX::Light);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(fx.getType(), VisualFX::Light);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
@ -210,6 +210,22 @@ void RWGame::tick(float dt)
|
|||||||
}
|
}
|
||||||
clockAccumulator -= 1.f;
|
clockAccumulator -= 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up old VisualFX
|
||||||
|
for( int i = 0; i < engine->effects.size(); ++i )
|
||||||
|
{
|
||||||
|
VisualFX* effect = engine->effects[i];
|
||||||
|
if( effect->getType() == VisualFX::Particle )
|
||||||
|
{
|
||||||
|
auto& part = effect->particle;
|
||||||
|
if( part.lifetime < 0.f ) continue;
|
||||||
|
if( engine->gameTime >= part.starttime + part.lifetime )
|
||||||
|
{
|
||||||
|
engine->destroyEffect( effect );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for( GameObject* object : engine->objects ) {
|
for( GameObject* object : engine->objects ) {
|
||||||
object->_updateLastTransform();
|
object->_updateLastTransform();
|
||||||
|
Loading…
Reference in New Issue
Block a user