diff options
author | chai <chaifix@163.com> | 2018-11-18 22:32:55 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-11-18 22:32:55 +0800 |
commit | fc7b4579e49aaeecc81919e247e03f68bd5abfd4 (patch) | |
tree | 6547b8c7d3632591358267d06006eddc53216105 /src | |
parent | 3905924fc35f92e5092576c3f6e8fc5db7588cde (diff) |
*粒子系统
Diffstat (limited to 'src')
28 files changed, 691 insertions, 231 deletions
diff --git a/src/libjin/Audio/SDL/je_sdl_source.cpp b/src/libjin/Audio/SDL/je_sdl_source.cpp index 207aa86..d417bf7 100644 --- a/src/libjin/Audio/SDL/je_sdl_source.cpp +++ b/src/libjin/Audio/SDL/je_sdl_source.cpp @@ -69,10 +69,10 @@ namespace JinEngine #define Action Command::Action #define Manager SDLSourceManager - ///*class member*/ std::queue<Command*> Manager::commands; - ///*class member*/ std::stack<Command*> Manager::commandsPool; - ///*class member*/ std::vector<SDLSource*> Manager::sources; - /*class member*/ Manager* Manager::manager = nullptr; + //std::queue<Command*> Manager::commands; + //std::stack<Command*> Manager::commandsPool; + //std::vector<SDLSource*> Manager::sources; + Manager* Manager::manager = nullptr; SDLSource* SDLSource::createSource(const char* file) { diff --git a/src/libjin/Common/je_object.h b/src/libjin/Common/je_object.h index 1afbf67..fb8221f 100644 --- a/src/libjin/Common/je_object.h +++ b/src/libjin/Common/je_object.h @@ -9,8 +9,6 @@ namespace JinEngine /// class Object { - public: - }; } // namespace JinEngine diff --git a/src/libjin/Common/je_types.h b/src/libjin/Common/je_types.h index 448d7ac..e31ce5e 100644 --- a/src/libjin/Common/je_types.h +++ b/src/libjin/Common/je_types.h @@ -1,6 +1,8 @@ #ifndef __JE_TYPES_H__ #define __JE_TYPES_H__ #include <stdint.h> +#include <stdlib.h> +#include <cstring> namespace JinEngine { @@ -18,6 +20,15 @@ namespace JinEngine typedef uint32_t uint; typedef int32_t sint; +#define Union(name, ...) \ +union _Ctor{ \ + _Ctor() { memset(this, 0, sizeof(*this)); } \ + __VA_ARGS__; \ +} name; + +#define Struct(name, ...) \ +struct {__VA_ARGS__;} name; + } #endif
\ No newline at end of file diff --git a/src/libjin/Game/je_application.cpp b/src/libjin/Game/je_application.cpp index a5a8812..723a809 100644 --- a/src/libjin/Game/je_application.cpp +++ b/src/libjin/Game/je_application.cpp @@ -6,20 +6,21 @@ #include "../time/je_timer.h" #include "../input/je_event.h" #include "../graphics/je_window.h" +#include "../graphics/je_gl.h" #include "../math/je_math.h" #include "je_application.h" +using namespace JinEngine::Graphics; +using namespace JinEngine::Input; +using namespace JinEngine::Time; +using namespace JinEngine::Math; + namespace JinEngine { namespace Game { - using namespace JinEngine::Graphics; - using namespace JinEngine::Input; - using namespace JinEngine::Time; - using namespace JinEngine::Math; - Application::Application() :_running(true) {}; /* default game loop */ @@ -49,6 +50,7 @@ namespace JinEngine dt = current - previous; if (_onUpdate != nullptr) _onUpdate(dt); + glClear(GL_COLOR_BUFFER_BIT); if (_onDraw != nullptr) _onDraw(); wnd->swapBuffers(); diff --git a/src/libjin/Game/je_entity.h b/src/libjin/Game/je_entity.h index 39822b6..80c6ff3 100644 --- a/src/libjin/Game/je_entity.h +++ b/src/libjin/Game/je_entity.h @@ -7,7 +7,7 @@ namespace JinEngine { namespace Game { - +/* /// /// /// @@ -20,7 +20,7 @@ namespace JinEngine }; - +*/ } // namespace Game } // namespace JinEngine diff --git a/src/libjin/Game/je_gameobject.h b/src/libjin/Game/je_gameobject.h index fefc6df..7c6ec2b 100644 --- a/src/libjin/Game/je_gameobject.h +++ b/src/libjin/Game/je_gameobject.h @@ -16,7 +16,7 @@ namespace JinEngine { namespace Game { - + /* /// /// Game object base class. /// @@ -61,10 +61,7 @@ namespace JinEngine bool mIsVisible; // if the entity is visible or not bool mIsActive; // if the entity is joined into the logic - /// - /// Position of entity. - /// - Math::Vector2<float> mPosition; + Math::Transform mTransform; }; @@ -77,7 +74,7 @@ namespace JinEngine /// Entity set. For searching and keeps entities unique and sorted. /// typedef std::set<GameObject*> EntitySet; - + */ } // namespace Game } // namespace JinEngine diff --git a/src/libjin/Graphics/fonts/je_texture_font.cpp b/src/libjin/Graphics/fonts/je_texture_font.cpp index 868188e..3599c58 100644 --- a/src/libjin/Graphics/fonts/je_texture_font.cpp +++ b/src/libjin/Graphics/fonts/je_texture_font.cpp @@ -220,7 +220,7 @@ namespace JinEngine Shader* shader = Shader::getCurrentShader(); const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Matrix modelMatrix = gl.getModelViewMatrix(x, y, 0, 1, 1, 0, 0); + Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); shader->sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix); shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); for (int i = 0; i < glyphinfolist.size(); ++i) diff --git a/src/libjin/Graphics/fonts/je_ttf.cpp b/src/libjin/Graphics/fonts/je_ttf.cpp index 3cbb28b..1f79558 100644 --- a/src/libjin/Graphics/fonts/je_ttf.cpp +++ b/src/libjin/Graphics/fonts/je_ttf.cpp @@ -308,7 +308,7 @@ namespace JinEngine Shader* shader = Shader::getCurrentShader(); const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Matrix modelMatrix = gl.getModelViewMatrix(x, y, 0, 1, 1, 0, 0); + Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0); shader->sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix); shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix()); for (int i = 0; i < glyphinfolist.size(); ++i) diff --git a/src/libjin/Graphics/je_canvas.cpp b/src/libjin/Graphics/je_canvas.cpp index 491bf6b..8f216e6 100644 --- a/src/libjin/Graphics/je_canvas.cpp +++ b/src/libjin/Graphics/je_canvas.cpp @@ -10,10 +10,10 @@ namespace JinEngine namespace Graphics { - /*class member*/ const Canvas* Canvas::current = nullptr; - /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0); + const Canvas* Canvas::current = nullptr; + const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0); - /*class member*/ Canvas* Canvas::createCanvas(int w, int h) + Canvas* Canvas::createCanvas(int w, int h) { return new Canvas(w, h); } @@ -51,7 +51,7 @@ namespace JinEngine { } - /*class member*/ bool Canvas::isBinded(const Canvas* cvs) + bool Canvas::isBinded(const Canvas* cvs) { return current == cvs; } @@ -59,7 +59,7 @@ namespace JinEngine /** * bind to canvas */ - /*class member*/ void Canvas::bind(Canvas* canvas) + void Canvas::bind(Canvas* canvas) { if (isBinded(canvas)) return; current = canvas; @@ -77,7 +77,7 @@ namespace JinEngine * https://blog.csdn.net/liji_digital/article/details/79370841 * https://blog.csdn.net/lyx2007825/article/details/8792475 */ - /*class member*/ void Canvas::unbind() + void Canvas::unbind() { if (isBinded(DEFAULT_CANVAS)) return; current = DEFAULT_CANVAS; diff --git a/src/libjin/Graphics/je_gl.cpp b/src/libjin/Graphics/je_gl.cpp index f098f97..c58f0ac 100644 --- a/src/libjin/Graphics/je_gl.cpp +++ b/src/libjin/Graphics/je_gl.cpp @@ -15,7 +15,9 @@ namespace JinEngine : ogl2d::OpenGL() { mModelViewMatrices.push_back(Matrix()); - solve(); + mModelViewMatrix.setIdentity(); + for (Matrix& m : mModelViewMatrices) + mModelViewMatrix *= m; } void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a) @@ -51,11 +53,6 @@ namespace JinEngine if (mModelViewMatrices.size() == 1) return; mModelViewMatrices.pop_back(); - solve(); - } - - void OpenGL::solve() - { mModelViewMatrix.setIdentity(); for (Matrix& m : mModelViewMatrices) mModelViewMatrix *= m; @@ -91,10 +88,15 @@ namespace JinEngine Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy) { Matrix m; - m.setTransformation(x, y, sx, sy, r, ox, oy); + m.setTransformation(x, y, r, sx, sy, ox, oy); return mModelViewMatrix*m; } + Math::Matrix OpenGL::getModelViewMatrix(const Math::Transform& tansform) + { + return mModelViewMatrix * tansform.getMatrix(); + } + Matrix OpenGL::getModelViewMatrix() { return mModelViewMatrix; diff --git a/src/libjin/Graphics/je_gl.h b/src/libjin/Graphics/je_gl.h index fba62a1..134cfee 100644 --- a/src/libjin/Graphics/je_gl.h +++ b/src/libjin/Graphics/je_gl.h @@ -4,16 +4,22 @@ #include <vector> #include "../math/je_matrix.h" +#include "../math/je_transform.h" -#include "je_color.h" #include "GLee/GLee.h" #include "ogl/OpenGL.h" +#include "je_color.h" + namespace JinEngine { namespace Graphics { + /*class Canvas; + class Shader; + class Font; +*/ class OpenGL : public ogl2d::OpenGL { @@ -42,6 +48,11 @@ namespace JinEngine void pop(); /// + /// + /// + Math::Matrix getModelViewMatrix(const Math::Transform& tansform); + + /// /// Get model view matrix. /// Math::Matrix getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy); @@ -61,17 +72,63 @@ namespace JinEngine /// const Math::Matrix& getProjectionMatrix(); - private: + /// + /// + /// + void useShader(); - void solve(); + /// + /// + /// + void useFont(); - Color mCurrentColor; + /// + /// + /// + void useCanvas(); + + /// + /// + /// + void unUseShader(); + + private: + /// + /// + /// std::vector<Math::Matrix> mModelViewMatrices; + + /// + /// + /// Math::Matrix mModelViewMatrix; + /// + /// + /// Math::Matrix mProjectionMatrix; + /// + /// + /// + Color mCurrentColor; +/* + /// + /// + /// + Canvas* mCurrentCanvas; + + /// + /// + /// + Shader* mCurrentShader; + + /// + /// + /// + Font* mCurrentFont; +*/ }; // Singleton. diff --git a/src/libjin/Graphics/je_graphic.cpp b/src/libjin/Graphics/je_graphic.cpp index 0bb3fe1..552eac6 100644 --- a/src/libjin/Graphics/je_graphic.cpp +++ b/src/libjin/Graphics/je_graphic.cpp @@ -4,10 +4,12 @@ #include <stdlib.h> #include "../math/je_matrix.h" +#include "../math/je_vector2.hpp" #include "shaders/je_shader.h" #include "je_graphic.h" +using namespace JinEngine::Math; using namespace JinEngine::Graphics::Shaders; namespace JinEngine @@ -45,7 +47,7 @@ namespace JinEngine void Graphic::render(int x, int y, float sx, float sy, float r, float ox, float oy) const { - Math::Matrix modelMatrix = gl.getModelViewMatrix(x, y, r, sx, sy, ox, oy); + Math::Matrix modelMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy); int w = getWidth(), h = getHeight(); static float vertexCoords[8]; static float textureCoords[8]; @@ -91,7 +93,7 @@ namespace JinEngine textureCoords[4] = slx + slw; textureCoords[5] = sly + slh; textureCoords[6] = slx + slw; textureCoords[7] = sly; - Math::Matrix modelMatrix = gl.getModelViewMatrix(x, y, r, sx, sy, ax, ay); + Math::Matrix modelMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ax, ay); Shader* shader = Shader::getCurrentShader(); shader->sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix); @@ -104,6 +106,24 @@ namespace JinEngine gl.bindTexture(0); } + void Graphic::render(const Math::Transform& transform) const + { + Vector2<float> position = transform.getPosition(); + Vector2<float> origin = transform.getOrigin(); + Vector2<float> scale = transform.getScale(); + float angle = transform.getRotation(); + render(position.x, position.y, scale.x, scale.y, angle, origin.x, origin.y); + } + + void Graphic::render(const Math::Quad& slice, const Math::Transform& transform) const + { + Vector2<float> position = transform.getPosition(); + Vector2<float> origin = transform.getOrigin(); + Vector2<float> scale = transform.getScale(); + float angle = transform.getRotation(); + render(slice, position.x, position.y, scale.x, scale.y, angle, origin.x, origin.y); + } + //void Graphic::setFilter(GLint min, GLint max) //{ // glTexParameteri(GL_) diff --git a/src/libjin/Graphics/je_graphic.h b/src/libjin/Graphics/je_graphic.h index 91c8b44..51c8e3d 100644 --- a/src/libjin/Graphics/je_graphic.h +++ b/src/libjin/Graphics/je_graphic.h @@ -5,6 +5,7 @@ #include "../math/je_quad.h" #include "../math/je_vector2.hpp" +#include "../math/je_transform.h" #include "je_gl.h" #include "je_bitmap.h" @@ -67,6 +68,16 @@ namespace JinEngine /// void render(const Math::Quad& slice, int x, int y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const; + /// + /// Render with transform. + /// + void render(const Math::Transform& transform) const; + + /// + /// + /// + void render(const Math::Quad& slice, const Math::Transform& transform) const; + protected: Math::Vector2<uint> mSize; diff --git a/src/libjin/Graphics/je_sprite.cpp b/src/libjin/Graphics/je_sprite.cpp index 810cb0e..b92a2c2 100644 --- a/src/libjin/Graphics/je_sprite.cpp +++ b/src/libjin/Graphics/je_sprite.cpp @@ -11,9 +11,7 @@ namespace JinEngine { Sprite::Sprite() - : mShader(nullptr) - , mGraphic(nullptr) - , mScale(1, 1) + : mGraphic(nullptr) , mColor(255, 255, 255, 255) , mIsOriginEnum(false) { @@ -35,7 +33,7 @@ namespace JinEngine void Sprite::setRotation(float r) { - mRotation = r; + mTransform.setRotation(r); } void Sprite::setOrigin(Origin origin) @@ -49,58 +47,49 @@ namespace JinEngine switch (origin) { case TopLeft: - mOrigin.x = l; - mOrigin.y = t; + mTransform.setOrigin(1, t); break; case TopCenter: - mOrigin.x = r/2.f; - mOrigin.y = t; + mTransform.setOrigin(r / 2.f, t); break; case TopRight: - mOrigin.x = r; - mOrigin.y = t; + mTransform.setOrigin(r, t); break; case MiddleLeft: - mOrigin.x = l; - mOrigin.y = b/2.f; + mTransform.setOrigin(1, b / 2.f); break; case MiddleCenter: - mOrigin.x = r/2.f; - mOrigin.y = b/2.f; + mTransform.setOrigin(r / 2.f, b / 2.f); break; case MiddleRight: - mOrigin.x = r; - mOrigin.y = b/2.f; + mTransform.setOrigin(r, b / 2.f); break; case BottomLeft: - mOrigin.x = l; - mOrigin.y = b; + mTransform.setOrigin(l, b); break; case BottomCenter: - mOrigin.x = r/2.f; - mOrigin.y = b; + mTransform.setOrigin(r / 2.f, b); break; case BottomRight: - mOrigin.x = r; - mOrigin.y = b; + mTransform.setOrigin(r, b); break; } } void Sprite::setOrigin(int x, int y) { - mOrigin.set(x, y); + mTransform.setOrigin(x, y); mIsOriginEnum = false; } void Sprite::setPosition(float x, float y) { - mPosition.set(x, y); + mTransform.setPosition(x, y); } void Sprite::setScale(float x, float y) { - mScale.set(x, y); + mTransform.setScale(x, y); } void Sprite::setColor(Color color) @@ -108,11 +97,6 @@ namespace JinEngine mColor = color; } - void Sprite::setShader(Shader* shader) - { - mShader = shader; - } - void Sprite::setGraphic(const Graphic* graphic) { mGraphic = graphic; @@ -121,34 +105,27 @@ namespace JinEngine setQuad(0, 0, w, h); } - void Sprite::move(float x, float y) { - mPosition.x += x; - mPosition.y += y; + mTransform.move(x, y); } void Sprite::rotate(float r) { - mRotation += r; + mTransform.rotate(r); } void Sprite::scale(float sx, float sy) { - mScale.x += sx; - mScale.y += sy; + mTransform.scale(sx, sy); } void Sprite::render() { - Shader* shader = Shader::getCurrentShader(); Color c = gl.getColor(); gl.setColor(mColor); - if(mShader != nullptr) - mShader->use(); - if(mGraphic != nullptr) - mGraphic->render(mQuad, mPosition.x, mPosition.y, mScale.x, mScale.y, mRotation, mOrigin.x, mOrigin.y); - shader->use(); + if (mGraphic != nullptr) + mGraphic->render(mQuad, mTransform); gl.setColor(c); } diff --git a/src/libjin/Graphics/je_sprite.h b/src/libjin/Graphics/je_sprite.h index 65e00eb..faf16df 100644 --- a/src/libjin/Graphics/je_sprite.h +++ b/src/libjin/Graphics/je_sprite.h @@ -41,36 +41,29 @@ namespace JinEngine void setPosition(float x, float y); void setScale(float sx, float sy); void setColor(Color color); - void setShader(Shaders::Shader* shader); void setGraphic(const Graphic* graphic); void move(float x, float y); void rotate(float r); void scale(float sx, float sy); - float getRotation() { return mRotation; } + float getRotation() { return mTransform.getRotation(); } Math::Vector2<int> getSize() { return Math::Vector2<int>(mQuad.w, mQuad.h); } const Math::Quad& getQuad() { return mQuad; } - const Math::Vector2<float>& getPosition() { return mPosition; } - const Math::Vector2<int>& getOrigin() { return mOrigin; } - const Math::Vector2<float>& getScale() { return mScale; } + const Math::Vector2<float>& getPosition() { return mTransform.getPosition(); } + const Math::Vector2<float>& getOrigin() { return mTransform.getOrigin(); } + const Math::Vector2<float>& getScale() { return mTransform.getScale(); } const Color& getColor() { return mColor; } const Graphic* getGraphic() { return mGraphic; } - const Shaders::Shader* getShader() { return mShader; } - /// - /// Render callback. - /// - virtual void render(); + void render(); private: /// /// Origin must be 0~1 float value. /// - Math::Vector2<float> mPosition; - Math::Vector2<int> mOrigin; - Math::Vector2<float> mScale; - float mRotation; + Math::Transform mTransform; + Color mColor; Math::Quad mQuad; @@ -78,7 +71,6 @@ namespace JinEngine bool mIsOriginEnum; Origin mOriginEnum; - Shaders::Shader* mShader; const Graphic* mGraphic; }; diff --git a/src/libjin/Graphics/particles/je_particle.cpp b/src/libjin/Graphics/particles/je_particle.cpp index 20bbd03..53f4570 100644 --- a/src/libjin/Graphics/particles/je_particle.cpp +++ b/src/libjin/Graphics/particles/je_particle.cpp @@ -1,5 +1,9 @@ +#include "../../math/je_math.h" + #include "je_particle.h" +using namespace JinEngine::Math; + namespace JinEngine { namespace Graphics @@ -7,20 +11,62 @@ namespace JinEngine namespace Particles { + Particle::Particle(const Graphic* grc) + : graphic(grc) + { + reset(); + } + void Particle::reset() { - lifeTime = 0.0f; + transform.set(0, 0, 1, 1, 0, 0, 0); + lifeTime = 1.0f; life = 0.0f; - position.set(0, 0); - direction = 0.0f; speed.set(0, 0); linearAcceleration.set(0, 0); radialAcceleration = 0.0f; - size = 1; - sizeBegin = 1; + angularSpeed = 0; + scaleBegin = 1; + scaleEnd = 1; + color = Color::WHITE; + colorStart = Color::WHITE; + colorEnd = Color::WHITE; alive = true; } + void Particle::update(float dt) + { + float t = life / lifeTime; + // Lerp color + color.r = lerp<int>(colorStart.r, colorEnd.r, t); + color.g = lerp<int>(colorStart.g, colorEnd.g, t); + color.b = lerp<int>(colorStart.b, colorEnd.b, t); + color.a = lerp<int>(colorStart.a, colorEnd.a, t); + // Lerp scale. + Vector2<float> scale = transform.getScale(); + scale.x = lerp<float>(scaleBegin, scaleEnd, t); + scale.y = scale.x; + transform.setScale(scale.x, scale.y); + // Calculate position. + speed += linearAcceleration * dt; + transform.move(speed * dt); + // Calculate rotation. + angularSpeed += radialAcceleration * dt; + transform.rotate(angularSpeed * dt); + // Update life time. + life += dt; + alive = life < lifeTime; + } + + void Particle::render() + { + Color c = gl.getColor(); + gl.setColor(color); + if (graphic != nullptr) + graphic->render(transform); + gl.getColor(); + } + } } }
\ No newline at end of file diff --git a/src/libjin/Graphics/particles/je_particle.h b/src/libjin/Graphics/particles/je_particle.h index 2d112d1..70a2653 100644 --- a/src/libjin/Graphics/particles/je_particle.h +++ b/src/libjin/Graphics/particles/je_particle.h @@ -1,8 +1,10 @@ #ifndef __JE_PARTICLE_H__ #define __JE_PARTICLE_H__ +#include "../../math/je_transform.h" #include "../../math/je_vector2.hpp" #include "../je_color.h" +#include "../je_graphic.h" namespace JinEngine { @@ -19,56 +21,20 @@ namespace JinEngine struct LifeTimeDef { bool enableRandom = false; - union - { - struct - { - float min, max; - } random; - float life; - } life; - }; - - /// - /// - /// - struct SpeedOverTimeDef - { - bool enable = false; - bool enableRandom = false; - union - { + Struct(life, struct { - Math::Vector2<float> startFloor; - Math::Vector2<float> startCeil; - Math::Vector2<float> endFloor; - Math::Vector2<float> endCeil; + float floor, ceil; } random; - struct - { - Math::Vector2<float> start; - Math::Vector2<float> end; - } speed; - } speed; + float life = 1.0f; + ); }; - struct SizeOverTimeDef + struct ScaleOverTimeDef { bool enable = false; - bool enableRandom = false; - union { - struct { - float startFloor = 1; - float startCeil = 1; - float endFloor = 1; - float endCeil = 1; - } random; - struct { - float start = 1; - float end = 1; - } size; - } size; + float start = 1; + float end = 1; }; struct ColorOverTimeDef @@ -85,7 +51,20 @@ namespace JinEngine struct RadialAccelarationDef { - float radialAccelaration; + float radialAccelaration = 0.f; + }; + + struct AngularSpeedDef + { + bool enableRandom = false; + Struct(angularSpeed, + struct + { + float floor = 0; + float ceil = 0; + } random; + float angularSpeed = 0; + ); }; /// @@ -101,22 +80,22 @@ namespace JinEngine LifeTimeDef lifeTimeDef; ///< linearAccelarationDef linearAccelarationDef; ///< RadialAccelarationDef radialAccelarationDef; ///< + AngularSpeedDef angularSpeedDef; ///< // Optional definitions. - SpeedOverTimeDef speedOverTimeDef; ///< - SizeOverTimeDef sizeOverTimeDef; ///< + ScaleOverTimeDef sizeOverTimeDef; ///< ColorOverTimeDef colorOverTimeDef; ///< }; /// - /// A single particle contains various properties of particle, such as position, accelaration, color and - /// other attributes changed over time. + /// A single particle contains various properties of particle, such as position, accelaration, color + /// and other attributes changed over time. /// struct Particle { /// /// Default constructor. /// - Particle() {}; + Particle(const Graphic* graphic); /// /// Reset to default. @@ -124,45 +103,54 @@ namespace JinEngine void reset(); /// + /// + /// + void update(float dt); + + /// + /// + /// + void render(); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /// /// Whole life time. /// - float lifeTime = 0.0f; + float lifeTime = 1.0f; /// /// Current life time. /// float life = 0.0f; + const Graphic* graphic; + /// - /// Current position. + /// Color over lifetime. /// - Math::Vector2<float> position; + Color color = Color::WHITE; + Color colorStart = Color::WHITE; + Color colorEnd = Color::WHITE; /// - /// Emitte direction. - /// - float direction = 0; + /// Position scale rotation origin. + /// + Math::Transform transform; + /// + /// Speeds. + /// Math::Vector2<float> speed; Math::Vector2<float> linearAcceleration; + float angularSpeed; float radialAcceleration = 0; /// /// Size over lifetime. /// - float size = 1; - float sizeBegin = 1; - float sizeEnd = 1; - - float rotation = 0; - float angle = 0; - - /// - /// Color over lifetime. - /// - Color color = Color::WHITE; - Color colorStart = Color::WHITE; - Color colorEnd = Color::WHITE; + float scaleBegin = 1; + float scaleEnd = 1; /// /// Is particle still alive? Alive is equivalent to NOT available in particle pool. diff --git a/src/libjin/Graphics/particles/je_particle_emitter.cpp b/src/libjin/Graphics/particles/je_particle_emitter.cpp index edc4bee..d8fb78d 100644 --- a/src/libjin/Graphics/particles/je_particle_emitter.cpp +++ b/src/libjin/Graphics/particles/je_particle_emitter.cpp @@ -3,6 +3,7 @@ #include "../../math/je_random.h" #include "je_particle_emitter.h" +#include "je_particle_system.h" using namespace JinEngine::Math; @@ -13,28 +14,90 @@ namespace JinEngine namespace Particles { + static const uint8 ACCURACY_4 = 4; + static const uint8 ACCURACY_5 = 5; + static const uint8 ACCURACY_6 = 6; + // Particle emitter - static RandomGenerator rnd(time(NULL)); + static RandomGenerator rng(0xEA44944); ParticleEmitter::ParticleEmitter(ParticleSystem& ps) - : mParticleSystem(ps) + : mPS(ps) + , mDef(ps.mDef.emitterDef) + , mPDef(ps.mDef.particleDef) + , mTime(0) { } void ParticleEmitter::update(float dt) { mTime += dt; - if (mTime < 1) - return; - - - mTime -= 1; + for (;mTime >= mInterval; mTime -= mInterval) + { + emit(); + // Random rate. + if (mDef.emitRateDef.enableRandom) + mInterval = rng.randf(mDef.emitRateDef.rate.random.floor, mDef.emitRateDef.rate.random.ceil, ACCURACY_5); + else + mInterval = mDef.emitRateDef.rate.rate; + } } void ParticleEmitter::emit() { - - + Particle* p = mPS.claim(); + if (p == nullptr) + return; + p->reset(); + // Init position. + if (mDef.positionDef.enableRandom) + { + float x = rng.randf(mDef.positionDef.position.random.floor.x, mDef.positionDef.position.random.ceil.x, ACCURACY_4); + float y = rng.randf(mDef.positionDef.position.random.floor.y, mDef.positionDef.position.random.ceil.y, ACCURACY_4); + p->transform.setPosition(x, y); + } + else + { + p->transform.setPosition(mDef.positionDef.position.position); + } + // Init speed. + float r = 0; + if (mDef.directionDef.enableRandom) + r = rng.randf(mDef.directionDef.direction.random.floor, mDef.directionDef.direction.random.ceil, ACCURACY_4); + else + r = mDef.directionDef.direction.direction; + float f = 0; + if (mDef.forceDef.enableRandom) + f = rng.randf(mDef.forceDef.force.random.floor, mDef.forceDef.force.random.ceil, ACCURACY_4); + else + f = mDef.forceDef.force.force; + p->speed.set(f*cos(r), f*sin(r)); + // Init life time + if (mPDef.lifeTimeDef.enableRandom) + p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.floor, ACCURACY_4); + else + p->lifeTime = mPDef.lifeTimeDef.life.life; + // Init linear accelaration + p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration; + // Init angular accelaration + p->radialAcceleration = mPDef.radialAccelarationDef.radialAccelaration; + // Init Angular speed. + if (mPDef.angularSpeedDef.enableRandom) + p->angularSpeed = rng.randf(mPDef.angularSpeedDef.angularSpeed.random.floor, mPDef.angularSpeedDef.angularSpeed.random.ceil, ACCURACY_4); + else + p->angularSpeed = mPDef.angularSpeedDef.angularSpeed.angularSpeed; + // Scale over time + if (mPDef.sizeOverTimeDef.enable) + { + p->scaleBegin = mPDef.sizeOverTimeDef.start; + p->scaleEnd = mPDef.sizeOverTimeDef.end; + } + // Color over time + if (mPDef.colorOverTimeDef.enable) + { + p->colorStart = mPDef.colorOverTimeDef.colorStart; + p->colorEnd = mPDef.colorOverTimeDef.colorEnd; + } } } diff --git a/src/libjin/Graphics/particles/je_particle_emitter.h b/src/libjin/Graphics/particles/je_particle_emitter.h index 9200532..44bd1fb 100644 --- a/src/libjin/Graphics/particles/je_particle_emitter.h +++ b/src/libjin/Graphics/particles/je_particle_emitter.h @@ -16,29 +16,27 @@ namespace JinEngine struct PositionDef { bool enableRandom = false; - union - { + Struct(position, struct { - Math::Vector2<float> min; - Math::Vector2<float> max; + Math::Vector2<float> floor; + Math::Vector2<float> ceil; } random; Math::Vector2<float> position; - } position; + ); }; struct DirectionDef { bool enableRandom = false; - union - { + Struct(direction, struct { - float min = 0; - float max = 0; + float floor = 0; + float ceil = 0; } random; float direction = 0; - } direction; + ); }; /// @@ -47,25 +45,42 @@ namespace JinEngine struct EmitRateDef { bool enableRandom = false; - union - { + Struct(rate, struct { - float min = 1; - float max = 1; + float floor = 1; + float ceil = 1; } random; float rate = 1; - } rate; + ); + }; + + /// + /// Initial speed of particle. + /// + struct ForceDef + { + bool enableRandom = false; + Struct(force, + struct + { + float floor = 1; + float ceil = 1; + } random; + float force = 1; + ); }; /// /// Definition of particle emitter. /// - struct ParticleEmitterDef : public Temporary + struct ParticleEmitterDef { + EmitRateDef emitRateDef; ///< Emit rate. + PositionDef positionDef; ///< Emit position(relativily to the particle system center). DirectionDef directionDef; ///< Emit direction. - EmitRateDef emitRateDef; ///< Emit rate. + ForceDef forceDef; ///< Emit force. }; class ParticleSystem; @@ -90,10 +105,14 @@ namespace JinEngine /// /// /// - ParticleSystem& mParticleSystem; + ParticleSystem& mPS; + + const ParticleEmitterDef& mDef; + + const ParticleDef& mPDef; /// - /// Emit a particle according to emitter definition and particle definition, particle system should + /// Emit particle according to emitter definition and particle definition, particle system should /// assign particle value to the particle in particle pool, but not use this return particle. /// void emit(); @@ -103,6 +122,11 @@ namespace JinEngine /// float mTime; + /// + /// + /// + float mInterval; + }; } // namespace Particles diff --git a/src/libjin/Graphics/particles/je_particle_system.cpp b/src/libjin/Graphics/particles/je_particle_system.cpp index 68f8f21..a81a3c9 100644 --- a/src/libjin/Graphics/particles/je_particle_system.cpp +++ b/src/libjin/Graphics/particles/je_particle_system.cpp @@ -4,8 +4,64 @@ namespace JinEngine { namespace Graphics { + namespace Particles + { + ParticleSystem::ParticleSystem(const ParticleSystemDef& def) + : mDef(def) + , mEmitter(*this) + , mParticlePool(def.maxParticleCount, sizeof(Particle)) + { + } + ParticleSystem::~ParticleSystem() + { + } + void ParticleSystem::update(float dt) + { + mEmitter.update(dt); + for (int i = 0; i < mAliveParticles.size(); ++i) + { + Particle* p = mAliveParticles[i]; + if (p->alive == false) + { + recycle(i, p); + --i; + } + else + { + p->update(dt); + } + } + } + + void ParticleSystem::render(float x, float y, float sx /* = 1 */, float sy /* = 1 */, float r /* = 0 */, float ax /* = 0 */, float ay /* = 0 */) + { + for (Particle* p : mAliveParticles) + p->render(); + } + + void ParticleSystem::setGraphic(const Graphic* graphic) + { + mGraphic = graphic; + } + + Particle* ParticleSystem::claim() + { + Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle(mGraphic); + mAliveParticles.push_back(p); + return p; + } + + void ParticleSystem::recycle(int i, Particle* p) + { + if (i >= mAliveParticles.size()) + return; + mAliveParticles.erase(mAliveParticles.begin() + i); + mParticlePool.Delete(p); + } + + } } -} +}
\ No newline at end of file diff --git a/src/libjin/Graphics/particles/je_particle_system.h b/src/libjin/Graphics/particles/je_particle_system.h index afa96b2..8ee79ec 100644 --- a/src/libjin/Graphics/particles/je_particle_system.h +++ b/src/libjin/Graphics/particles/je_particle_system.h @@ -22,10 +22,10 @@ namespace JinEngine /// /// Definition of particle system. /// - struct ParticleSystemDef : public Temporary + struct ParticleSystemDef { + ParticleSystemDef() {} uint maxParticleCount = 1; ///< Max count of particles in pool. 1 by default. - ParticleEmitterDef emitterDef; ///< Particle emitter definition. ParticleDef particleDef; ///< Particle definition. }; @@ -33,7 +33,7 @@ namespace JinEngine /// /// Particle emitter, handle all particles it emitts. /// - class ParticleSystem : public Game::GameObject + class ParticleSystem/* : public Game::GameObject*/ { public: /// @@ -51,25 +51,37 @@ namespace JinEngine /// /// Update particle system and all alive particles. /// - void update(float sec); + void update(float dt); /// /// Render particle system. /// - void render(int x, int y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); + void render(float x, float y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); /// /// Set sprite to render. /// /// @param sprite Sprite to render. /// - void setSprite(Sprite* sprite); + void setGraphic(const Graphic* graphic); private: - // Disable default constructor. + + friend class ParticleEmitter; + ParticleSystem(); /// + /// + /// + Particle* claim(); + + /// + /// + /// + void recycle(int i, Particle* p); + + /// /// Particle system definition. /// ParticleSystemDef mDef; @@ -77,7 +89,7 @@ namespace JinEngine /// /// Sprite to be drawn. /// - Sprite* mSprite; + const Graphic* mGraphic; /// /// Particle emitter. diff --git a/src/libjin/Math/je_random.cpp b/src/libjin/Math/je_random.cpp index 983fa36..216fd79 100644 --- a/src/libjin/Math/je_random.cpp +++ b/src/libjin/Math/je_random.cpp @@ -1,3 +1,4 @@ +#include <math.h> #include "je_random.h" namespace JinEngine @@ -5,9 +6,47 @@ namespace JinEngine namespace Math { - RandomGenerator::RandomGenerator() + RandomGenerator::RandomGenerator(uint32 seed) + : mSeed(seed) { } + uint32 RandomGenerator::rand() + { + unsigned int next = mSeed; + uint32 result; + + next *= 1103515245; + next += 12345; + result = (unsigned int)(next / 65536) % 2048; + + next *= 1103515245; + next += 12345; + result <<= 10; + result ^= (unsigned int)(next / 65536) % 1024; + + next *= 1103515245; + next += 12345; + result <<= 10; + result ^= (unsigned int)(next / 65536) % 1024; + + mSeed = next; + + return result; + } + + uint32 RandomGenerator::rand(uint32 min, uint32 max) + { + uint32 n = rand(); + return n % (max - min + 1) + min; + } + + float RandomGenerator::randf(float min, float max, int ac) + { + uint32 a = pow(10.f, ac); + uint32 n = rand(min*a, max*a); + return (float)n / a; + } + } }
\ No newline at end of file diff --git a/src/libjin/Math/je_random.h b/src/libjin/Math/je_random.h index 0bcdec7..0f53155 100644 --- a/src/libjin/Math/je_random.h +++ b/src/libjin/Math/je_random.h @@ -14,11 +14,16 @@ namespace JinEngine class RandomGenerator { public: - RandomGenerator(); - explicit RandomGenerator(uint32 seed); + RandomGenerator(uint32 seed); + + uint32 rand(); uint32 rand(uint32 min, uint32 max); - float rand(float min, float max); + + float randf(float min, float max, int ac); + + private: + uint32 mSeed; }; diff --git a/src/libjin/Math/je_transform.cpp b/src/libjin/Math/je_transform.cpp new file mode 100644 index 0000000..c0676cb --- /dev/null +++ b/src/libjin/Math/je_transform.cpp @@ -0,0 +1,99 @@ +#include "je_transform.h" + +namespace JinEngine +{ + namespace Math + { + + Transform::Transform() + : mScale(1, 1) + , mPosition(0, 0) + , mOrigin(0, 0) + , mRotation(0) + { + } + + void Transform::set(float x, float y, float sx, float sy, float r, float ox, float oy) + { + setPosition(x, y); + setScale(sx, sy); + setRotation(r); + setOrigin(ox, oy); + } + + void Transform::setScale(float sx, float sy) + { + mScale.set(sx, sy); + } + + Vector2<float> Transform::getScale() const + { + return mScale; + } + + void Transform::scale(float sx, float sy) + { + mScale.x *= sx; + mScale.y *= sy; + } + + void Transform::setPosition(const Vector2<float>& p) + { + setPosition(p.x, p.y); + } + + void Transform::setPosition(float x, float y) + { + mPosition.set(x, y); + } + + Vector2<float> Transform::getPosition() const + { + return mPosition; + } + + void Transform::move(float x, float y) + { + mPosition.x += x; + mPosition.y += y; + } + + void Transform::move(const Vector2<float>& v) + { + move(v.x, v.y); + } + + void Transform::setOrigin(float x, float y) + { + mOrigin.set(x, y); + } + + Vector2<float> Transform::getOrigin() const + { + return mOrigin; + } + + void Transform::setRotation(float r) + { + mRotation = r; + } + + float Transform::getRotation() const + { + return mRotation; + } + + void Transform::rotate(float r) + { + mRotation += r; + } + + Matrix Transform::getMatrix() const + { + Matrix m; + m.setTransformation(mPosition.x, mPosition.y, mRotation, mScale.x, mScale.y, mOrigin.x, mOrigin.y); + return m; + } + + } +}
\ No newline at end of file diff --git a/src/libjin/Math/je_transform.h b/src/libjin/Math/je_transform.h new file mode 100644 index 0000000..cb1f0ee --- /dev/null +++ b/src/libjin/Math/je_transform.h @@ -0,0 +1,49 @@ +#ifndef __JE_TRANSFORM_H__ +#define __JE_TRANSFORM_H__ + +#include "je_matrix.h" +#include "je_vector2.hpp" + +namespace JinEngine +{ + namespace Math + { + + class Transform + { + public: + Transform(); + + void set(float x, float y, float sx, float sy, float r, float ox, float oy); + + void setScale(float sx, float sy); + Vector2<float> getScale() const; + void scale(float sx, float sy); + + void setPosition(float x, float y); + void setPosition(const Vector2<float>& p); + Vector2<float> getPosition() const; + void move(float x, float y); + void move(const Vector2<float>& v); + + void setOrigin(float x, float y); + Vector2<float> getOrigin() const; + + void setRotation(float r); + float getRotation() const; + void rotate(float r); + + Matrix getMatrix() const; + + private: + Vector2<float> mScale; + Vector2<float> mPosition; + Vector2<float> mOrigin; + float mRotation; + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/src/libjin/Math/je_vector2.hpp b/src/libjin/Math/je_vector2.hpp index e9599e1..b4cab44 100644 --- a/src/libjin/Math/je_vector2.hpp +++ b/src/libjin/Math/je_vector2.hpp @@ -31,6 +31,17 @@ namespace JinEngine data[1] = v.data[1]; } + Vector2<T> operator * (float n) + { + return Vector2<T>(data[0]*n, data[1]*n); + } + + void operator +=(const Vector2<T> v) + { + data[0] += v.data[0]; + data[1] += v.data[1]; + } + void set(T _x, T _y) { data[0] = _x; diff --git a/src/lua/modules/graphics/je_lua_graphics.cpp b/src/lua/modules/graphics/je_lua_graphics.cpp index ce569d0..900b26b 100644 --- a/src/lua/modules/graphics/je_lua_graphics.cpp +++ b/src/lua/modules/graphics/je_lua_graphics.cpp @@ -17,6 +17,7 @@ #include "je_lua_text.h" #include "je_lua_texture_font.h" #include "je_lua_page.h" +#include "je_lua_sprite.h" using namespace std; using namespace JinEngine; @@ -385,16 +386,27 @@ namespace JinEngine font->render(page, x, y); } + LUA_IMPLEMENT void l_draw_sprite(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Sprite)) + return; + Proxy* pxySprite = (Proxy*)luax_toudata(L, 1); + Sprite* spr = pxySprite->getObject<Sprite>(); + spr->render(); + } + LUA_IMPLEMENT int l_draw(lua_State* L) { - if (luax_istype(L, 1, Jin_Lua_Texture)) - l_draw_texture(L); - else if (luax_istype(L, 1, Jin_Lua_Canvas)) - l_draw_canvas(L); - else if (luax_istype(L, 1, Jin_Lua_Text)) - l_draw_text(L); - else if (luax_istype(L, 1, Jin_Lua_Page)) - l_draw_page(L); + if (luax_istype(L, 1, Jin_Lua_Texture)) + l_draw_texture(L); + else if (luax_istype(L, 1, Jin_Lua_Canvas)) + l_draw_canvas(L); + else if (luax_istype(L, 1, Jin_Lua_Text)) + l_draw_text(L); + else if (luax_istype(L, 1, Jin_Lua_Page)) + l_draw_page(L); + else if (luax_istype(L, 1, Jin_Lua_Sprite)) + l_draw_sprite(L); else { luax_typerror(L, 1, "texture or canvas"); diff --git a/src/lua/modules/graphics/je_lua_sprite.cpp b/src/lua/modules/graphics/je_lua_sprite.cpp index 97128a9..76d6c1f 100644 --- a/src/lua/modules/graphics/je_lua_sprite.cpp +++ b/src/lua/modules/graphics/je_lua_sprite.cpp @@ -91,16 +91,6 @@ namespace JinEngine return 0; } - LUA_IMPLEMENT int l_setShader(lua_State* L) - { - SharedSprite sprite = checkSprite(L); - Proxy* proxy = (Proxy*)luax_checktype(L, 2, Jin_Lua_Shader); - Shader* shader = proxy->getObject<Shader>(); - sprite->setShader(shader); - sprite.setDependency((int)SpriteDependency::DEP_SHADER, &proxy->getShared<Shader>()); - return 0; - } - LUA_IMPLEMENT int l_setGraphic(lua_State* L) { SharedSprite sprite = checkSprite(L); @@ -164,7 +154,7 @@ namespace JinEngine LUA_IMPLEMENT int l_getOrigin(lua_State* L) { SharedSprite sprite = checkSprite(L); - const Math::Vector2<int>& origin = sprite->getOrigin(); + const Math::Vector2<float>& origin = sprite->getOrigin(); luax_pushinteger(L, origin.x); luax_pushinteger(L, origin.y); return 2; @@ -241,7 +231,6 @@ namespace JinEngine { "setPosition", l_setPosition }, { "setScale", l_setScale }, { "setColor", l_setColor }, - { "setShader", l_setShader }, { "setGraphic", l_setGraphic }, { "move", l_move }, { "scale", l_scale }, |