aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/graphics')
-rw-r--r--src/libjin/graphics/animations/animation.cpp94
-rw-r--r--src/libjin/graphics/animations/animation.h62
-rw-r--r--src/libjin/graphics/animations/animator.cpp240
-rw-r--r--src/libjin/graphics/animations/animator.h64
-rw-r--r--src/libjin/graphics/bitmap.cpp348
-rw-r--r--src/libjin/graphics/bitmap.h288
-rw-r--r--src/libjin/graphics/canvas.cpp92
-rw-r--r--src/libjin/graphics/canvas.h78
-rw-r--r--src/libjin/graphics/color.cpp28
-rw-r--r--src/libjin/graphics/color.h198
-rw-r--r--src/libjin/graphics/fonts/decoder.cpp162
-rw-r--r--src/libjin/graphics/fonts/decoder.h170
-rw-r--r--src/libjin/graphics/fonts/font.h204
-rw-r--r--src/libjin/graphics/fonts/page.h84
-rw-r--r--src/libjin/graphics/fonts/text.cpp298
-rw-r--r--src/libjin/graphics/fonts/text.h324
-rw-r--r--src/libjin/graphics/fonts/texture_font.cpp548
-rw-r--r--src/libjin/graphics/fonts/texture_font.h222
-rw-r--r--src/libjin/graphics/fonts/ttf.cpp858
-rw-r--r--src/libjin/graphics/fonts/ttf.h520
-rw-r--r--src/libjin/graphics/graphic.cpp252
-rw-r--r--src/libjin/graphics/graphic.h152
-rw-r--r--src/libjin/graphics/image.cpp78
-rw-r--r--src/libjin/graphics/image.h74
-rw-r--r--src/libjin/graphics/mesh.cpp114
-rw-r--r--src/libjin/graphics/mesh.h74
-rw-r--r--src/libjin/graphics/opengl.cpp784
-rw-r--r--src/libjin/graphics/opengl.h412
-rw-r--r--src/libjin/graphics/particles/particle.cpp352
-rw-r--r--src/libjin/graphics/particles/particle.h410
-rw-r--r--src/libjin/graphics/particles/particle_emitter.cpp200
-rw-r--r--src/libjin/graphics/particles/particle_emitter.h246
-rw-r--r--src/libjin/graphics/particles/particle_pool.h20
-rw-r--r--src/libjin/graphics/particles/particle_system.cpp514
-rw-r--r--src/libjin/graphics/particles/particle_system.h334
-rw-r--r--src/libjin/graphics/renderable.h66
-rw-r--r--src/libjin/graphics/shaders/built-in/default.shader.h4
-rw-r--r--src/libjin/graphics/shaders/built-in/font.shader.h4
-rw-r--r--src/libjin/graphics/shaders/built-in/texture.shader.h4
-rw-r--r--src/libjin/graphics/shaders/jsl_compiler.cpp268
-rw-r--r--src/libjin/graphics/shaders/jsl_compiler.h78
-rw-r--r--src/libjin/graphics/shaders/shader.cpp592
-rw-r--r--src/libjin/graphics/shaders/shader.h360
-rw-r--r--src/libjin/graphics/shapes.cpp260
-rw-r--r--src/libjin/graphics/shapes.h30
-rw-r--r--src/libjin/graphics/sprite.cpp154
-rw-r--r--src/libjin/graphics/sprite.h50
-rw-r--r--src/libjin/graphics/sprite_batch.cpp6
-rw-r--r--src/libjin/graphics/sprite_batch.h20
-rw-r--r--src/libjin/graphics/sprite_sheet.cpp122
-rw-r--r--src/libjin/graphics/sprite_sheet.h46
-rw-r--r--src/libjin/graphics/texture.cpp56
-rw-r--r--src/libjin/graphics/texture.h64
-rw-r--r--src/libjin/graphics/vertex.h18
-rw-r--r--src/libjin/graphics/window.cpp200
-rw-r--r--src/libjin/graphics/window.h176
56 files changed, 5738 insertions, 5738 deletions
diff --git a/src/libjin/graphics/animations/animation.cpp b/src/libjin/graphics/animations/animation.cpp
index 168c3e3..3eb67c0 100644
--- a/src/libjin/graphics/animations/animation.cpp
+++ b/src/libjin/graphics/animations/animation.cpp
@@ -5,61 +5,61 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Animations
- {
+ namespace Graphics
+ {
+ namespace Animations
+ {
- Animation::Animation()
- : mLoop(true)
- {
- }
+ Animation::Animation()
+ : mLoop(true)
+ {
+ }
- void Animation::addFrame(const Sprite* frame)
- {
- if(frame != nullptr)
- mFrames.push_back(frame);
- }
+ void Animation::addFrame(const Sprite* frame)
+ {
+ if(frame != nullptr)
+ mFrames.push_back(frame);
+ }
- void Animation::addFrames(const std::vector<Sprite*>& frames)
- {
- mFrames.insert(mFrames.end(), frames.begin(), frames.end());
- }
+ void Animation::addFrames(const std::vector<Sprite*>& frames)
+ {
+ mFrames.insert(mFrames.end(), frames.begin(), frames.end());
+ }
- void Animation::setSpeed(float speed)
- {
- mSpeed = speed;
- }
+ void Animation::setSpeed(float speed)
+ {
+ mSpeed = speed;
+ }
- void Animation::setLoop(bool loop)
- {
- mLoop = loop;
- }
+ void Animation::setLoop(bool loop)
+ {
+ mLoop = loop;
+ }
- const Sprite* Animation::getFrame(uint index) const
- {
- if (mFrames.size() == 0)
- return nullptr;
- if (without<uint>(index, 0, mFrames.size() - 1))
- return nullptr;
- return mFrames[index];
- }
+ const Sprite* Animation::getFrame(uint index) const
+ {
+ if (mFrames.size() == 0)
+ return nullptr;
+ if (without<uint>(index, 0, mFrames.size() - 1))
+ return nullptr;
+ return mFrames[index];
+ }
- uint Animation::getFrameCount() const
- {
- return mFrames.size();
- }
+ uint Animation::getFrameCount() const
+ {
+ return mFrames.size();
+ }
- bool Animation::isLoop() const
- {
- return mLoop;
- }
+ bool Animation::isLoop() const
+ {
+ return mLoop;
+ }
- float Animation::getSpeed() const
- {
- return mSpeed;
- }
+ float Animation::getSpeed() const
+ {
+ return mSpeed;
+ }
- }
- }
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/animations/animation.h b/src/libjin/graphics/animations/animation.h
index 72565fc..f48ff33 100644
--- a/src/libjin/graphics/animations/animation.h
+++ b/src/libjin/graphics/animations/animation.h
@@ -10,50 +10,50 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Animations
- {
+ namespace Graphics
+ {
+ namespace Animations
+ {
- ///
- /// Animation clip with key.
- ///
- class Animation : public Object
- {
- public:
- Animation();
-
- void addFrame(const Sprite* frame);
+ ///
+ /// Animation clip with key.
+ ///
+ class Animation : public Object
+ {
+ public:
+ Animation();
+
+ void addFrame(const Sprite* frame);
- void addFrames(const std::vector<Sprite*>& frames);
+ void addFrames(const std::vector<Sprite*>& frames);
- void setLoop(bool loop);
+ void setLoop(bool loop);
- void setSpeed(float speed);
+ void setSpeed(float speed);
- bool isLoop() const;
+ bool isLoop() const;
- float getSpeed() const;
+ float getSpeed() const;
- uint getFrameCount() const;
+ uint getFrameCount() const;
- const Sprite* getFrame(uint index) const;
+ const Sprite* getFrame(uint index) const;
- private:
+ private:
- std::vector<const Sprite*> mFrames;
+ std::vector<const Sprite*> mFrames;
- ///
- /// Frame per second.
- ///
- float mSpeed;
+ ///
+ /// Frame per second.
+ ///
+ float mSpeed;
- float mLoop;
-
- };
+ float mLoop;
+
+ };
- } // namespace Animations
- } // namespace Graphics
+ } // namespace Animations
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/animations/animator.cpp b/src/libjin/graphics/animations/animator.cpp
index 8db3bc2..d3fac8b 100644
--- a/src/libjin/graphics/animations/animator.cpp
+++ b/src/libjin/graphics/animations/animator.cpp
@@ -5,124 +5,124 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Animations
- {
-
- Animator::Animator()
- : mIndex(0)
- , mTick(0)
- , mIsActive(true)
- {
- }
-
- void Animator::setAnimation(const Animation* anim)
- {
- mAnimation = anim;
- if (mAnimation)
- {
- mSpeed = mAnimation->getSpeed();
- mLoop = mAnimation->isLoop();
- }
- }
-
- void Animator::play()
- {
- mIndex = 0;
- mIsActive = true;
- mTick = 0;
- }
-
- void Animator::pause()
- {
- mIsActive = false;
- }
-
- void Animator::resume()
- {
- mIsActive = true;
- }
-
- void Animator::update(float dt)
- {
- if (!mIsActive || !mAnimation)
- return;
- float interval = 1 / mSpeed;
- mTick += dt;
- uint fc = mAnimation->getFrameCount();
- if (mTick >= interval)
- {
- mIndex += int(mTick / interval);
- mTick = fmod(mTick, interval);
- if (mLoop)
- mIndex %= fc;
- mIndex = clamp<uint>(mIndex, 0, fc - 1);
- }
- }
-
- void Animator::rewind()
- {
- mIndex = 0;
- }
-
- void Animator::render(float x, float y, float sx, float sy, float r) const
- {
- if (!mAnimation)
- return;
- const Sprite* spr = mAnimation->getFrame(mIndex);
- if (spr)
- spr->render(x, y, sx, sy, r);
- }
-
- void Animator::forceToFrame(uint index)
- {
- mIndex = index;
-
- }
-
- void Animator::setSpeed(float speed)
- {
- mSpeed = speed;
- }
-
- void Animator::setDefaultSpeed()
- {
- if(mAnimation != nullptr)
- mSpeed = mAnimation->getSpeed();
- else
- {
- jin_log_error("Animation is null.");
- return;
- }
- }
-
- void Animator::setLoop(bool loop)
- {
- mLoop = loop;
- }
-
- void Animator::setDefaultLoop()
- {
- if(mAnimation != nullptr)
- mLoop = mAnimation->isLoop();
- else
- {
- jin_log_error("Animation is null.");
- return;
- }
- }
-
- float Animator::getSpeed()
- {
- return mSpeed;
- }
-
- uint Animator::getFrameCount()
- {
- return mAnimation->getFrameCount();
- }
-
- }
- }
+ namespace Graphics
+ {
+ namespace Animations
+ {
+
+ Animator::Animator()
+ : mIndex(0)
+ , mTick(0)
+ , mIsActive(true)
+ {
+ }
+
+ void Animator::setAnimation(const Animation* anim)
+ {
+ mAnimation = anim;
+ if (mAnimation)
+ {
+ mSpeed = mAnimation->getSpeed();
+ mLoop = mAnimation->isLoop();
+ }
+ }
+
+ void Animator::play()
+ {
+ mIndex = 0;
+ mIsActive = true;
+ mTick = 0;
+ }
+
+ void Animator::pause()
+ {
+ mIsActive = false;
+ }
+
+ void Animator::resume()
+ {
+ mIsActive = true;
+ }
+
+ void Animator::update(float dt)
+ {
+ if (!mIsActive || !mAnimation)
+ return;
+ float interval = 1 / mSpeed;
+ mTick += dt;
+ uint fc = mAnimation->getFrameCount();
+ if (mTick >= interval)
+ {
+ mIndex += int(mTick / interval);
+ mTick = fmod(mTick, interval);
+ if (mLoop)
+ mIndex %= fc;
+ mIndex = clamp<uint>(mIndex, 0, fc - 1);
+ }
+ }
+
+ void Animator::rewind()
+ {
+ mIndex = 0;
+ }
+
+ void Animator::render(float x, float y, float sx, float sy, float r) const
+ {
+ if (!mAnimation)
+ return;
+ const Sprite* spr = mAnimation->getFrame(mIndex);
+ if (spr)
+ spr->render(x, y, sx, sy, r);
+ }
+
+ void Animator::forceToFrame(uint index)
+ {
+ mIndex = index;
+
+ }
+
+ void Animator::setSpeed(float speed)
+ {
+ mSpeed = speed;
+ }
+
+ void Animator::setDefaultSpeed()
+ {
+ if(mAnimation != nullptr)
+ mSpeed = mAnimation->getSpeed();
+ else
+ {
+ jin_log_error("Animation is null.");
+ return;
+ }
+ }
+
+ void Animator::setLoop(bool loop)
+ {
+ mLoop = loop;
+ }
+
+ void Animator::setDefaultLoop()
+ {
+ if(mAnimation != nullptr)
+ mLoop = mAnimation->isLoop();
+ else
+ {
+ jin_log_error("Animation is null.");
+ return;
+ }
+ }
+
+ float Animator::getSpeed()
+ {
+ return mSpeed;
+ }
+
+ uint Animator::getFrameCount()
+ {
+ return mAnimation->getFrameCount();
+ }
+
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/animations/animator.h b/src/libjin/graphics/animations/animator.h
index 263c7cb..6a0cb28 100644
--- a/src/libjin/graphics/animations/animator.h
+++ b/src/libjin/graphics/animations/animator.h
@@ -10,61 +10,61 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Animations
- {
+ namespace Graphics
+ {
+ namespace Animations
+ {
- class Animator : public Object, public Renderable
- {
- public:
- Animator();
+ class Animator : public Object, public Renderable
+ {
+ public:
+ Animator();
- void play();
+ void play();
- void pause();
+ void pause();
- void resume();
+ void resume();
- void update(float dt);
+ void update(float dt);
- void rewind();
+ void rewind();
- void render(float x, float y, float sx, float sy, float r) const override;
+ void render(float x, float y, float sx, float sy, float r) const override;
- void setAnimation(const Animation* anim);
+ void setAnimation(const Animation* anim);
- void forceToFrame(uint index);
+ void forceToFrame(uint index);
- void setSpeed(float speed);
+ void setSpeed(float speed);
- void setDefaultSpeed();
+ void setDefaultSpeed();
- void setLoop(bool loop);
+ void setLoop(bool loop);
- void setDefaultLoop();
+ void setDefaultLoop();
- float getSpeed();
+ float getSpeed();
- uint getFrameCount();
+ uint getFrameCount();
- private:
- const Animation* mAnimation;
+ private:
+ const Animation* mAnimation;
- uint mIndex;
+ uint mIndex;
- float mTick;
+ float mTick;
- bool mIsActive;
+ bool mIsActive;
- float mSpeed;
+ float mSpeed;
- bool mLoop;
+ bool mLoop;
- };
+ };
- }
- }
+ }
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/bitmap.cpp b/src/libjin/graphics/bitmap.cpp
index cae6f0b..b038d6c 100644
--- a/src/libjin/graphics/bitmap.cpp
+++ b/src/libjin/graphics/bitmap.cpp
@@ -12,178 +12,178 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
-
- Bitmap* Bitmap::clone()
- {
- Bitmap* b = new Bitmap(this);
- return b;
- }
-
- Bitmap::Bitmap()
- : width(0)
- , height(0)
- , pixels(nullptr)
- {
- }
-
- Bitmap::Bitmap(unsigned w, unsigned h)
- {
- width = w;
- height = h;
- pixels = new Color[w*h];
- if (pixels == nullptr)
- throw Exception("No enough memory.");
- }
-
- Bitmap::Bitmap(const char* path)
- {
- AssetDatabase* ad = AssetDatabase::get();
- Buffer buffer;
- ad->read(path, buffer);
- new (this) Bitmap(&buffer, buffer.size());
- }
-
- Bitmap::Bitmap(const void* pix, unsigned w, unsigned h)
- {
- new (this) Bitmap(w, h);
- memcpy(pixels, pix, w * h * sizeof(Color));
- }
-
- Bitmap::Bitmap(const void* imgData, size_t size)
- {
- if (imgData == nullptr)
- return;
- int w, h;
- void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
- if (data == nullptr)
- {
- throw Exception("Could not create bitmap from image data.");
- return;
- }
- new (this) Bitmap();
- pixels = (Color*)data;
- width = w;
- height = h;
- }
-
- Bitmap::Bitmap(int w, int h, Color color)
- {
- new (this) Bitmap(w, h);
- if (color != Color::BLACK)
- setPixels(color);
- }
-
- Bitmap::Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer)
- {
- new (this) Bitmap(w, h);
- for (int y = 0; y < height; ++y)
- {
- for (int x = 0; x < width; ++x)
- {
- Color c = drawer(width, height, x, y);
- setPixel(c, x, y);
- }
- }
- }
-
- Bitmap::Bitmap(const Bitmap* bitmap)
- {
- new (this) Bitmap();
- int w = bitmap->getWidth();
- int h = bitmap->getHeight();
- resetPixels(bitmap->getPixels(), w, h);
- }
-
- Bitmap::~Bitmap()
- {
- stbi_image_free(pixels);
- }
-
- void Bitmap::bind(Color* p, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = p;
- width = w;
- height = h;
- }
-
- void Bitmap::resetPixels(const Color* p, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = new Color[w*h];
- if (pixels == nullptr)
- throw Exception("Not enough memory.");
- size_t s = w * h * sizeof(Color);
- memcpy(pixels, p, s);
- width = w;
- height = h;
- }
-
- void Bitmap::setPixel(const Color& c, int x, int y)
- {
- if (pixels == nullptr)
- throw Exception("Bitmap don't have pixel space.");
- if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
- return;
- if (x + y * width >= width * height)
- throw Exception("Pixel <%d, %d> of bitmap is out of range.", x, y);
- pixels[x + y * width] = c;
- }
-
- void Bitmap::resetPixels(const Color& c, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = new Color[w*h];
- if (pixels == nullptr)
- throw Exception("Not enough memory.");
- width = w;
- height = h;
- for (int x = 0; x < w; ++x)
- {
- for (int y = 0; y < h; ++y)
- {
- pixels[x + y * w] = c;
- }
- }
- }
-
- void Bitmap::setPixels(Color* p, int count)
- {
- if (count > width * height)
- throw Exception("Pixels are out of range.");
- size_t s = width * height * sizeof(Color);
- memcpy(pixels, p, s);
- }
-
- void Bitmap::setPixels(Color c)
- {
- for (int x = 0; x < width; ++x)
- {
- for (int y = 0; y < height; ++y)
- {
- pixels[x + y * width] = c;
- }
- }
- }
-
- Color Bitmap::getPixel(int x, int y)
- {
- if (pixels == nullptr)
- return Color::BLACK;
- if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
- return Color::BLACK;
- return pixels[x + y * width];
- }
-
- const Color* Bitmap::getPixels() const
- {
- return pixels;
- }
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ Bitmap* Bitmap::clone()
+ {
+ Bitmap* b = new Bitmap(this);
+ return b;
+ }
+
+ Bitmap::Bitmap()
+ : width(0)
+ , height(0)
+ , pixels(nullptr)
+ {
+ }
+
+ Bitmap::Bitmap(unsigned w, unsigned h)
+ {
+ width = w;
+ height = h;
+ pixels = new Color[w*h];
+ if (pixels == nullptr)
+ throw Exception("No enough memory.");
+ }
+
+ Bitmap::Bitmap(const char* path)
+ {
+ AssetDatabase* ad = AssetDatabase::get();
+ Buffer buffer;
+ ad->read(path, buffer);
+ new (this) Bitmap(&buffer, buffer.size());
+ }
+
+ Bitmap::Bitmap(const void* pix, unsigned w, unsigned h)
+ {
+ new (this) Bitmap(w, h);
+ memcpy(pixels, pix, w * h * sizeof(Color));
+ }
+
+ Bitmap::Bitmap(const void* imgData, size_t size)
+ {
+ if (imgData == nullptr)
+ return;
+ int w, h;
+ void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
+ if (data == nullptr)
+ {
+ throw Exception("Could not create bitmap from image data.");
+ return;
+ }
+ new (this) Bitmap();
+ pixels = (Color*)data;
+ width = w;
+ height = h;
+ }
+
+ Bitmap::Bitmap(int w, int h, Color color)
+ {
+ new (this) Bitmap(w, h);
+ if (color != Color::BLACK)
+ setPixels(color);
+ }
+
+ Bitmap::Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer)
+ {
+ new (this) Bitmap(w, h);
+ for (int y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ Color c = drawer(width, height, x, y);
+ setPixel(c, x, y);
+ }
+ }
+ }
+
+ Bitmap::Bitmap(const Bitmap* bitmap)
+ {
+ new (this) Bitmap();
+ int w = bitmap->getWidth();
+ int h = bitmap->getHeight();
+ resetPixels(bitmap->getPixels(), w, h);
+ }
+
+ Bitmap::~Bitmap()
+ {
+ stbi_image_free(pixels);
+ }
+
+ void Bitmap::bind(Color* p, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = p;
+ width = w;
+ height = h;
+ }
+
+ void Bitmap::resetPixels(const Color* p, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = new Color[w*h];
+ if (pixels == nullptr)
+ throw Exception("Not enough memory.");
+ size_t s = w * h * sizeof(Color);
+ memcpy(pixels, p, s);
+ width = w;
+ height = h;
+ }
+
+ void Bitmap::setPixel(const Color& c, int x, int y)
+ {
+ if (pixels == nullptr)
+ throw Exception("Bitmap don't have pixel space.");
+ if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
+ return;
+ if (x + y * width >= width * height)
+ throw Exception("Pixel <%d, %d> of bitmap is out of range.", x, y);
+ pixels[x + y * width] = c;
+ }
+
+ void Bitmap::resetPixels(const Color& c, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = new Color[w*h];
+ if (pixels == nullptr)
+ throw Exception("Not enough memory.");
+ width = w;
+ height = h;
+ for (int x = 0; x < w; ++x)
+ {
+ for (int y = 0; y < h; ++y)
+ {
+ pixels[x + y * w] = c;
+ }
+ }
+ }
+
+ void Bitmap::setPixels(Color* p, int count)
+ {
+ if (count > width * height)
+ throw Exception("Pixels are out of range.");
+ size_t s = width * height * sizeof(Color);
+ memcpy(pixels, p, s);
+ }
+
+ void Bitmap::setPixels(Color c)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ for (int y = 0; y < height; ++y)
+ {
+ pixels[x + y * width] = c;
+ }
+ }
+ }
+
+ Color Bitmap::getPixel(int x, int y)
+ {
+ if (pixels == nullptr)
+ return Color::BLACK;
+ if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
+ return Color::BLACK;
+ return pixels[x + y * width];
+ }
+
+ const Color* Bitmap::getPixels() const
+ {
+ return pixels;
+ }
+
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/bitmap.h b/src/libjin/graphics/bitmap.h
index 17dca40..c42fc23 100644
--- a/src/libjin/graphics/bitmap.h
+++ b/src/libjin/graphics/bitmap.h
@@ -12,150 +12,150 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- ///
- /// A RGBA32 bitmap.
- ///
- /// A bitmap keeps pixels and can't draw directly onto screen. To render bitmap, a texture is required. A
- /// texture is a renderable hard ware side structure which could be handled with GPU. For instance, opengl
- /// create texture and store it in GPU memory for rendering them onto hdc.
- ///
- class Bitmap : public Object
- {
- public:
- ///
- /// Constructor of bitmap.
- ///
- Bitmap();
-
- ///
- /// Constructor of bitmap.
- ///
- /// @param width Width of bitmap.
- /// @param height Height of bitmap.
- ///
- Bitmap(unsigned w, unsigned h);
-
- Bitmap(const char* path);
-
- Bitmap(const void* pixels, unsigned w, unsigned h);
-
- Bitmap(const void* imgData, size_t size);
-
- Bitmap(int w, int h, Color color);
-
- Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer);
-
- Bitmap(const Bitmap* bitmap);
-
- ///
- /// Destructor of bitmap
- ///
- virtual ~Bitmap();
-
- ///
- /// Create bitmap with another one.
- ///
- /// @param bitmap Bitmap be cloned.
- /// @return Return bitmap pointer if created, otherwise return null.
- ///
- Bitmap* clone();
-
- ///
- /// Directly bind pixels with given pixels data
- ///
- /// @param pixels Pixels to be binded.
- /// @param width Width of bitmap
- /// @param height Height of bitmap
- ///
- void bind(Color* pixels, int width, int height);
-
- ///
- /// Reset pixel data with given pixels data.
- ///
- /// @param pixels Pixels to be set.
- /// @param width Width of bitmap
- /// @param height Height of bitmap
- ///
- void resetPixels(const Color* pixels, int width, int height);
-
- ///
- /// Reset pixel data with given color.
- ///
- /// @param color Color to be set.
- /// @param width Width of bitmap
- /// @param height Height of bitmap
- ///
- void resetPixels(const Color& color, int width, int height);
-
- ///
- /// Set pixel with given color.
- ///
- /// @param color Color to be set.
- /// @param x X value of pixel.
- /// @param y Y value of pixel.
- ///
- void setPixel(const Color& color, int x, int y);
-
- ///
- /// Set pixels with given color.
- ///
- /// @param color Color to be set.
- ///
- void setPixels(Color color);
-
- ///
- /// Set pixels with given color data.
- ///
- /// @param colors New pixels' colors.
- /// @param count Number of pixels.
- ///
- void setPixels(Color* colors, int count);
-
- ///
- /// Get pixel in given position.
- ///
- /// @param x X value of position.
- /// @param y Y value of position.
- ///
- Color getPixel(int x, int y);
-
- ///
- /// Get pixels.
- /// @return Colors of the bitmap.
- ///
- const Color* getPixels() const;
-
- ///
- /// Get bitmap width.
- ///
- /// @return Width of bitmap.
- ///
- inline int getWidth() const { return width; }
-
- ///
- /// Get bitmap height.
- ///
- /// @return Height of bitmap.
- ///
- inline int getHeight() const { return height; }
-
- ///
- /// Get bitmap size.
- ///
- /// @return Size of bitmap.
- ///
- inline Math::Vector2<int> getSize() const { return Math::Vector2<int>(width, height); }
-
- protected:
- Color * pixels;
- unsigned width, height;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ ///
+ /// A RGBA32 bitmap.
+ ///
+ /// A bitmap keeps pixels and can't draw directly onto screen. To render bitmap, a texture is required. A
+ /// texture is a renderable hard ware side structure which could be handled with GPU. For instance, opengl
+ /// create texture and store it in GPU memory for rendering them onto hdc.
+ ///
+ class Bitmap : public Object
+ {
+ public:
+ ///
+ /// Constructor of bitmap.
+ ///
+ Bitmap();
+
+ ///
+ /// Constructor of bitmap.
+ ///
+ /// @param width Width of bitmap.
+ /// @param height Height of bitmap.
+ ///
+ Bitmap(unsigned w, unsigned h);
+
+ Bitmap(const char* path);
+
+ Bitmap(const void* pixels, unsigned w, unsigned h);
+
+ Bitmap(const void* imgData, size_t size);
+
+ Bitmap(int w, int h, Color color);
+
+ Bitmap(int w, int h, std::function<Color(int, int, int, int)> drawer);
+
+ Bitmap(const Bitmap* bitmap);
+
+ ///
+ /// Destructor of bitmap
+ ///
+ virtual ~Bitmap();
+
+ ///
+ /// Create bitmap with another one.
+ ///
+ /// @param bitmap Bitmap be cloned.
+ /// @return Return bitmap pointer if created, otherwise return null.
+ ///
+ Bitmap* clone();
+
+ ///
+ /// Directly bind pixels with given pixels data
+ ///
+ /// @param pixels Pixels to be binded.
+ /// @param width Width of bitmap
+ /// @param height Height of bitmap
+ ///
+ void bind(Color* pixels, int width, int height);
+
+ ///
+ /// Reset pixel data with given pixels data.
+ ///
+ /// @param pixels Pixels to be set.
+ /// @param width Width of bitmap
+ /// @param height Height of bitmap
+ ///
+ void resetPixels(const Color* pixels, int width, int height);
+
+ ///
+ /// Reset pixel data with given color.
+ ///
+ /// @param color Color to be set.
+ /// @param width Width of bitmap
+ /// @param height Height of bitmap
+ ///
+ void resetPixels(const Color& color, int width, int height);
+
+ ///
+ /// Set pixel with given color.
+ ///
+ /// @param color Color to be set.
+ /// @param x X value of pixel.
+ /// @param y Y value of pixel.
+ ///
+ void setPixel(const Color& color, int x, int y);
+
+ ///
+ /// Set pixels with given color.
+ ///
+ /// @param color Color to be set.
+ ///
+ void setPixels(Color color);
+
+ ///
+ /// Set pixels with given color data.
+ ///
+ /// @param colors New pixels' colors.
+ /// @param count Number of pixels.
+ ///
+ void setPixels(Color* colors, int count);
+
+ ///
+ /// Get pixel in given position.
+ ///
+ /// @param x X value of position.
+ /// @param y Y value of position.
+ ///
+ Color getPixel(int x, int y);
+
+ ///
+ /// Get pixels.
+ /// @return Colors of the bitmap.
+ ///
+ const Color* getPixels() const;
+
+ ///
+ /// Get bitmap width.
+ ///
+ /// @return Width of bitmap.
+ ///
+ inline int getWidth() const { return width; }
+
+ ///
+ /// Get bitmap height.
+ ///
+ /// @return Height of bitmap.
+ ///
+ inline int getHeight() const { return height; }
+
+ ///
+ /// Get bitmap size.
+ ///
+ /// @return Size of bitmap.
+ ///
+ inline Math::Vector2<int> getSize() const { return Math::Vector2<int>(width, height); }
+
+ protected:
+ Color * pixels;
+ unsigned width, height;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif
diff --git a/src/libjin/graphics/canvas.cpp b/src/libjin/graphics/canvas.cpp
index db02110..a5c757b 100644
--- a/src/libjin/graphics/canvas.cpp
+++ b/src/libjin/graphics/canvas.cpp
@@ -7,52 +7,52 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- Canvas::Canvas(GLuint n)
- : fbo(n)
- {
- ++gl.getStats().canvases;
- }
-
- Canvas::Canvas(int w, int h)
- : Graphic(w, h)
- {
- GLint current_fbo;
- glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
-
- // Generate a new render buffer object.
- fbo = gl.genFrameBuffer();
- gl.bindFrameBuffer(fbo);
-
- // Render texture.
- GLuint texture = getGLTexture();
- gl.bindTexture2D(texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
- // Unbind framebuffer
- gl.bindFrameBuffer(current_fbo);
-
- ++gl.getStats().canvases;
- }
-
- Canvas::~Canvas()
- {
- --gl.getStats().canvases;
- }
-
- bool Canvas::isBinded(const Canvas* cvs)
- {
- return gl.getCanvas() == cvs;
- }
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ Canvas::Canvas(GLuint n)
+ : fbo(n)
+ {
+ ++gl.getStats().canvases;
+ }
+
+ Canvas::Canvas(int w, int h)
+ : Graphic(w, h)
+ {
+ GLint current_fbo;
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
+
+ // Generate a new render buffer object.
+ fbo = gl.genFrameBuffer();
+ gl.bindFrameBuffer(fbo);
+
+ // Render texture.
+ GLuint texture = getGLTexture();
+ gl.bindTexture2D(texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ // Unbind framebuffer
+ gl.bindFrameBuffer(current_fbo);
+
+ ++gl.getStats().canvases;
+ }
+
+ Canvas::~Canvas()
+ {
+ --gl.getStats().canvases;
+ }
+
+ bool Canvas::isBinded(const Canvas* cvs)
+ {
+ return gl.getCanvas() == cvs;
+ }
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/canvas.h b/src/libjin/graphics/canvas.h
index 302764a..4ccf96c 100644
--- a/src/libjin/graphics/canvas.h
+++ b/src/libjin/graphics/canvas.h
@@ -7,45 +7,45 @@
namespace JinEngine
{
- namespace Graphics
- {
- ///
- /// Renderable canvas.
- ///
- /// A canvas is a rendering target.
- ///
- class Canvas : public Graphic
- {
- public:
- ///
- ///
- ///
- static bool isBinded(const Canvas*);
-
- ///
- /// Default canvas, aka screen.
- ///
- Canvas(GLuint n);
-
- ///
- ///
- ///
- Canvas(int w, int h);
-
- ///
- ///
- ///
- ~Canvas();
-
- inline GLuint getGLFrameBuffer() const { return fbo; };
-
- protected:
-
- GLuint fbo;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+ ///
+ /// Renderable canvas.
+ ///
+ /// A canvas is a rendering target.
+ ///
+ class Canvas : public Graphic
+ {
+ public:
+ ///
+ ///
+ ///
+ static bool isBinded(const Canvas*);
+
+ ///
+ /// Default canvas, aka screen.
+ ///
+ Canvas(GLuint n);
+
+ ///
+ ///
+ ///
+ Canvas(int w, int h);
+
+ ///
+ ///
+ ///
+ ~Canvas();
+
+ inline GLuint getGLFrameBuffer() const { return fbo; };
+
+ protected:
+
+ GLuint fbo;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics)
diff --git a/src/libjin/graphics/color.cpp b/src/libjin/graphics/color.cpp
index 92f61c6..5b3492e 100644
--- a/src/libjin/graphics/color.cpp
+++ b/src/libjin/graphics/color.cpp
@@ -2,21 +2,21 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- const Color Color::WHITE = Color(255, 255, 255);
- const Color Color::BLACK = Color(0, 0, 0);
- const Color Color::RED = Color(255, 0, 0);
- const Color Color::GREEN = Color(0, 255, 0);
- const Color Color::BLUE = Color(0, 0, 255);
- const Color Color::MAGENTA = Color(255, 0, 255);
- const Color Color::YELLOW = Color(255, 255, 0);
+ const Color Color::WHITE = Color(255, 255, 255);
+ const Color Color::BLACK = Color(0, 0, 0);
+ const Color Color::RED = Color(255, 0, 0);
+ const Color Color::GREEN = Color(0, 255, 0);
+ const Color Color::BLUE = Color(0, 0, 255);
+ const Color Color::MAGENTA = Color(255, 0, 255);
+ const Color Color::YELLOW = Color(255, 255, 0);
- const uint32 Color::RMASK = 0x000000ff;
- const uint32 Color::GMASK = 0x0000ff00;
- const uint32 Color::BMASK = 0x00ff0000;
- const uint32 Color::AMASK = 0xff000000;
+ const uint32 Color::RMASK = 0x000000ff;
+ const uint32 Color::GMASK = 0x0000ff00;
+ const uint32 Color::BMASK = 0x00ff0000;
+ const uint32 Color::AMASK = 0xff000000;
- }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/color.h b/src/libjin/graphics/color.h
index 0f7d6dd..f10d918 100644
--- a/src/libjin/graphics/color.h
+++ b/src/libjin/graphics/color.h
@@ -13,105 +13,105 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- typedef uint8 Channel;
-
- class Color
- {
- public:
- // Built-in colors
- static const Color WHITE;
- static const Color BLACK;
- static const Color RED;
- static const Color GREEN;
- static const Color BLUE;
- static const Color MAGENTA;
- static const Color YELLOW;
-
- static const uint32 RMASK;
- static const uint32 GMASK;
- static const uint32 BMASK;
- static const uint32 AMASK;
-
- ///
- /// Get lerp color with given factor.
- ///
- /// @param start Start color.
- /// @param end End color.
- /// @param t Factor of interplation.
- /// @return Color after interplation.
- ///
- static Color lerp(Color start, Color end, float t)
- {
- t = Math::clamp<float>(t, 0, 1);
- Color c;
- c.r = Math::lerp(start.r, end.r, t);
- c.g = Math::lerp(start.g, end.g, t);
- c.b = Math::lerp(start.b, end.b, t);
- c.a = Math::lerp(start.a, end.a, t);
- return c;
- }
-
- ///
- ///
- ///
- Color() { r = g = b = a = 0; };
-
- ///
- ///
- ///
- Color(unsigned char _r
- , unsigned char _g
- , unsigned char _b
- , unsigned char _a = 255)
- {
- r = _r;
- g = _g;
- b = _b;
- a = _a;
- }
-
- Color(const Color& c)
- {
- r = c.r;
- g = c.g;
- b = c.b;
- a = c.a;
- }
-
- void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
- {
- r = _r;
- g = _g;
- b = _b;
- a = _a;
- }
-
- void operator = (const Color& c)
- {
- r = c.r;
- g = c.g;
- b = c.b;
- a = c.a;
- }
-
- bool operator == (const Color& c)
- {
- return r == c.r && g == c.g && b == c.b && a == c.a;
- }
-
- bool operator != (const Color& c)
- {
- return !(r == c.r && g == c.g && b == c.b && a == c.a);
- }
-
- Channel r, g, b, a;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ typedef uint8 Channel;
+
+ class Color
+ {
+ public:
+ // Built-in colors
+ static const Color WHITE;
+ static const Color BLACK;
+ static const Color RED;
+ static const Color GREEN;
+ static const Color BLUE;
+ static const Color MAGENTA;
+ static const Color YELLOW;
+
+ static const uint32 RMASK;
+ static const uint32 GMASK;
+ static const uint32 BMASK;
+ static const uint32 AMASK;
+
+ ///
+ /// Get lerp color with given factor.
+ ///
+ /// @param start Start color.
+ /// @param end End color.
+ /// @param t Factor of interplation.
+ /// @return Color after interplation.
+ ///
+ static Color lerp(Color start, Color end, float t)
+ {
+ t = Math::clamp<float>(t, 0, 1);
+ Color c;
+ c.r = Math::lerp(start.r, end.r, t);
+ c.g = Math::lerp(start.g, end.g, t);
+ c.b = Math::lerp(start.b, end.b, t);
+ c.a = Math::lerp(start.a, end.a, t);
+ return c;
+ }
+
+ ///
+ ///
+ ///
+ Color() { r = g = b = a = 0; };
+
+ ///
+ ///
+ ///
+ Color(unsigned char _r
+ , unsigned char _g
+ , unsigned char _b
+ , unsigned char _a = 255)
+ {
+ r = _r;
+ g = _g;
+ b = _b;
+ a = _a;
+ }
+
+ Color(const Color& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+ }
+
+ void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
+ {
+ r = _r;
+ g = _g;
+ b = _b;
+ a = _a;
+ }
+
+ void operator = (const Color& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+ }
+
+ bool operator == (const Color& c)
+ {
+ return r == c.r && g == c.g && b == c.b && a == c.a;
+ }
+
+ bool operator != (const Color& c)
+ {
+ return !(r == c.r && g == c.g && b == c.b && a == c.a);
+ }
+
+ Channel r, g, b, a;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // jin_graphics
diff --git a/src/libjin/graphics/fonts/decoder.cpp b/src/libjin/graphics/fonts/decoder.cpp
index 5c74258..2b6fb66 100644
--- a/src/libjin/graphics/fonts/decoder.cpp
+++ b/src/libjin/graphics/fonts/decoder.cpp
@@ -4,93 +4,93 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
+ namespace Graphics
+ {
+ namespace Fonts
+ {
- /* utf8 byte string to unicode codepoint */
- static const char *utf8toCodepoint(const char *p, unsigned *res) {
- return nullptr;
+ /* utf8 byte string to unicode codepoint */
+ static const char *utf8toCodepoint(const char *p, unsigned *res) {
+ return nullptr;
- }
+ }
- /////////////////////////////////////////////////////////////////////////////
- // decoders
- /////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////
+ // decoders
+ /////////////////////////////////////////////////////////////////////////////
- const void* Utf8::decode(const void* data, Codepoint* res) const
- {
- const char* p = (char*)data;
- unsigned x, mask, shift;
- switch (*p & 0xf0) {
- case 0xf0: mask = 0x07; shift = 18; break;
- case 0xe0: mask = 0x0f; shift = 12; break;
- case 0xc0:
- case 0xd0: mask = 0x1f; shift = 6; break;
- default:
- *res = *p;
- return p + 1;
- }
- x = (*p & mask) << shift;
- do {
- if (*(++p) == '\0') {
- *res = x;
- return p;
- }
- shift -= 6;
- x |= (*p & 0x3f) << shift;
- } while (shift);
- *res = x;
- return p + 1;
- }
+ const void* Utf8::decode(const void* data, Codepoint* res) const
+ {
+ const char* p = (char*)data;
+ unsigned x, mask, shift;
+ switch (*p & 0xf0) {
+ case 0xf0: mask = 0x07; shift = 18; break;
+ case 0xe0: mask = 0x0f; shift = 12; break;
+ case 0xc0:
+ case 0xd0: mask = 0x1f; shift = 6; break;
+ default:
+ *res = *p;
+ return p + 1;
+ }
+ x = (*p & mask) << shift;
+ do {
+ if (*(++p) == '\0') {
+ *res = x;
+ return p;
+ }
+ shift -= 6;
+ x |= (*p & 0x3f) << shift;
+ } while (shift);
+ *res = x;
+ return p + 1;
+ }
- const void* Utf8::next(const void* data) const
- {
- const char* p = (char*)data;
- unsigned x, mask, shift;
- switch (*p & 0xf0) {
- case 0xf0: mask = 0x07; shift = 18; break;
- case 0xe0: mask = 0x0f; shift = 12; break;
- case 0xc0:
- case 0xd0: mask = 0x1f; shift = 6; break;
- default:
- return p + 1;
- }
- x = (*p & mask) << shift;
- do {
- if (*(++p) == '\0') {
- return p;
- }
- shift -= 6;
- x |= (*p & 0x3f) << shift;
- } while (shift);
- return p + 1;
- }
- /*
- const void* Utf16::decode(const void* data, Codepoint* res) const
- {
- return nullptr;
- }
+ const void* Utf8::next(const void* data) const
+ {
+ const char* p = (char*)data;
+ unsigned x, mask, shift;
+ switch (*p & 0xf0) {
+ case 0xf0: mask = 0x07; shift = 18; break;
+ case 0xe0: mask = 0x0f; shift = 12; break;
+ case 0xc0:
+ case 0xd0: mask = 0x1f; shift = 6; break;
+ default:
+ return p + 1;
+ }
+ x = (*p & mask) << shift;
+ do {
+ if (*(++p) == '\0') {
+ return p;
+ }
+ shift -= 6;
+ x |= (*p & 0x3f) << shift;
+ } while (shift);
+ return p + 1;
+ }
+ /*
+ const void* Utf16::decode(const void* data, Codepoint* res) const
+ {
+ return nullptr;
+ }
- const void* Utf16::next(const void* data) const
- {
- return nullptr;
- }
- */
- const void* Ascii::decode(const void* data, Codepoint* res) const
- {
- const char* p = (char*)data;
- *res = *p;
- return p + 1;
- }
+ const void* Utf16::next(const void* data) const
+ {
+ return nullptr;
+ }
+ */
+ const void* Ascii::decode(const void* data, Codepoint* res) const
+ {
+ const char* p = (char*)data;
+ *res = *p;
+ return p + 1;
+ }
- const void* Ascii::next(const void* data) const
- {
- const char* p = (char*)data;
- return p + 1;
- }
+ const void* Ascii::next(const void* data) const
+ {
+ const char* p = (char*)data;
+ return p + 1;
+ }
- } // namespace Fonts
- } // namespace Graphics
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/decoder.h b/src/libjin/graphics/fonts/decoder.h
index 8ff7bd7..e5e7bda 100644
--- a/src/libjin/graphics/fonts/decoder.h
+++ b/src/libjin/graphics/fonts/decoder.h
@@ -9,91 +9,91 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- ///
- /// Text decoder.
- ///
- class Decoder : public Object
- {
- public:
-
- ///
- /// Decode a code unit.
- ///
- /// @param data Code units.
- /// @param codepoint Value of code point.
- /// @return Next code unit location.
- ///
- virtual const void* decode(const void* data, Codepoint* codepoint) const = 0;
-
- ///
- /// Get next code unit location.
- ///
- /// @param data Code units.
- /// @return Next code unit location.
- ///
- virtual const void* next(const void* data) const = 0;
-
- };
-
- ///
- /// Utf-8 decoder.
- ///
- class Utf8 : public Decoder
- {
- public:
-
- ///
- /// Decode a code unit.
- ///
- /// @param data Code units.
- /// @param codepoint Value of code point.
- /// @return Next code unit location.
- ///
- const void* decode(const void* data, Codepoint* codepoint) const override;
-
- ///
- /// Get next code unit location.
- ///
- /// @param data Code units.
- /// @return Next code unit location.
- ///
- const void* next(const void* data) const override;
-
- };
-
- ///
- /// Ascii decoder.
- ///
- class Ascii : public Decoder
- {
- public:
-
- ///
- /// Decode a code unit.
- ///
- /// @param data Code units.
- /// @param codepoint Value of code point.
- /// @return Next code unit location.
- ///
- const void* decode(const void* data, Codepoint* codepoint) const override;
-
- ///
- /// Get next code unit location.
- ///
- /// @param data Code units.
- /// @return Next code unit location.
- ///
- const void* next(const void* data) const override;
-
- };
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ ///
+ /// Text decoder.
+ ///
+ class Decoder : public Object
+ {
+ public:
+
+ ///
+ /// Decode a code unit.
+ ///
+ /// @param data Code units.
+ /// @param codepoint Value of code point.
+ /// @return Next code unit location.
+ ///
+ virtual const void* decode(const void* data, Codepoint* codepoint) const = 0;
+
+ ///
+ /// Get next code unit location.
+ ///
+ /// @param data Code units.
+ /// @return Next code unit location.
+ ///
+ virtual const void* next(const void* data) const = 0;
+
+ };
+
+ ///
+ /// Utf-8 decoder.
+ ///
+ class Utf8 : public Decoder
+ {
+ public:
+
+ ///
+ /// Decode a code unit.
+ ///
+ /// @param data Code units.
+ /// @param codepoint Value of code point.
+ /// @return Next code unit location.
+ ///
+ const void* decode(const void* data, Codepoint* codepoint) const override;
+
+ ///
+ /// Get next code unit location.
+ ///
+ /// @param data Code units.
+ /// @return Next code unit location.
+ ///
+ const void* next(const void* data) const override;
+
+ };
+
+ ///
+ /// Ascii decoder.
+ ///
+ class Ascii : public Decoder
+ {
+ public:
+
+ ///
+ /// Decode a code unit.
+ ///
+ /// @param data Code units.
+ /// @param codepoint Value of code point.
+ /// @return Next code unit location.
+ ///
+ const void* decode(const void* data, Codepoint* codepoint) const override;
+
+ ///
+ /// Get next code unit location.
+ ///
+ /// @param data Code units.
+ /// @return Next code unit location.
+ ///
+ const void* next(const void* data) const override;
+
+ };
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/font.h b/src/libjin/graphics/fonts/font.h
index 166cd6b..b206a2d 100644
--- a/src/libjin/graphics/fonts/font.h
+++ b/src/libjin/graphics/fonts/font.h
@@ -9,108 +9,108 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- struct Page;
-
- //
- // Font
- // |- TTF
- // |- TextureFont
- //
-
- ///
- /// Base Font class.
- ///
- class Font : public Object, public Renderable
- {
- public:
- ///
- /// Font constructor.
- ///
- Font(unsigned fontsize)
- : mFontSize(fontsize)
- {
- ++gl.getStats().fonts;
- }
-
- ///
- /// Font destructor.
- ///
- virtual ~Font()
- {
- --gl.getStats().fonts;
- };
-
- ///
- /// Create page with given text.
- ///
- /// @param text Text to be typesetted.
- /// @param lineheight Line height of text.
- /// @param spacing Spacing between characters. 0 by default.
- /// @return Page if created successfully, otherwise return null.
- ///
- virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0;
-
- ///
- /// Create page with given unicode codepoints.
- ///
- /// @param content Unicode codepoints to be typesetted.
- /// @param lineheight Line height of text.
- /// @param spacing Spacing between characters. 0 by default.
- /// @return Page if created successfully, otherwise return null.
- ///
- virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0;
-
- ///
- /// Render page to given position.
- ///
- /// @param page Page to be rendered.
- /// @param x X value of the position.
- /// @param y Y value of the position.
- ///
- virtual void render(const Page* page, int x, int y) = 0;
-
- ///
- /// Render unicode codepoints to given position.
- ///
- /// @param content Unicode codepoints to be typesetted.
- /// @param x X value of the position.
- /// @param y Y value of the position.
- /// @param lineheight Line height of the content.
- /// @param spacing Spacing between characters.
- ///
- virtual void render(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0;
-
- ///
- /// Render text to given position.
- ///
- /// @param text Text to be rendered.
- /// @param x X value of the position.
- /// @param y Y value of the position.
- /// @param lineheight Line height of the text.
- /// @param spacing Spacing between characters.
- ///
- virtual void render(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0;
-
- ///
- /// Get font size.
- ///
- /// @return Font size.
- ///
- inline unsigned getFontSize() { return mFontSize; };
-
- protected:
-
- unsigned mFontSize;
-
- };
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ struct Page;
+
+ //
+ // Font
+ // |- TTF
+ // |- TextureFont
+ //
+
+ ///
+ /// Base Font class.
+ ///
+ class Font : public Object, public Renderable
+ {
+ public:
+ ///
+ /// Font constructor.
+ ///
+ Font(unsigned fontsize)
+ : mFontSize(fontsize)
+ {
+ ++gl.getStats().fonts;
+ }
+
+ ///
+ /// Font destructor.
+ ///
+ virtual ~Font()
+ {
+ --gl.getStats().fonts;
+ };
+
+ ///
+ /// Create page with given text.
+ ///
+ /// @param text Text to be typesetted.
+ /// @param lineheight Line height of text.
+ /// @param spacing Spacing between characters. 0 by default.
+ /// @return Page if created successfully, otherwise return null.
+ ///
+ virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0;
+
+ ///
+ /// Create page with given unicode codepoints.
+ ///
+ /// @param content Unicode codepoints to be typesetted.
+ /// @param lineheight Line height of text.
+ /// @param spacing Spacing between characters. 0 by default.
+ /// @return Page if created successfully, otherwise return null.
+ ///
+ virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0;
+
+ ///
+ /// Render page to given position.
+ ///
+ /// @param page Page to be rendered.
+ /// @param x X value of the position.
+ /// @param y Y value of the position.
+ ///
+ virtual void render(const Page* page, int x, int y) = 0;
+
+ ///
+ /// Render unicode codepoints to given position.
+ ///
+ /// @param content Unicode codepoints to be typesetted.
+ /// @param x X value of the position.
+ /// @param y Y value of the position.
+ /// @param lineheight Line height of the content.
+ /// @param spacing Spacing between characters.
+ ///
+ virtual void render(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0;
+
+ ///
+ /// Render text to given position.
+ ///
+ /// @param text Text to be rendered.
+ /// @param x X value of the position.
+ /// @param y Y value of the position.
+ /// @param lineheight Line height of the text.
+ /// @param spacing Spacing between characters.
+ ///
+ virtual void render(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0;
+
+ ///
+ /// Get font size.
+ ///
+ /// @return Font size.
+ ///
+ inline unsigned getFontSize() { return mFontSize; };
+
+ protected:
+
+ unsigned mFontSize;
+
+ };
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif // __JE_FONT_H__
diff --git a/src/libjin/graphics/fonts/page.h b/src/libjin/graphics/fonts/page.h
index 75f1840..0a9b5e2 100644
--- a/src/libjin/graphics/fonts/page.h
+++ b/src/libjin/graphics/fonts/page.h
@@ -7,48 +7,48 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- class Font;
-
- ///
- /// Glyphs data to be rendered.
- ///
- struct GlyphVertex
- {
- int x, y; ///< screen coordinates
- float u, v; ///< normalized texture uv
- };
-
- ///
- /// Glyphs info for reducing draw call.
- ///
- struct GlyphArrayDrawInfo
- {
- GLuint texture; ///< atlas
- unsigned int start; ///< glyph vertex indecies
- unsigned int count; ///< glyph vertex count
- };
-
- ///
- /// Page to be rendered.
- ///
- /// A page is a pre-rendered text struct for reducing draw call. Each page
- /// keeps a font pointer which should not be changed.
- ///
- struct Page : public Object
- {
- Font* font;
- std::vector<GlyphArrayDrawInfo> glyphinfolist;
- std::vector<GlyphVertex> glyphvertices;
- Math::Vector2<int> size;
- };
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ class Font;
+
+ ///
+ /// Glyphs data to be rendered.
+ ///
+ struct GlyphVertex
+ {
+ int x, y; ///< screen coordinates
+ float u, v; ///< normalized texture uv
+ };
+
+ ///
+ /// Glyphs info for reducing draw call.
+ ///
+ struct GlyphArrayDrawInfo
+ {
+ GLuint texture; ///< atlas
+ unsigned int start; ///< glyph vertex indecies
+ unsigned int count; ///< glyph vertex count
+ };
+
+ ///
+ /// Page to be rendered.
+ ///
+ /// A page is a pre-rendered text struct for reducing draw call. Each page
+ /// keeps a font pointer which should not be changed.
+ ///
+ struct Page : public Object
+ {
+ Font* font;
+ std::vector<GlyphArrayDrawInfo> glyphinfolist;
+ std::vector<GlyphVertex> glyphvertices;
+ Math::Vector2<int> size;
+ };
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif // __JE_PAGE_H__
diff --git a/src/libjin/graphics/fonts/text.cpp b/src/libjin/graphics/fonts/text.cpp
index 9684b81..311c8c8 100644
--- a/src/libjin/graphics/fonts/text.cpp
+++ b/src/libjin/graphics/fonts/text.cpp
@@ -5,153 +5,153 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- /////////////////////////////////////////////////////////////////////////////
- // iterator
- /////////////////////////////////////////////////////////////////////////////
-
- Text::Iterator::Iterator(const Iterator& itor)
- : data(itor.data)
- , p(itor.p)
- , encode(itor.encode)
- , length(itor.length)
- {
- switch (encode)
- {
- case Encode::UTF8: decoder = new Utf8(); break;
- case Encode::ASCII: decoder = new Ascii(); break;
- }
- }
-
- Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length)
- : data(_data)
- , p(_data)
- , encode(_encode)
- , length(_length)
- {
- switch (encode)
- {
- case Encode::UTF8: decoder = new Utf8(); break;
- case Encode::ASCII: decoder = new Ascii(); break;
- }
- }
-
- Text::Iterator::~Iterator()
- {
- delete decoder;
- }
-
- Codepoint Text::Iterator::get()
- {
- Codepoint codepoint;
- decoder->decode(p, &codepoint);
- return codepoint;
- }
-
- Codepoint Text::Iterator::operator*()
- {
- return get();
- }
- /*
- Text::Iterator Text::Iterator::begin()
- {
- Iterator itor(encode, data, length);
- itor.toBegin();
- return itor;
- }
-
- Text::Iterator Text::Iterator::end()
- {
- Iterator itor(encode, data, length);
- itor.toEnd();
- return itor;
- }
- */
- void Text::Iterator::toBegin()
- {
- p = (const unsigned char*)data;
- }
-
- void Text::Iterator::toEnd()
- {
- p = (const unsigned char*)data + length;
- }
-
- Text::Iterator& Text::Iterator::operator ++()
- {
- p = decoder->next(p);
- return *this;
- }
-
- Text::Iterator Text::Iterator::operator ++(int)
- {
- p = decoder->next(p);
- Iterator itor(encode, data, length);
- itor.p = p;
- return itor;
- }
-
- bool Text::Iterator::operator !=(const Iterator& itor)
- {
- return !(data == itor.data
- && p == itor.p
- && length == itor.length
- && encode == itor.encode);
- }
-
- bool Text::Iterator::operator ==(const Iterator& itor)
- {
- return data == itor.data
- && p == itor.p
- && length == itor.length
- && encode == itor.encode;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // text
- /////////////////////////////////////////////////////////////////////////////
-
- Text::Text(Encode encode, const void* data)
- {
- unsigned length = strlen((const char*)data);
- Iterator end = Iterator(encode, data, length);
- end.toEnd();
- Iterator it = Iterator(encode, data, length);
- for (; it != end; ++it)
- {
- content.push_back(*it);
- }
- }
-
- Text::Text(Encode encode, const void* data, unsigned length)
- {
- Iterator end = Iterator(encode, data, length);
- end.toEnd();
- Iterator it = Iterator(encode, data, length);
- for (; it != end; ++it)
- {
- content.push_back(*it);
- }
- }
-
- Text::~Text()
- {
- }
-
- const Content& Text::getContent() const
- {
- return content;
- }
-
- const Content& Text::operator*() const
- {
- return content;
- }
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ /////////////////////////////////////////////////////////////////////////////
+ // iterator
+ /////////////////////////////////////////////////////////////////////////////
+
+ Text::Iterator::Iterator(const Iterator& itor)
+ : data(itor.data)
+ , p(itor.p)
+ , encode(itor.encode)
+ , length(itor.length)
+ {
+ switch (encode)
+ {
+ case Encode::UTF8: decoder = new Utf8(); break;
+ case Encode::ASCII: decoder = new Ascii(); break;
+ }
+ }
+
+ Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length)
+ : data(_data)
+ , p(_data)
+ , encode(_encode)
+ , length(_length)
+ {
+ switch (encode)
+ {
+ case Encode::UTF8: decoder = new Utf8(); break;
+ case Encode::ASCII: decoder = new Ascii(); break;
+ }
+ }
+
+ Text::Iterator::~Iterator()
+ {
+ delete decoder;
+ }
+
+ Codepoint Text::Iterator::get()
+ {
+ Codepoint codepoint;
+ decoder->decode(p, &codepoint);
+ return codepoint;
+ }
+
+ Codepoint Text::Iterator::operator*()
+ {
+ return get();
+ }
+ /*
+ Text::Iterator Text::Iterator::begin()
+ {
+ Iterator itor(encode, data, length);
+ itor.toBegin();
+ return itor;
+ }
+
+ Text::Iterator Text::Iterator::end()
+ {
+ Iterator itor(encode, data, length);
+ itor.toEnd();
+ return itor;
+ }
+ */
+ void Text::Iterator::toBegin()
+ {
+ p = (const unsigned char*)data;
+ }
+
+ void Text::Iterator::toEnd()
+ {
+ p = (const unsigned char*)data + length;
+ }
+
+ Text::Iterator& Text::Iterator::operator ++()
+ {
+ p = decoder->next(p);
+ return *this;
+ }
+
+ Text::Iterator Text::Iterator::operator ++(int)
+ {
+ p = decoder->next(p);
+ Iterator itor(encode, data, length);
+ itor.p = p;
+ return itor;
+ }
+
+ bool Text::Iterator::operator !=(const Iterator& itor)
+ {
+ return !(data == itor.data
+ && p == itor.p
+ && length == itor.length
+ && encode == itor.encode);
+ }
+
+ bool Text::Iterator::operator ==(const Iterator& itor)
+ {
+ return data == itor.data
+ && p == itor.p
+ && length == itor.length
+ && encode == itor.encode;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ // text
+ /////////////////////////////////////////////////////////////////////////////
+
+ Text::Text(Encode encode, const void* data)
+ {
+ unsigned length = strlen((const char*)data);
+ Iterator end = Iterator(encode, data, length);
+ end.toEnd();
+ Iterator it = Iterator(encode, data, length);
+ for (; it != end; ++it)
+ {
+ content.push_back(*it);
+ }
+ }
+
+ Text::Text(Encode encode, const void* data, unsigned length)
+ {
+ Iterator end = Iterator(encode, data, length);
+ end.toEnd();
+ Iterator it = Iterator(encode, data, length);
+ for (; it != end; ++it)
+ {
+ content.push_back(*it);
+ }
+ }
+
+ Text::~Text()
+ {
+ }
+
+ const Content& Text::getContent() const
+ {
+ return content;
+ }
+
+ const Content& Text::operator*() const
+ {
+ return content;
+ }
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/text.h b/src/libjin/graphics/fonts/text.h
index c3bb8db..fe02d36 100644
--- a/src/libjin/graphics/fonts/text.h
+++ b/src/libjin/graphics/fonts/text.h
@@ -7,168 +7,168 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- typedef unsigned int Codepoint;
-
- typedef std::vector<Codepoint> Content;
-
- class Text;
-
- class Decoder;
-
- ///
- /// Supported text encoding.
- ///
- enum Encode
- {
- UTF8, ///< utf-8
- ASCII, ///< ASCII
- };
-
- ///
- /// Decoded text. Saved as unicode codepoints.
- ///
- class Text : public Object
- {
- public:
- ///
- ///
- ///
- Text(Encode encode, const void* data);
-
- ///
- ///
- ///
- Text(Encode encode, const void* data, unsigned int length);
-
- ///
- ///
- ///
- ~Text();
-
- ///
- ///
- ///
- const Content& getContent() const;
-
- ///
- ///
- ///
- const Content& operator*() const;
-
- private:
- ///
- ///
- ///
- class Iterator
- {
- public:
-
- ///
- ///
- ///
- Iterator(const Iterator& itor);
-
- ///
- ///
- ///
- Iterator(const Encode& encode, const void* data, unsigned int length);
-
- ///
- ///
- ///
- ~Iterator();
-
- ///
- ///
- ///
- Codepoint get();
-
- //Iterator begin();
- //Iterator end();
-
- ///
- ///
- ///
- void toBegin();
-
- ///
- ///
- ///
- void toEnd();
-
- ///
- ///
- ///
- Codepoint operator *();
-
- ///
- ///
- ///
- Iterator& operator ++();
-
- ///
- ///
- ///
- Iterator operator ++(int);
-
- ///
- ///
- ///
- bool operator !=(const Iterator& itor);
-
- ///
- ///
- ///
- bool operator ==(const Iterator& itor);
-
- private:
-
- ///
- ///
- ///
- void operator = (const Iterator&);
-
- ///
- ///
- ///
- const Encode encode;
-
- ///
- ///
- ///
- const Decoder* decoder;
-
- ///
- ///
- ///
- const void* p;
-
- ///
- ///
- ///
- const void* const data;
-
- ///
- ///
- ///
- unsigned int length;
-
- };
-
- ///
- ///
- ///
- Content content;
-
- };
-
- }
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ typedef unsigned int Codepoint;
+
+ typedef std::vector<Codepoint> Content;
+
+ class Text;
+
+ class Decoder;
+
+ ///
+ /// Supported text encoding.
+ ///
+ enum Encode
+ {
+ UTF8, ///< utf-8
+ ASCII, ///< ASCII
+ };
+
+ ///
+ /// Decoded text. Saved as unicode codepoints.
+ ///
+ class Text : public Object
+ {
+ public:
+ ///
+ ///
+ ///
+ Text(Encode encode, const void* data);
+
+ ///
+ ///
+ ///
+ Text(Encode encode, const void* data, unsigned int length);
+
+ ///
+ ///
+ ///
+ ~Text();
+
+ ///
+ ///
+ ///
+ const Content& getContent() const;
+
+ ///
+ ///
+ ///
+ const Content& operator*() const;
+
+ private:
+ ///
+ ///
+ ///
+ class Iterator
+ {
+ public:
+
+ ///
+ ///
+ ///
+ Iterator(const Iterator& itor);
+
+ ///
+ ///
+ ///
+ Iterator(const Encode& encode, const void* data, unsigned int length);
+
+ ///
+ ///
+ ///
+ ~Iterator();
+
+ ///
+ ///
+ ///
+ Codepoint get();
+
+ //Iterator begin();
+ //Iterator end();
+
+ ///
+ ///
+ ///
+ void toBegin();
+
+ ///
+ ///
+ ///
+ void toEnd();
+
+ ///
+ ///
+ ///
+ Codepoint operator *();
+
+ ///
+ ///
+ ///
+ Iterator& operator ++();
+
+ ///
+ ///
+ ///
+ Iterator operator ++(int);
+
+ ///
+ ///
+ ///
+ bool operator !=(const Iterator& itor);
+
+ ///
+ ///
+ ///
+ bool operator ==(const Iterator& itor);
+
+ private:
+
+ ///
+ ///
+ ///
+ void operator = (const Iterator&);
+
+ ///
+ ///
+ ///
+ const Encode encode;
+
+ ///
+ ///
+ ///
+ const Decoder* decoder;
+
+ ///
+ ///
+ ///
+ const void* p;
+
+ ///
+ ///
+ ///
+ const void* const data;
+
+ ///
+ ///
+ ///
+ unsigned int length;
+
+ };
+
+ ///
+ ///
+ ///
+ Content content;
+
+ };
+
+ }
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/texture_font.cpp b/src/libjin/graphics/fonts/texture_font.cpp
index 31e5293..33e3bf1 100644
--- a/src/libjin/graphics/fonts/texture_font.cpp
+++ b/src/libjin/graphics/fonts/texture_font.cpp
@@ -12,298 +12,298 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
+ namespace Graphics
+ {
+ namespace Fonts
+ {
- TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
- : Graphic(bitmap)
- , Font(cellh)
- {
- TextureGlyph glyph;
- Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh);
- glyph.w = cellw;
- glyph.h = cellh;
- for (int y = 0; y < count.row(); ++y)
- {
- glyph.y = y * cellh;
- for (int x = 0; x < count.colum(); ++x)
- {
- glyph.x = x * cellw;
- if (x + y * count.colum() >= codepoints.size())
- return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum()], glyph));
- }
- }
- }
+ TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
+ : Graphic(bitmap)
+ , Font(cellh)
+ {
+ TextureGlyph glyph;
+ Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh);
+ glyph.w = cellw;
+ glyph.h = cellh;
+ for (int y = 0; y < count.row(); ++y)
+ {
+ glyph.y = y * cellh;
+ for (int x = 0; x < count.colum(); ++x)
+ {
+ glyph.x = x * cellw;
+ if (x + y * count.colum() >= codepoints.size())
+ return;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum()], glyph));
+ }
+ }
+ }
- TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
- : Graphic(bitmap)
- , Font(cellh)
- {
- TextureGlyph glyph;
- glyph.h = cellh;
- int w = bitmap->getWidth();
- int h = bitmap->getHeight();
- int i = 0;
- for (int y = 0; y < h; y += cellh)
- {
- glyph.y = y;
- bool newc = false;
- for (int x = 0; x <= w; ++x)
- {
- if (x == w && newc)
- {
- glyph.w = x - glyph.x;
- if (i >= codepoints.size())
- return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
- ++i;
- newc = false;
- break;
- }
- Color c = bitmap->getPixels()[x + y * w];
- if (!newc && c != mask)
- {
- glyph.x = x;
- newc = true;
- }
- else if (newc && c == mask)
- {
- glyph.w = x - glyph.x;
- if (i >= codepoints.size())
- return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
- if (codepoints[i] == 't')
- {
- int a = 10;
- }
- ++i;
- newc = false;
- }
- }
- }
- }
+ TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
+ : Graphic(bitmap)
+ , Font(cellh)
+ {
+ TextureGlyph glyph;
+ glyph.h = cellh;
+ int w = bitmap->getWidth();
+ int h = bitmap->getHeight();
+ int i = 0;
+ for (int y = 0; y < h; y += cellh)
+ {
+ glyph.y = y;
+ bool newc = false;
+ for (int x = 0; x <= w; ++x)
+ {
+ if (x == w && newc)
+ {
+ glyph.w = x - glyph.x;
+ if (i >= codepoints.size())
+ return;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
+ ++i;
+ newc = false;
+ break;
+ }
+ Color c = bitmap->getPixels()[x + y * w];
+ if (!newc && c != mask)
+ {
+ glyph.x = x;
+ newc = true;
+ }
+ else if (newc && c == mask)
+ {
+ glyph.w = x - glyph.x;
+ if (i >= codepoints.size())
+ return;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
+ if (codepoints[i] == 't')
+ {
+ int a = 10;
+ }
+ ++i;
+ newc = false;
+ }
+ }
+ }
+ }
- TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh)
- : TextureFont(bitmap, *text, mask, cellh)
- {
- }
+ TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh)
+ : TextureFont(bitmap, *text, mask, cellh)
+ {
+ }
- TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh)
- : TextureFont(bitmap, *text, cellw, cellh)
- {
- }
+ TextureFont::TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh)
+ : TextureFont(bitmap, *text, cellw, cellh)
+ {
+ }
- TextureFont::~TextureFont()
- {
- }
+ TextureFont::~TextureFont()
+ {
+ }
- const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const
- {
- auto it = glyphs.find(codepoint);
- if (it != glyphs.end())
- {
- return &it->second;
- }
- else
- return nullptr;
- }
+ const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const
+ {
+ auto it = glyphs.find(codepoint);
+ if (it != glyphs.end())
+ {
+ return &it->second;
+ }
+ else
+ return nullptr;
+ }
- Page* TextureFont::typeset(const Content& text, int lineheight, int spacing)
- {
- Page* page = new Page();
- page->font = this;
- vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- int texture = -1;
- const TextureGlyph* glyph = nullptr;
- GlyphVertex vertex;
- Vector2<int> p(0, 0);
- int i = 0;
+ Page* TextureFont::typeset(const Content& text, int lineheight, int spacing)
+ {
+ Page* page = new Page();
+ page->font = this;
+ vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ int texture = -1;
+ const TextureGlyph* glyph = nullptr;
+ GlyphVertex vertex;
+ Vector2<int> p(0, 0);
+ int i = 0;
#define glyphvertices_push(_x, _y, _u, _v) \
- vertex.x = _x; vertex.y = _y;\
- vertex.u = _u; vertex.v = _v;\
- glyphvertices.push_back(vertex);\
+ vertex.x = _x; vertex.y = _y;\
+ vertex.u = _u; vertex.v = _v;\
+ glyphvertices.push_back(vertex);\
- for (Codepoint c : text)
- {
- // return
- if (c == 0x0D) continue;
- // newline
- if (c == 0x0A)
- {
- p.y() += lineheight;
- p.x() = 0;
- continue;
- }
- if (c == 0x09)
- {
- // tab = 4*space
- unsigned cw = getCharWidth(0x20);
- p.x() += cw * 4;
- continue;
- }
- glyph = findGlyph(c);
- if (glyph == nullptr) continue;
- if (texture != getGLTexture())
- {
- texture = getGLTexture();
- GlyphArrayDrawInfo info;
- info.start = i;
- info.count = 0;
- info.texture = texture;
- glyphinfolist.push_back(info);
- }
- glyphinfolist[glyphinfolist.size() - 1].count += 4;
- // normalized
- float w = getWidth(), h = getHeight();
- float nx = glyph->x / w, ny = glyph->y / h;
- float nw = glyph->w / w, nh = glyph->h / h;
- glyphvertices_push(p.x(), p.y(), nx, ny);
- glyphvertices_push(p.x(), p.y() + glyph->h, nx, ny + nh);
- glyphvertices_push(p.x() + glyph->w, p.y() + glyph->h, nx + nw, ny + nh);
- glyphvertices_push(p.x() + glyph->w, p.y(), nx + nw, ny);
- p.x() += glyph->w + spacing;
- i += 4;
- }
- getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing);
- return page;
- }
+ for (Codepoint c : text)
+ {
+ // return
+ if (c == 0x0D) continue;
+ // newline
+ if (c == 0x0A)
+ {
+ p.y() += lineheight;
+ p.x() = 0;
+ continue;
+ }
+ if (c == 0x09)
+ {
+ // tab = 4*space
+ unsigned cw = getCharWidth(0x20);
+ p.x() += cw * 4;
+ continue;
+ }
+ glyph = findGlyph(c);
+ if (glyph == nullptr) continue;
+ if (texture != getGLTexture())
+ {
+ texture = getGLTexture();
+ GlyphArrayDrawInfo info;
+ info.start = i;
+ info.count = 0;
+ info.texture = texture;
+ glyphinfolist.push_back(info);
+ }
+ glyphinfolist[glyphinfolist.size() - 1].count += 4;
+ // normalized
+ float w = getWidth(), h = getHeight();
+ float nx = glyph->x / w, ny = glyph->y / h;
+ float nw = glyph->w / w, nh = glyph->h / h;
+ glyphvertices_push(p.x(), p.y(), nx, ny);
+ glyphvertices_push(p.x(), p.y() + glyph->h, nx, ny + nh);
+ glyphvertices_push(p.x() + glyph->w, p.y() + glyph->h, nx + nw, ny + nh);
+ glyphvertices_push(p.x() + glyph->w, p.y(), nx + nw, ny);
+ p.x() += glyph->w + spacing;
+ i += 4;
+ }
+ getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing);
+ return page;
+ }
- int TextureFont::getCharWidth(int c)
- {
- auto it = glyphs.find(c);
- if (it != glyphs.end())
- {
- return it->second.w;
- }
- return 0;
- }
+ int TextureFont::getCharWidth(int c)
+ {
+ auto it = glyphs.find(c);
+ if (it != glyphs.end())
+ {
+ return it->second.w;
+ }
+ return 0;
+ }
- int TextureFont::getCharHeight(int c)
- {
- auto it = glyphs.find(c);
- if (it != glyphs.end())
- {
- return it->second.h;
- }
- return 0;
- }
+ int TextureFont::getCharHeight(int c)
+ {
+ auto it = glyphs.find(c);
+ if (it != glyphs.end())
+ {
+ return it->second.h;
+ }
+ return 0;
+ }
- int TextureFont::getTextWidth(const Content& t, int spacing)
- {
- int res = 0;
- int tmp = 0;
- for (Codepoint c : t)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- continue;
- }
- if (c == 0x09)
- {
- // tab = 4*space
- unsigned cw = getCharWidth(0x20);
- tmp += cw * 4;
- if (tmp > res) res = tmp;
- continue;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > res) res = tmp;
- }
- return res;
- }
+ int TextureFont::getTextWidth(const Content& t, int spacing)
+ {
+ int res = 0;
+ int tmp = 0;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ continue;
+ }
+ if (c == 0x09)
+ {
+ // tab = 4*space
+ unsigned cw = getCharWidth(0x20);
+ tmp += cw * 4;
+ if (tmp > res) res = tmp;
+ continue;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > res) res = tmp;
+ }
+ return res;
+ }
- int TextureFont::getTextHeight(const Content& t, int lineheight)
- {
- int res = 0;
- bool newline = true;
- for (Codepoint c : t)
- {
- if (c == 0x0A)
- newline = true;
- else if (c == 0x0D);
- else if (newline)
- {
- newline = false;
- res += lineheight;
- }
- }
- return res;
- }
+ int TextureFont::getTextHeight(const Content& t, int lineheight)
+ {
+ int res = 0;
+ bool newline = true;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0A)
+ newline = true;
+ else if (c == 0x0D);
+ else if (newline)
+ {
+ newline = false;
+ res += lineheight;
+ }
+ }
+ return res;
+ }
- void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
- {
- *w = 0;
- *h = 0;
- int tmp = 0;
- bool newline = true;
- for (Codepoint c : text)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- newline = true;
- continue;
- }
- else if (newline)
- {
- newline = false;
- *h += lineheight;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > *w)
- *w = tmp;
- }
- }
+ void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
+ {
+ *w = 0;
+ *h = 0;
+ int tmp = 0;
+ bool newline = true;
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ newline = true;
+ continue;
+ }
+ else if (newline)
+ {
+ newline = false;
+ *h += lineheight;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > *w)
+ *w = tmp;
+ }
+ }
- Page* TextureFont::typeset(const Text& text, int lineheight, int spacing)
- {
- return typeset(*text, lineheight, spacing);
- }
+ Page* TextureFont::typeset(const Text& text, int lineheight, int spacing)
+ {
+ return typeset(*text, lineheight, spacing);
+ }
- void TextureFont::render(const Page* page, int x, int y)
- {
- Shader* shader = gl.getShader();
- const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0);
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
- for (int i = 0; i < glyphinfolist.size(); ++i)
- {
- const GlyphArrayDrawInfo& info = glyphinfolist[i];
- shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x)
- .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
- gl.bindTexture2D(info.texture);
- gl.drawArrays(GL_QUADS, 0, info.count);
- }
- shader->end();
- }
+ void TextureFont::render(const Page* page, int x, int y)
+ {
+ Shader* shader = gl.getShader();
+ const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0);
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
+ for (int i = 0; i < glyphinfolist.size(); ++i)
+ {
+ const GlyphArrayDrawInfo& info = glyphinfolist[i];
+ shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x)
+ .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
+ gl.bindTexture2D(info.texture);
+ gl.drawArrays(GL_QUADS, 0, info.count);
+ }
+ shader->end();
+ }
- void TextureFont::render(const Content& text, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(text, lineheight, spacing);
- render(page, x, y);
- delete page;
- }
+ void TextureFont::render(const Content& text, int x, int y, int lineheight, int spacing)
+ {
+ Page* page = typeset(text, lineheight, spacing);
+ render(page, x, y);
+ delete page;
+ }
- void TextureFont::render(const Text& text, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(text, lineheight, spacing);
- render(page, x, y);
- delete page;
- }
+ void TextureFont::render(const Text& text, int x, int y, int lineheight, int spacing)
+ {
+ Page* page = typeset(text, lineheight, spacing);
+ render(page, x, y);
+ delete page;
+ }
- }
- }
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/texture_font.h b/src/libjin/graphics/fonts/texture_font.h
index 1d7f0d2..510badb 100644
--- a/src/libjin/graphics/fonts/texture_font.h
+++ b/src/libjin/graphics/fonts/texture_font.h
@@ -15,117 +15,117 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- ///
- ///
- ///
- class TextureFont : public Font, public Graphic, public Object
- {
- public:
- ///
- ///
- ///
- TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
-
- ///
- ///
- ///
- TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
-
- ///
- ///
- ///
- TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh);
-
- ///
- ///
- ///
- TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh);
-
- ///
- ///
- ///
- ~TextureFont();
-
- ///
- ///
- ///
- Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- void render(const Page* page, int x, int y) override;
-
- ///
- ///
- ///
- void render(const Content& text, int x, int y, int linehgiht, int spacing = 0) override;
-
- ///
- ///
- ///
- void render(const Text& text, int x, int y, int lineheight, int spacing = 0)override;
-
- private:
-
- ///
- ///
- ///
- struct TextureGlyph
- {
- float x, y, w, h;
- };
-
- ///
- ///
- ///
- int getCharWidth(int c);
-
- ///
- ///
- ///
- int getCharHeight(int c);
-
- ///
- ///
- ///
- int getTextWidth(const Content& text, int spacing = 0);
-
- ///
- ///
- ///
- int getTextHeight(const Content& text, int lineheight);
-
- ///
- ///
- ///
- void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
-
- ///
- ///
- ///
- const TextureGlyph* findGlyph(Codepoint codepoint) const;
-
-
- ///
- ///
- ///
- std::map<Codepoint, TextureGlyph> glyphs;
-
- };
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ ///
+ ///
+ ///
+ class TextureFont : public Font, public Graphic, public Object
+ {
+ public:
+ ///
+ ///
+ ///
+ TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
+
+ ///
+ ///
+ ///
+ TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
+
+ ///
+ ///
+ ///
+ TextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh);
+
+ ///
+ ///
+ ///
+ TextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh);
+
+ ///
+ ///
+ ///
+ ~TextureFont();
+
+ ///
+ ///
+ ///
+ Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ void render(const Page* page, int x, int y) override;
+
+ ///
+ ///
+ ///
+ void render(const Content& text, int x, int y, int linehgiht, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ void render(const Text& text, int x, int y, int lineheight, int spacing = 0)override;
+
+ private:
+
+ ///
+ ///
+ ///
+ struct TextureGlyph
+ {
+ float x, y, w, h;
+ };
+
+ ///
+ ///
+ ///
+ int getCharWidth(int c);
+
+ ///
+ ///
+ ///
+ int getCharHeight(int c);
+
+ ///
+ ///
+ ///
+ int getTextWidth(const Content& text, int spacing = 0);
+
+ ///
+ ///
+ ///
+ int getTextHeight(const Content& text, int lineheight);
+
+ ///
+ ///
+ ///
+ void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
+
+ ///
+ ///
+ ///
+ const TextureGlyph* findGlyph(Codepoint codepoint) const;
+
+
+ ///
+ ///
+ ///
+ std::map<Codepoint, TextureGlyph> glyphs;
+
+ };
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/ttf.cpp b/src/libjin/graphics/fonts/ttf.cpp
index 1357810..b540fda 100644
--- a/src/libjin/graphics/fonts/ttf.cpp
+++ b/src/libjin/graphics/fonts/ttf.cpp
@@ -19,438 +19,438 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // TTFData
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TTFData::TTFData(const unsigned char* d, unsigned int s)
- {
- raw.size = s;
- raw.data = (unsigned char*)malloc(s);
- memcpy(raw.data, d, s);
- if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0))
- {
- delete raw.data;
- throw 0;
- }
- /* push default fontsize */
- pushTTFsize(FONT_SIZE);
- }
-
- TTFData::~TTFData()
- {
- free(raw.data);
- }
-
- TTF* TTFData::createTTF(unsigned fontSize)
- {
- TTF* ttf;
- try
- {
- ttf = new TTF(this, fontSize);
- }
- catch (...)
- {
- return nullptr;
- }
- return ttf;
- }
-
- /*
- * (0, 0)
- * +--------------+ ascent
- * | +--------+ |
- * | | | |
- * | | bitmap | |
- * +--|--------|--+ baseline
- * | +--------+ |
- * +--|-----------+ decent
- * | |
- * leftSideBearing |
- * advanceWidth
- */
- void TTFData::getVMetrics(int* baseline, int* descent)
- {
- float scale = scales.back();
- int ascent;
- stbtt_GetFontVMetrics(&info, &ascent, descent, 0);
- *baseline = (int)(ascent*scale) + 1; // slight adjustment
- *descent = *baseline - (int)(*descent*scale) + 1;
- }
-
- void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing)
- {
- float scale = scales.back();
- int adw, lsb;
- stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb);
- *advanceWidth = (int)(adw*scale);
- *leftSideBearing = (int)(lsb*scale);
- }
-
- void TTFData::pushTTFsize(unsigned int fs)
- {
- float sc = stbtt_ScaleForPixelHeight(&info, fs);
- scales.push_back(sc);
- }
-
- void TTFData::popTTFsize()
- {
- /* always keep default ttf size on the bottom of stack */
- if (scales.size() > 1)
- scales.pop_back();
- }
-
- Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
- {
- float scale = scales.back();
- Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
- return bitmap;
- }
-
- Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
- {
- float scale = scales.back();
- Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
- int w = *width, h = *height;
- //int xo = *xoff, yo = *yoff;
- Color* bitmap32 = new Color[w*h];
- for (int y = 0; y < h; ++y)
- {
- for (int x = 0; x < w; ++x)
- {
- bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]);
- }
- }
- free(bitmap);
- return bitmap32;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // TTF
- //////////////////////////////////////////////////////////////////////////////////////////////////////
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TTFData
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TTFData::TTFData(const unsigned char* d, unsigned int s)
+ {
+ raw.size = s;
+ raw.data = (unsigned char*)malloc(s);
+ memcpy(raw.data, d, s);
+ if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0))
+ {
+ delete raw.data;
+ throw 0;
+ }
+ /* push default fontsize */
+ pushTTFsize(FONT_SIZE);
+ }
+
+ TTFData::~TTFData()
+ {
+ free(raw.data);
+ }
+
+ TTF* TTFData::createTTF(unsigned fontSize)
+ {
+ TTF* ttf;
+ try
+ {
+ ttf = new TTF(this, fontSize);
+ }
+ catch (...)
+ {
+ return nullptr;
+ }
+ return ttf;
+ }
+
+ /*
+ * (0, 0)
+ * +--------------+ ascent
+ * | +--------+ |
+ * | | | |
+ * | | bitmap | |
+ * +--|--------|--+ baseline
+ * | +--------+ |
+ * +--|-----------+ decent
+ * | |
+ * leftSideBearing |
+ * advanceWidth
+ */
+ void TTFData::getVMetrics(int* baseline, int* descent)
+ {
+ float scale = scales.back();
+ int ascent;
+ stbtt_GetFontVMetrics(&info, &ascent, descent, 0);
+ *baseline = (int)(ascent*scale) + 1; // slight adjustment
+ *descent = *baseline - (int)(*descent*scale) + 1;
+ }
+
+ void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing)
+ {
+ float scale = scales.back();
+ int adw, lsb;
+ stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb);
+ *advanceWidth = (int)(adw*scale);
+ *leftSideBearing = (int)(lsb*scale);
+ }
+
+ void TTFData::pushTTFsize(unsigned int fs)
+ {
+ float sc = stbtt_ScaleForPixelHeight(&info, fs);
+ scales.push_back(sc);
+ }
+
+ void TTFData::popTTFsize()
+ {
+ /* always keep default ttf size on the bottom of stack */
+ if (scales.size() > 1)
+ scales.pop_back();
+ }
+
+ Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
+ {
+ float scale = scales.back();
+ Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
+ return bitmap;
+ }
+
+ Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
+ {
+ float scale = scales.back();
+ Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
+ int w = *width, h = *height;
+ //int xo = *xoff, yo = *yoff;
+ Color* bitmap32 = new Color[w*h];
+ for (int y = 0; y < h; ++y)
+ {
+ for (int x = 0; x < w; ++x)
+ {
+ bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]);
+ }
+ }
+ free(bitmap);
+ return bitmap32;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TTF
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
#include "../shaders/built-in/font.shader.h"
- using namespace std;
- using namespace JinEngine::Math;
-
- const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 };
- const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 };
-
- /* little endian unicode */
- static const char* unicodeLittleEndian(const char* p, unsigned* res)
- {
- }
-
- //TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie)
- //{
- // TTF* ttf;
- // try
- // {
- // ttf = new TTF(fontData, fontSzie);
- // }
- // catch (...)
- // {
- // return nullptr;
- // }
- // return ttf;
- //}
-
- TTF::TTF(TTFData* f, unsigned int fontSize)
- : Font(fontSize)
- , cursor(0, 0)
- , ttf(f)
- {
- ttf->pushTTFsize(fontSize);
- ttf->getVMetrics(&baseline, &descent);
- estimateSize();
- ttf->popTTFsize();
- /* create a default texture */
- createAtlas();
- }
-
- /* estimate the size of atlas texture */
- void TTF::estimateSize()
- {
- for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level)
- {
- if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level])
- {
- textureWidth = TEXTURE_WIDTHS[level];
- textureHeight = TEXTURE_HEIGHTS[level];
- break;
- }
- }
- }
-
- TTF::~TTF()
- {
- }
-
- GLuint TTF::createAtlas()
- {
- GLuint t;
- gl.flushError();
- t = gl.genTexture();
- gl.bindTexture2D(t);
- gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE);
- if (glGetError() != GL_NO_ERROR)
- {
- glDeleteTextures(1, &t);
-
- return 0;
- }
- atlases.push_back(t);
-
- return t;
- }
-
- void TTF::render(const Content& t, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(t, lineheight, spacing);
- render(page, x, y);
- delete page;
- }
-
- Page* TTF::typeset(const Content& text, int lineheight, int spacing)
- {
- Page* page = new Page();
- page->font = this;
- vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- int texture = -1;
- TTFGlyph* glyph = nullptr;
- GlyphVertex vertex;
- Vector2<int> p(0, 0);
- int i = 0;
-
- #define glyphvertices_push(_x, _y, _u, _v) \
- vertex.x = _x; vertex.y = _y;\
- vertex.u = _u; vertex.v = _v;\
- glyphvertices.push_back(vertex);
-
- #define glyphlize(c)\
- do{\
- glyph = &findGlyph(c); \
- if (texture != glyph->atlas) \
- { \
- GlyphArrayDrawInfo info; \
- info.start = i; \
- info.count = 0; \
- info.texture = glyph->atlas; \
- texture = glyph->atlas; \
- glyphinfolist.push_back(info); \
- } \
- glyphinfolist[glyphinfolist.size() - 1].count += 4; \
- TTFGlyph::Bbox& bbox = glyph->bbox; \
- glyphvertices_push(p.x(), p.y(), bbox.x, bbox.y); \
- glyphvertices_push(p.x(), p.y() + glyph->height, bbox.x, bbox.y + bbox.h); \
- glyphvertices_push(p.x() + glyph->width, p.y() + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \
- glyphvertices_push(p.x() + glyph->width, p.y(), bbox.x + bbox.w, bbox.y); \
- }while(0)
-
- for (Codepoint c : text)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- /* new line */
- p.y() += lineheight;
- p.x() = 0;
- continue;
- }
- if (c == 0x09)
- {
- // tab = 4*space
- unsigned cw = getCharWidth(0x20);
- p.x() += cw * 4;
- continue;
- }
- glyphlize(c);
- p.x() += glyph->width + spacing;
- i += 4;
- }
- getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing);
- return page;
- }
-
- Page* TTF::typeset(const Text& text, int lineheight, int spacing)
- {
- return typeset(*text, lineheight, spacing);
- }
-
- void TTF::render(const Page* page, int x, int y)
- {
- Shader* shader = gl.getShader();
- const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0);
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
- for (int i = 0; i < glyphinfolist.size(); ++i)
- {
- const GlyphArrayDrawInfo& info = glyphinfolist[i];
- shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x)
- .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
- gl.bindTexture2D(info.texture);
- gl.drawArrays(GL_QUADS, 0, info.count);
-
- }
- shader->end();
- }
-
- void TTF::render(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */)
- {
- render(*text, x, y, lineheight, spacing);
- }
-
- int TTF::getCharWidth(int c)
- {
- int adw, lsb;
- ttf->pushTTFsize(mFontSize);
- ttf->getHMetrics(c, &adw, &lsb);
- ttf->popTTFsize();
- return adw;
- }
-
- int TTF::getCharHeight(int c)
- {
- return descent;
- }
-
- int TTF::getTextWidth(const Content& t, int spacing)
- {
- ttf->pushTTFsize(mFontSize);
- int res = 0;
- int tmp = 0;
- for (Codepoint c : t)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- continue;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > res)
- res = tmp;
- }
- ttf->popTTFsize();
- return res;
- }
-
- int TTF::getTextHeight(const Content& t, int lineheight)
- {
- ttf->pushTTFsize(mFontSize);
- int res = 0;
- bool newline = true;
- for (Codepoint c : t)
- {
- if (c == 0x0A)
- newline = true;
- else if (c == 0x0D);
- else if (newline)
- {
- newline = false;
- res += lineheight;
- }
- }
- ttf->popTTFsize();
- return res;
- }
-
- void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
- {
- ttf->pushTTFsize(mFontSize);
- *w = 0;
- *h = 0;
- int tmp = 0;
- bool newline = true;
- for (Codepoint c : text)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- newline = true;
- continue;
- }
- else if (newline)
- {
- newline = false;
- *h += lineheight;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > *w)
- *w = tmp;
- }
- ttf->popTTFsize();
- }
-
- TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character)
- {
- int w, h, xoff, yoff;
- ttf->pushTTFsize(mFontSize);
- GLuint atlas = atlases.back();
- const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff);
- int adw, lsb;
- {
- /* bake glyph */
- ttf->getHMetrics(character, &adw, &lsb);
- ttf->popTTFsize();
- if (cursor.x() + adw > textureWidth)
- {
- cursor.x() = 0;
- cursor.y() += descent;
- if (cursor.y() + descent * 2 > textureHeight)
- {
- /* create new atlas */
- atlas = createAtlas();
- cursor.y() = 0;
- }
- }
- gl.bindTexture2D(atlas);
- gl.texSubImage(cursor.x() + xoff, cursor.y() + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
- gl.bindTexture2D();
- delete[] bitmap;
- }
- TTFGlyph glyph;
- glyph.atlas = atlas;
- glyph.bbox.x = cursor.x() / (float)textureWidth;
- glyph.bbox.y = cursor.y() / (float)textureHeight;
- glyph.bbox.w = adw / (float)textureWidth;
- glyph.bbox.h = descent / (float)textureHeight;
- glyph.width = adw;
- glyph.height = descent;
- glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph));
- cursor.x() += adw;
- return glyphs[character];
- }
-
- TTF::TTFGlyph& TTF::findGlyph(unsigned int character)
- {
- map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character);
- if (it != glyphs.end())
- return it->second;
- else
- return bakeGlyph(character);
- }
-
- } // namespace Fonts
- } // namespace Graphics
+ using namespace std;
+ using namespace JinEngine::Math;
+
+ const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 };
+ const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 };
+
+ /* little endian unicode */
+ static const char* unicodeLittleEndian(const char* p, unsigned* res)
+ {
+ }
+
+ //TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie)
+ //{
+ // TTF* ttf;
+ // try
+ // {
+ // ttf = new TTF(fontData, fontSzie);
+ // }
+ // catch (...)
+ // {
+ // return nullptr;
+ // }
+ // return ttf;
+ //}
+
+ TTF::TTF(TTFData* f, unsigned int fontSize)
+ : Font(fontSize)
+ , cursor(0, 0)
+ , ttf(f)
+ {
+ ttf->pushTTFsize(fontSize);
+ ttf->getVMetrics(&baseline, &descent);
+ estimateSize();
+ ttf->popTTFsize();
+ /* create a default texture */
+ createAtlas();
+ }
+
+ /* estimate the size of atlas texture */
+ void TTF::estimateSize()
+ {
+ for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level)
+ {
+ if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level])
+ {
+ textureWidth = TEXTURE_WIDTHS[level];
+ textureHeight = TEXTURE_HEIGHTS[level];
+ break;
+ }
+ }
+ }
+
+ TTF::~TTF()
+ {
+ }
+
+ GLuint TTF::createAtlas()
+ {
+ GLuint t;
+ gl.flushError();
+ t = gl.genTexture();
+ gl.bindTexture2D(t);
+ gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ glDeleteTextures(1, &t);
+
+ return 0;
+ }
+ atlases.push_back(t);
+
+ return t;
+ }
+
+ void TTF::render(const Content& t, int x, int y, int lineheight, int spacing)
+ {
+ Page* page = typeset(t, lineheight, spacing);
+ render(page, x, y);
+ delete page;
+ }
+
+ Page* TTF::typeset(const Content& text, int lineheight, int spacing)
+ {
+ Page* page = new Page();
+ page->font = this;
+ vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ int texture = -1;
+ TTFGlyph* glyph = nullptr;
+ GlyphVertex vertex;
+ Vector2<int> p(0, 0);
+ int i = 0;
+
+ #define glyphvertices_push(_x, _y, _u, _v) \
+ vertex.x = _x; vertex.y = _y;\
+ vertex.u = _u; vertex.v = _v;\
+ glyphvertices.push_back(vertex);
+
+ #define glyphlize(c)\
+ do{\
+ glyph = &findGlyph(c); \
+ if (texture != glyph->atlas) \
+ { \
+ GlyphArrayDrawInfo info; \
+ info.start = i; \
+ info.count = 0; \
+ info.texture = glyph->atlas; \
+ texture = glyph->atlas; \
+ glyphinfolist.push_back(info); \
+ } \
+ glyphinfolist[glyphinfolist.size() - 1].count += 4; \
+ TTFGlyph::Bbox& bbox = glyph->bbox; \
+ glyphvertices_push(p.x(), p.y(), bbox.x, bbox.y); \
+ glyphvertices_push(p.x(), p.y() + glyph->height, bbox.x, bbox.y + bbox.h); \
+ glyphvertices_push(p.x() + glyph->width, p.y() + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \
+ glyphvertices_push(p.x() + glyph->width, p.y(), bbox.x + bbox.w, bbox.y); \
+ }while(0)
+
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ /* new line */
+ p.y() += lineheight;
+ p.x() = 0;
+ continue;
+ }
+ if (c == 0x09)
+ {
+ // tab = 4*space
+ unsigned cw = getCharWidth(0x20);
+ p.x() += cw * 4;
+ continue;
+ }
+ glyphlize(c);
+ p.x() += glyph->width + spacing;
+ i += 4;
+ }
+ getTextBox(text, &page->size.w(), &page->size.h(), lineheight, spacing);
+ return page;
+ }
+
+ Page* TTF::typeset(const Text& text, int lineheight, int spacing)
+ {
+ return typeset(*text, lineheight, spacing);
+ }
+
+ void TTF::render(const Page* page, int x, int y)
+ {
+ Shader* shader = gl.getShader();
+ const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ Matrix modelMatrix = gl.getModelViewMatrix(x, y, 1, 1, 0, 0, 0);
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
+ for (int i = 0; i < glyphinfolist.size(); ++i)
+ {
+ const GlyphArrayDrawInfo& info = glyphinfolist[i];
+ shader->uploadVertices(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x)
+ .uploadUV(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
+ gl.bindTexture2D(info.texture);
+ gl.drawArrays(GL_QUADS, 0, info.count);
+
+ }
+ shader->end();
+ }
+
+ void TTF::render(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */)
+ {
+ render(*text, x, y, lineheight, spacing);
+ }
+
+ int TTF::getCharWidth(int c)
+ {
+ int adw, lsb;
+ ttf->pushTTFsize(mFontSize);
+ ttf->getHMetrics(c, &adw, &lsb);
+ ttf->popTTFsize();
+ return adw;
+ }
+
+ int TTF::getCharHeight(int c)
+ {
+ return descent;
+ }
+
+ int TTF::getTextWidth(const Content& t, int spacing)
+ {
+ ttf->pushTTFsize(mFontSize);
+ int res = 0;
+ int tmp = 0;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ continue;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > res)
+ res = tmp;
+ }
+ ttf->popTTFsize();
+ return res;
+ }
+
+ int TTF::getTextHeight(const Content& t, int lineheight)
+ {
+ ttf->pushTTFsize(mFontSize);
+ int res = 0;
+ bool newline = true;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0A)
+ newline = true;
+ else if (c == 0x0D);
+ else if (newline)
+ {
+ newline = false;
+ res += lineheight;
+ }
+ }
+ ttf->popTTFsize();
+ return res;
+ }
+
+ void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
+ {
+ ttf->pushTTFsize(mFontSize);
+ *w = 0;
+ *h = 0;
+ int tmp = 0;
+ bool newline = true;
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ newline = true;
+ continue;
+ }
+ else if (newline)
+ {
+ newline = false;
+ *h += lineheight;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > *w)
+ *w = tmp;
+ }
+ ttf->popTTFsize();
+ }
+
+ TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character)
+ {
+ int w, h, xoff, yoff;
+ ttf->pushTTFsize(mFontSize);
+ GLuint atlas = atlases.back();
+ const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff);
+ int adw, lsb;
+ {
+ /* bake glyph */
+ ttf->getHMetrics(character, &adw, &lsb);
+ ttf->popTTFsize();
+ if (cursor.x() + adw > textureWidth)
+ {
+ cursor.x() = 0;
+ cursor.y() += descent;
+ if (cursor.y() + descent * 2 > textureHeight)
+ {
+ /* create new atlas */
+ atlas = createAtlas();
+ cursor.y() = 0;
+ }
+ }
+ gl.bindTexture2D(atlas);
+ gl.texSubImage(cursor.x() + xoff, cursor.y() + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
+ gl.bindTexture2D();
+ delete[] bitmap;
+ }
+ TTFGlyph glyph;
+ glyph.atlas = atlas;
+ glyph.bbox.x = cursor.x() / (float)textureWidth;
+ glyph.bbox.y = cursor.y() / (float)textureHeight;
+ glyph.bbox.w = adw / (float)textureWidth;
+ glyph.bbox.h = descent / (float)textureHeight;
+ glyph.width = adw;
+ glyph.height = descent;
+ glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph));
+ cursor.x() += adw;
+ return glyphs[character];
+ }
+
+ TTF::TTFGlyph& TTF::findGlyph(unsigned int character)
+ {
+ map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character);
+ if (it != glyphs.end())
+ return it->second;
+ else
+ return bakeGlyph(character);
+ }
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/fonts/ttf.h b/src/libjin/graphics/fonts/ttf.h
index 8439cd7..5b137ff 100644
--- a/src/libjin/graphics/fonts/ttf.h
+++ b/src/libjin/graphics/fonts/ttf.h
@@ -19,266 +19,266 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Fonts
- {
-
- class TTF;
-
- //
- // TTFData
- // |- TTF(14px)
- // |- TTF(15px)
- // .
- // .
- // .
- //
- class TTFData : public Object
- {
- public:
- ///
- ///
- ///
- TTFData(const unsigned char* data, unsigned int size);
-
- ///
- ///
- ///
- ~TTFData();
-
- ///
- ///
- ///
- TTF* createTTF(unsigned ttfsize);
-
- ///
- ///
- ///
- void pushTTFsize(unsigned ttfsize);
-
- ///
- ///
- ///
- void popTTFsize();
-
- ///
- ///
- ///
- Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
-
- ///
- ///
- ///
- Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
-
- ///
- ///
- ///
- void getVMetrics(int* baseline, int* descent);
-
- ///
- ///
- ///
- void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing);
-
- private:
-
- ///
- ///
- ///
- static const unsigned int FONT_SIZE = 12;
-
- ///
- ///
- ///
- stbtt_fontinfo info;
-
- ///
- ///
- ///
- struct
- {
- unsigned char* data;
- unsigned int size;
- } raw;
-
- ///
- ///
- ///
- std::vector<float> scales;
-
- };
-
- class TTF : public Font, public Object
- {
- public:
- //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie);
-
- ///
- ///
- ///
- Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- void render(const Text& text, int x, int y, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- void render(const Content& text, int x, int y, int lineheight, int spacing = 0) override;
-
- ///
- ///
- ///
- void render(const Page* page, int x, int y) override;
-
- ///
- ///
- ///
- ~TTF();
-
- private:
-
- friend class TTFData;
-
- ///
- ///
- ///
- struct TTFGlyph
- {
- GLuint atlas;
- // normalized coordinates
- struct Bbox
- {
- float x, y;
- float w, h;
- } bbox;
- // glyph size in pixel
- unsigned int width, height;
- };
-
- ///
- ///
- ///
- static const int TEXTURE_SIZE_LEVELS_COUNT = 7;
-
- ///
- ///
- ///
- static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1;
-
- ///
- ///
- ///
- static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT];
-
- ///
- ///
- ///
- static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT];
-
- ///
- ///
- ///
- TTF(TTFData* ttf, Codepoint ttfSize);
-
- ///
- ///
- ///
- void estimateSize();
-
- ///
- ///
- ///
- GLuint createAtlas();
-
- ///
- ///
- ///
- TTFGlyph& bakeGlyph(Codepoint character);
-
- ///
- ///
- ///
- TTFGlyph& findGlyph(Codepoint character);
-
- ///
- ///
- ///
- int getCharWidth(int c);
-
- ///
- ///
- ///
- int getCharHeight(int c);
-
- ///
- ///
- ///
- int getTextWidth(const Content& text, int spacing = 0);
-
- ///
- ///
- ///
- int getTextHeight(const Content& text, int lineheight);
-
- ///
- ///
- ///
- void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
-
- ///
- ///
- ///
- int textureWidth;
-
- ///
- ///
- ///
- int textureHeight;
-
- ///
- ///
- ///
- std::vector<GLuint> atlases;
-
- ///
- ///
- ///
- std::map<Codepoint, TTFGlyph> glyphs;
-
- ///
- ///
- ///
- TTFData* ttf;
-
- ///
- ///
- ///
- int baseline;
-
- ///
- ///
- ///
- int descent;
-
- ///
- ///
- ///
- Math::Vector2<float> cursor;
-
- };
-
- } // namespace Fonts
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Fonts
+ {
+
+ class TTF;
+
+ //
+ // TTFData
+ // |- TTF(14px)
+ // |- TTF(15px)
+ // .
+ // .
+ // .
+ //
+ class TTFData : public Object
+ {
+ public:
+ ///
+ ///
+ ///
+ TTFData(const unsigned char* data, unsigned int size);
+
+ ///
+ ///
+ ///
+ ~TTFData();
+
+ ///
+ ///
+ ///
+ TTF* createTTF(unsigned ttfsize);
+
+ ///
+ ///
+ ///
+ void pushTTFsize(unsigned ttfsize);
+
+ ///
+ ///
+ ///
+ void popTTFsize();
+
+ ///
+ ///
+ ///
+ Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
+
+ ///
+ ///
+ ///
+ Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
+
+ ///
+ ///
+ ///
+ void getVMetrics(int* baseline, int* descent);
+
+ ///
+ ///
+ ///
+ void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing);
+
+ private:
+
+ ///
+ ///
+ ///
+ static const unsigned int FONT_SIZE = 12;
+
+ ///
+ ///
+ ///
+ stbtt_fontinfo info;
+
+ ///
+ ///
+ ///
+ struct
+ {
+ unsigned char* data;
+ unsigned int size;
+ } raw;
+
+ ///
+ ///
+ ///
+ std::vector<float> scales;
+
+ };
+
+ class TTF : public Font, public Object
+ {
+ public:
+ //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie);
+
+ ///
+ ///
+ ///
+ Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ void render(const Text& text, int x, int y, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ void render(const Content& text, int x, int y, int lineheight, int spacing = 0) override;
+
+ ///
+ ///
+ ///
+ void render(const Page* page, int x, int y) override;
+
+ ///
+ ///
+ ///
+ ~TTF();
+
+ private:
+
+ friend class TTFData;
+
+ ///
+ ///
+ ///
+ struct TTFGlyph
+ {
+ GLuint atlas;
+ // normalized coordinates
+ struct Bbox
+ {
+ float x, y;
+ float w, h;
+ } bbox;
+ // glyph size in pixel
+ unsigned int width, height;
+ };
+
+ ///
+ ///
+ ///
+ static const int TEXTURE_SIZE_LEVELS_COUNT = 7;
+
+ ///
+ ///
+ ///
+ static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1;
+
+ ///
+ ///
+ ///
+ static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT];
+
+ ///
+ ///
+ ///
+ static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT];
+
+ ///
+ ///
+ ///
+ TTF(TTFData* ttf, Codepoint ttfSize);
+
+ ///
+ ///
+ ///
+ void estimateSize();
+
+ ///
+ ///
+ ///
+ GLuint createAtlas();
+
+ ///
+ ///
+ ///
+ TTFGlyph& bakeGlyph(Codepoint character);
+
+ ///
+ ///
+ ///
+ TTFGlyph& findGlyph(Codepoint character);
+
+ ///
+ ///
+ ///
+ int getCharWidth(int c);
+
+ ///
+ ///
+ ///
+ int getCharHeight(int c);
+
+ ///
+ ///
+ ///
+ int getTextWidth(const Content& text, int spacing = 0);
+
+ ///
+ ///
+ ///
+ int getTextHeight(const Content& text, int lineheight);
+
+ ///
+ ///
+ ///
+ void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
+
+ ///
+ ///
+ ///
+ int textureWidth;
+
+ ///
+ ///
+ ///
+ int textureHeight;
+
+ ///
+ ///
+ ///
+ std::vector<GLuint> atlases;
+
+ ///
+ ///
+ ///
+ std::map<Codepoint, TTFGlyph> glyphs;
+
+ ///
+ ///
+ ///
+ TTFData* ttf;
+
+ ///
+ ///
+ ///
+ int baseline;
+
+ ///
+ ///
+ ///
+ int descent;
+
+ ///
+ ///
+ ///
+ Math::Vector2<float> cursor;
+
+ };
+
+ } // namespace Fonts
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics)
diff --git a/src/libjin/graphics/graphic.cpp b/src/libjin/graphics/graphic.cpp
index 7659e4e..67e416a 100644
--- a/src/libjin/graphics/graphic.cpp
+++ b/src/libjin/graphics/graphic.cpp
@@ -14,132 +14,132 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
-
- Graphic::Graphic(int w, int h)
- : mTexture(0)
- , mSize(w, h)
- {
- mTexture = gl.genTexture();
- }
-
- Graphic::Graphic(const Bitmap* bitmap)
- : mTexture(0)
- {
- mSize.w() = bitmap->getWidth();
- mSize.h() = bitmap->getHeight();
-
- const Color* pixels = bitmap->getPixels();
-
- mTexture = gl.genTexture();
- gl.bindTexture2D(mTexture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl.texImage(GL_RGBA8, mSize.w(), mSize.h(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- }
-
- Graphic::~Graphic()
- {
- glDeleteTextures(1, &mTexture);
- }
-
- void Graphic::setFilter(GLint min_filter, GLint max_filter)
- {
- gl.bindTexture2D(mTexture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
- }
-
- void Graphic::render(float x, float y, float sx, float sy, float r, float ox, float oy) const
- {
- Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy);
- int w = getWidth(), h = getHeight();
- static float vertexCoords[8];
- static float textureCoords[8];
- // Set vertex coordinates.
- vertexCoords[0] = 0; vertexCoords[1] = 0;
- vertexCoords[2] = 0; vertexCoords[3] = h;
- vertexCoords[4] = w; vertexCoords[5] = h;
- vertexCoords[6] = w; vertexCoords[7] = 0;
- // Set texture coordinates.
- textureCoords[0] = 0; textureCoords[1] = 0;
- textureCoords[2] = 0; textureCoords[3] = 1;
- textureCoords[4] = 1; textureCoords[5] = 1;
- textureCoords[6] = 1; textureCoords[7] = 0;
- // Set shader.
- Shader* shader = gl.getShader();
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
- .uploadVertices(2, GL_FLOAT, 0, vertexCoords)
- .uploadUV(2, GL_FLOAT, 0, textureCoords);
-
- gl.bindTexture2D(mTexture);
- gl.drawArrays(GL_QUADS, 0, 4);
-
- shader->end();
- }
-
- void Graphic::render(const Math::Quad& slice, float x, float y, float sx, float sy, float r, float ax, float ay) const
- {
- static float vertexCoords[8];
- static float textureCoords[8];
-
- // Set vertex coordinates.
- vertexCoords[0] = 0; vertexCoords[1] = 0;
- vertexCoords[2] = 0; vertexCoords[3] = slice.h;
- vertexCoords[4] = slice.w; vertexCoords[5] = slice.h;
- vertexCoords[6] = slice.w; vertexCoords[7] = 0;
- // Set texture coordinates.
- float slx = slice.x / mSize.w();
- float sly = slice.y / mSize.h();
- float slw = slice.w / mSize.w();
- float slh = slice.h / mSize.h();
- textureCoords[0] = slx; textureCoords[1] = sly;
- textureCoords[2] = slx; textureCoords[3] = sly + slh;
- textureCoords[4] = slx + slw; textureCoords[5] = sly + slh;
- textureCoords[6] = slx + slw; textureCoords[7] = sly;
-
- Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ax, ay);
-
- Shader* shader = gl.getShader();
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
- .uploadVertices(2, GL_FLOAT, 0, vertexCoords)
- .uploadUV(2, GL_FLOAT, 0, textureCoords);
-
- gl.bindTexture2D(mTexture);
- gl.drawArrays(GL_QUADS, 0, 4);
-
- shader->end();
- }
-
- 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_)
- //}
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ Graphic::Graphic(int w, int h)
+ : mTexture(0)
+ , mSize(w, h)
+ {
+ mTexture = gl.genTexture();
+ }
+
+ Graphic::Graphic(const Bitmap* bitmap)
+ : mTexture(0)
+ {
+ mSize.w() = bitmap->getWidth();
+ mSize.h() = bitmap->getHeight();
+
+ const Color* pixels = bitmap->getPixels();
+
+ mTexture = gl.genTexture();
+ gl.bindTexture2D(mTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl.texImage(GL_RGBA8, mSize.w(), mSize.h(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
+
+ Graphic::~Graphic()
+ {
+ glDeleteTextures(1, &mTexture);
+ }
+
+ void Graphic::setFilter(GLint min_filter, GLint max_filter)
+ {
+ gl.bindTexture2D(mTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
+ }
+
+ void Graphic::render(float x, float y, float sx, float sy, float r, float ox, float oy) const
+ {
+ Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy);
+ int w = getWidth(), h = getHeight();
+ static float vertexCoords[8];
+ static float textureCoords[8];
+ // Set vertex coordinates.
+ vertexCoords[0] = 0; vertexCoords[1] = 0;
+ vertexCoords[2] = 0; vertexCoords[3] = h;
+ vertexCoords[4] = w; vertexCoords[5] = h;
+ vertexCoords[6] = w; vertexCoords[7] = 0;
+ // Set texture coordinates.
+ textureCoords[0] = 0; textureCoords[1] = 0;
+ textureCoords[2] = 0; textureCoords[3] = 1;
+ textureCoords[4] = 1; textureCoords[5] = 1;
+ textureCoords[6] = 1; textureCoords[7] = 0;
+ // Set shader.
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
+ .uploadVertices(2, GL_FLOAT, 0, vertexCoords)
+ .uploadUV(2, GL_FLOAT, 0, textureCoords);
+
+ gl.bindTexture2D(mTexture);
+ gl.drawArrays(GL_QUADS, 0, 4);
+
+ shader->end();
+ }
+
+ void Graphic::render(const Math::Quad& slice, float x, float y, float sx, float sy, float r, float ax, float ay) const
+ {
+ static float vertexCoords[8];
+ static float textureCoords[8];
+
+ // Set vertex coordinates.
+ vertexCoords[0] = 0; vertexCoords[1] = 0;
+ vertexCoords[2] = 0; vertexCoords[3] = slice.h;
+ vertexCoords[4] = slice.w; vertexCoords[5] = slice.h;
+ vertexCoords[6] = slice.w; vertexCoords[7] = 0;
+ // Set texture coordinates.
+ float slx = slice.x / mSize.w();
+ float sly = slice.y / mSize.h();
+ float slw = slice.w / mSize.w();
+ float slh = slice.h / mSize.h();
+ textureCoords[0] = slx; textureCoords[1] = sly;
+ textureCoords[2] = slx; textureCoords[3] = sly + slh;
+ textureCoords[4] = slx + slw; textureCoords[5] = sly + slh;
+ textureCoords[6] = slx + slw; textureCoords[7] = sly;
+
+ Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ax, ay);
+
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
+ .uploadVertices(2, GL_FLOAT, 0, vertexCoords)
+ .uploadUV(2, GL_FLOAT, 0, textureCoords);
+
+ gl.bindTexture2D(mTexture);
+ gl.drawArrays(GL_QUADS, 0, 4);
+
+ shader->end();
+ }
+
+ 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_)
+ //}
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/graphic.h b/src/libjin/graphics/graphic.h
index 857785d..fdb1c9c 100644
--- a/src/libjin/graphics/graphic.h
+++ b/src/libjin/graphics/graphic.h
@@ -14,82 +14,82 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- ///
- /// Class inherites Graphic doesn't keep any state such as origin, scale and other properties. Very low
- /// level visualized resources.
- ///
- class Graphic : public Object, public Renderable
- {
- public:
- ///
- ///
- ///
- Graphic(int w = 0, int h = 0);
-
- ///
- ///
- ///
- Graphic(const Bitmap* bitmap);
-
- ///
- ///
- ///
- virtual ~Graphic();
-
- ///
- ///
- ///
- inline int getWidth() const { return mSize.w(); }
-
- ///
- ///
- ///
- inline int getHeight() const { return mSize.h(); }
-
- ///
- /// Get opengl texture token.
- ///
- /// @return OpenGL texture token.
- ///
- inline GLuint getGLTexture() const { return mTexture; }
-
- ///
- ///
- ///
- void setFilter(GLint min, GLint max);
-
- ///
- /// Render graphic single with given coordinates.
- ///
- void render(float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const;
-
- ///
- /// Render part of graphic single with given coordinates.
- ///
- void render(const Math::Quad& slice, float x, float 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;
-
- private:
- GLuint mTexture;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ ///
+ /// Class inherites Graphic doesn't keep any state such as origin, scale and other properties. Very low
+ /// level visualized resources.
+ ///
+ class Graphic : public Object, public Renderable
+ {
+ public:
+ ///
+ ///
+ ///
+ Graphic(int w = 0, int h = 0);
+
+ ///
+ ///
+ ///
+ Graphic(const Bitmap* bitmap);
+
+ ///
+ ///
+ ///
+ virtual ~Graphic();
+
+ ///
+ ///
+ ///
+ inline int getWidth() const { return mSize.w(); }
+
+ ///
+ ///
+ ///
+ inline int getHeight() const { return mSize.h(); }
+
+ ///
+ /// Get opengl texture token.
+ ///
+ /// @return OpenGL texture token.
+ ///
+ inline GLuint getGLTexture() const { return mTexture; }
+
+ ///
+ ///
+ ///
+ void setFilter(GLint min, GLint max);
+
+ ///
+ /// Render graphic single with given coordinates.
+ ///
+ void render(float x, float y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0) const;
+
+ ///
+ /// Render part of graphic single with given coordinates.
+ ///
+ void render(const Math::Quad& slice, float x, float 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;
+
+ private:
+ GLuint mTexture;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics)
diff --git a/src/libjin/graphics/image.cpp b/src/libjin/graphics/image.cpp
index 42d717d..de36355 100644
--- a/src/libjin/graphics/image.cpp
+++ b/src/libjin/graphics/image.cpp
@@ -6,43 +6,43 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- using namespace Filesystem;
-
- Image::Image(const char* path)
- : Bitmap()
- {
- AssetDatabase* fs = AssetDatabase::get();
- Buffer buffer;
- fs->read(path, buffer);
- Image(&buffer, buffer.size());
- }
-
- Image::Image(const void* imgData, size_t size)
- : Bitmap()
- {
- if (imgData == nullptr)
- return;
- int w, h;
- void* data = stbi_load_from_memory((uint8*)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
- if (data == nullptr)
- return;
- Image();
- pixels = (Color*)data;
- width = w;
- height = h;
- }
-
- Image::Image()
- : Bitmap()
- {
- }
-
- Image::~Image()
- {
- }
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ using namespace Filesystem;
+
+ Image::Image(const char* path)
+ : Bitmap()
+ {
+ AssetDatabase* fs = AssetDatabase::get();
+ Buffer buffer;
+ fs->read(path, buffer);
+ Image(&buffer, buffer.size());
+ }
+
+ Image::Image(const void* imgData, size_t size)
+ : Bitmap()
+ {
+ if (imgData == nullptr)
+ return;
+ int w, h;
+ void* data = stbi_load_from_memory((uint8*)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
+ if (data == nullptr)
+ return;
+ Image();
+ pixels = (Color*)data;
+ width = w;
+ height = h;
+ }
+
+ Image::Image()
+ : Bitmap()
+ {
+ }
+
+ Image::~Image()
+ {
+ }
+
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/image.h b/src/libjin/graphics/image.h
index 05a40e1..7fc4135 100644
--- a/src/libjin/graphics/image.h
+++ b/src/libjin/graphics/image.h
@@ -5,43 +5,43 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- ///
- /// A readonly bitmap.
- ///
- /// Just like bitmap but only from image file. The pixels data is readonly.
- ///
- class Image : public Bitmap
- {
- public:
- ///
- /// Image constructor.
- ///
- Image();
-
- Image(const char* path);
-
- Image(const void* imgData, size_t size);
-
- ///
- /// Image destructor.
- ///
- ~Image();
-
- private:
- // Disable setters inherited from Bitmap.
- void bind(Color* pixels, int w, int h);
- void resetPixels(const Color* pixels, int w, int h);
- void resetPixels(const Color& pixels, int w, int h);
- void setPixel(const Color& pixel, int x, int y);
- void setPixels(Color pixels);
- void setPixels(Color* pixels);
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ ///
+ /// A readonly bitmap.
+ ///
+ /// Just like bitmap but only from image file. The pixels data is readonly.
+ ///
+ class Image : public Bitmap
+ {
+ public:
+ ///
+ /// Image constructor.
+ ///
+ Image();
+
+ Image(const char* path);
+
+ Image(const void* imgData, size_t size);
+
+ ///
+ /// Image destructor.
+ ///
+ ~Image();
+
+ private:
+ // Disable setters inherited from Bitmap.
+ void bind(Color* pixels, int w, int h);
+ void resetPixels(const Color* pixels, int w, int h);
+ void resetPixels(const Color& pixels, int w, int h);
+ void setPixel(const Color& pixel, int x, int y);
+ void setPixels(Color pixels);
+ void setPixels(Color* pixels);
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/mesh.cpp b/src/libjin/graphics/mesh.cpp
index 71ebf62..2847a4f 100644
--- a/src/libjin/graphics/mesh.cpp
+++ b/src/libjin/graphics/mesh.cpp
@@ -8,71 +8,71 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- Mesh::Mesh()
- : mGraphic(nullptr)
- {
- }
+ Mesh::Mesh()
+ : mGraphic(nullptr)
+ {
+ }
- void Mesh::setGraphic(const Graphic* graphic)
- {
- mGraphic = graphic;
- }
+ void Mesh::setGraphic(const Graphic* graphic)
+ {
+ mGraphic = graphic;
+ }
- void Mesh::pushVertex(float x, float y, float u, float v, Color color)
- {
- Vertex vert;
- vert.xy.x() = x; vert.xy.y() = y;
- vert.uv.u() = u; vert.uv.v() = v;
- vert.color = color;
- pushVertex(vert);
- }
+ void Mesh::pushVertex(float x, float y, float u, float v, Color color)
+ {
+ Vertex vert;
+ vert.xy.x() = x; vert.xy.y() = y;
+ vert.uv.u() = u; vert.uv.v() = v;
+ vert.color = color;
+ pushVertex(vert);
+ }
- void Mesh::pushVertex(const Vertex& vert)
- {
- mVertices.push_back(vert);
- // Update bound
- if (mVertices.size() == 2)
- {
- const Vertex& v0 = mVertices[0];
- mBound.l = min(v0.xy.x(), vert.xy.x());
- mBound.r = max(v0.xy.x(), vert.xy.x());
- mBound.t = min(v0.xy.y(), vert.xy.y());
- mBound.b = max(v0.xy.y(), vert.xy.y());
- }
- else
- {
- float x = vert.xy.x(), y = vert.xy.y();
- mBound.l = x < mBound.l ? x : mBound.l;
- mBound.r = x > mBound.r ? x : mBound.r;
- mBound.t = y < mBound.t ? y : mBound.t;
- mBound.b = y > mBound.b ? y : mBound.b;
- }
- }
+ void Mesh::pushVertex(const Vertex& vert)
+ {
+ mVertices.push_back(vert);
+ // Update bound
+ if (mVertices.size() == 2)
+ {
+ const Vertex& v0 = mVertices[0];
+ mBound.l = min(v0.xy.x(), vert.xy.x());
+ mBound.r = max(v0.xy.x(), vert.xy.x());
+ mBound.t = min(v0.xy.y(), vert.xy.y());
+ mBound.b = max(v0.xy.y(), vert.xy.y());
+ }
+ else
+ {
+ float x = vert.xy.x(), y = vert.xy.y();
+ mBound.l = x < mBound.l ? x : mBound.l;
+ mBound.r = x > mBound.r ? x : mBound.r;
+ mBound.t = y < mBound.t ? y : mBound.t;
+ mBound.b = y > mBound.b ? y : mBound.b;
+ }
+ }
- void Mesh::render(float x, float y, float sx, float sy, float r, float ox, float oy) const
- {
- if (mGraphic == nullptr || mVertices.size() == 0)
- return;
+ void Mesh::render(float x, float y, float sx, float sy, float r, float ox, float oy) const
+ {
+ if (mGraphic == nullptr || mVertices.size() == 0)
+ return;
- Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy);
+ Math::Matrix modelViewMatrix = gl.getModelViewMatrix(x, y, sx, sy, r, ox, oy);
- Shader* shader = gl.getShader();
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
- .uploadVertices(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].xy))
- .uploadUV(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].uv))
- .uploadColor(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(mVertices[0].color), GL_TRUE);
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelViewMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
+ .uploadVertices(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].xy))
+ .uploadUV(2, GL_FLOAT, sizeof(Vertex), &(mVertices[0].uv))
+ .uploadColor(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(mVertices[0].color), GL_TRUE);
- gl.bindTexture2D(mGraphic->getGLTexture());
- gl.drawArrays(GL_POLYGON, 0, mVertices.size());
-
+ gl.bindTexture2D(mGraphic->getGLTexture());
+ gl.drawArrays(GL_POLYGON, 0, mVertices.size());
+
- shader->end();
- };
+ shader->end();
+ };
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/mesh.h b/src/libjin/graphics/mesh.h
index d17fcea..511a85c 100644
--- a/src/libjin/graphics/mesh.h
+++ b/src/libjin/graphics/mesh.h
@@ -10,43 +10,43 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- ///
- /// A 2D mesh.
- ///
- class Mesh : public Renderable, public Object
- {
- public:
- Mesh();
-
- void setGraphic(const Graphic* graphic);
- void pushVertex(float x, float y, float u, float v, Color color = Color::WHITE);
- void pushVertex(const Vertex& vertex);
- inline Math::BBox getBound() { return mBound; }
-
- void render(float x, float y, float sx, float sy, float r, float ox = 0, float oy = 0) const;
-
- private:
- ///
- /// Graphic binded.
- ///
- const Graphic* mGraphic;
-
- ///
- /// Bound box of mesh.
- ///
- Math::BBox mBound;
-
- ///
- ///
- ///
- std::vector<Vertex> mVertices;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ ///
+ /// A 2D mesh.
+ ///
+ class Mesh : public Renderable, public Object
+ {
+ public:
+ Mesh();
+
+ void setGraphic(const Graphic* graphic);
+ void pushVertex(float x, float y, float u, float v, Color color = Color::WHITE);
+ void pushVertex(const Vertex& vertex);
+ inline Math::BBox getBound() { return mBound; }
+
+ void render(float x, float y, float sx, float sy, float r, float ox = 0, float oy = 0) const;
+
+ private:
+ ///
+ /// Graphic binded.
+ ///
+ const Graphic* mGraphic;
+
+ ///
+ /// Bound box of mesh.
+ ///
+ Math::BBox mBound;
+
+ ///
+ ///
+ ///
+ std::vector<Vertex> mVertices;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/opengl.cpp b/src/libjin/graphics/opengl.cpp
index c1696f4..c00e206 100644
--- a/src/libjin/graphics/opengl.cpp
+++ b/src/libjin/graphics/opengl.cpp
@@ -15,403 +15,403 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
-
- OpenGL gl;
-
- Canvas* const OpenGL::SCREEN = NULL;
-
- OpenGL::OpenGL()
- {
- memset(&mStats, 0, sizeof(mStats));
- memset(&mColor, 0xff, sizeof(mColor));
- // Set default modelview matrix.
- mModelViewMatrices.push_back(Matrix());
- mModelViewMatrix.setIdentity();
- for (Matrix& m : mModelViewMatrices)
- mModelViewMatrix *= m;
- }
-
- OpenGL::~OpenGL()
- {
- }
-
- bool OpenGL::loadGL()
- {
- // Init glad library.
- if (!gladLoadGLLoader(SDL_GL_GetProcAddress))
- {
- jin_log_error("init opengl context failed");
- return false;
- }
-
- return true;
- }
-
- void OpenGL::init()
- {
- enable(GL_BLEND);
+ namespace Graphics
+ {
+
+ OpenGL gl;
+
+ Canvas* const OpenGL::SCREEN = NULL;
+
+ OpenGL::OpenGL()
+ {
+ memset(&mStats, 0, sizeof(mStats));
+ memset(&mColor, 0xff, sizeof(mColor));
+ // Set default modelview matrix.
+ mModelViewMatrices.push_back(Matrix());
+ mModelViewMatrix.setIdentity();
+ for (Matrix& m : mModelViewMatrices)
+ mModelViewMatrix *= m;
+ }
+
+ OpenGL::~OpenGL()
+ {
+ }
+
+ bool OpenGL::loadGL()
+ {
+ // Init glad library.
+ if (!gladLoadGLLoader(SDL_GL_GetProcAddress))
+ {
+ jin_log_error("init opengl context failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ void OpenGL::init()
+ {
+ enable(GL_BLEND);
unbindCanvas();
unuseShader();
- setClearColor(0, 0, 0, 0xff);
- setColor(0xff, 0xff, 0xff, 0xff);
- setBlendMode(OpenGL::BlendMode::ALPHA);
- }
-
- void OpenGL::enable(GLenum cap)
- {
- glEnable(cap);
- }
-
- void OpenGL::disable(GLenum cap)
- {
- glDisable(cap);
- }
-
- void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a)
- {
- glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
- }
-
- void OpenGL::popColor()
- {
- glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
- }
-
- void OpenGL::flushError()
- {
- while (glGetError() != GL_NO_ERROR);
- }
-
- GLuint OpenGL::genTexture()
- {
- GLuint t;
- glGenTextures(1, &t);
- return t;
- }
-
- void OpenGL::bindTexture2D(GLuint texture)
- {
- glBindTexture(GL_TEXTURE_2D, texture);
- }
-
- void OpenGL::deleteTexture(GLuint texture)
- {
- glDeleteTextures(1, &texture);
- }
-
- void OpenGL::setTexParameter(GLenum pname, GLint param)
- {
- glTexParameteri(GL_TEXTURE_2D, pname, param);
- }
-
- void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
- {
- glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels);
- }
-
- void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
- {
- glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels);
- }
-
- void OpenGL::activeTextureUnit(unsigned int unit)
- {
- // glActiveTexture selects which texture unit subsequent texture state calls will affect.
- glActiveTexture(GL_TEXTURE0 + unit);
- }
-
- void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count)
- {
- glDrawArrays(mode, first, count);
- ++mStats.drawCalls;
- }
-
- void OpenGL::drawBuffer(GLenum mode)
- {
-
- }
-
- void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
- {
-
- }
-
- void OpenGL::enableClientState(GLenum arr)
- {
- glEnableClientState(arr);
- }
-
- void OpenGL::disableClientState(GLenum arr)
- {
- glDisableClientState(arr);
- }
-
- GLuint OpenGL::genFrameBuffer()
- {
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- return fbo;
- }
-
- void OpenGL::bindFrameBuffer(GLuint fbo)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- }
-
- void OpenGL::ortho(int w, float radio)
- {
- glOrtho(0, w, w*radio, 0, -1, 1);
- }
-
- void OpenGL::orthox(int w, int h)
- {
- glOrtho(0, w, h, 0, -1, 1);
- }
-
- void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a)
- {
- setColor(Color(r, g, b, a));
- }
-
- void OpenGL::setColor(Color c)
- {
- mColor = c;
- glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f);
- }
-
- Color OpenGL::getColor()
- {
- return mColor;
- }
-
- void OpenGL::clearMatrix()
- {
- mModelViewMatrices.clear();
- mModelViewMatrices.push_back(Matrix());
- mModelViewMatrix.setIdentity();
- }
-
- void OpenGL::pushMatrix()
- {
- mModelViewMatrices.push_back(Matrix());
- }
-
- void OpenGL::popMatrix()
- {
- if (mModelViewMatrices.size() == 1)
- return;
- mModelViewMatrices.pop_back();
- mModelViewMatrix.setIdentity();
- for (Matrix& m : mModelViewMatrices)
- mModelViewMatrix *= m;
- }
-
- void OpenGL::translate(float x, float y)
- {
- if (mModelViewMatrices.size() == 1)
- return;
- Matrix& m = mModelViewMatrices.back();
- m.translate(x, y);
- mModelViewMatrix.translate(x, y);
- }
-
- void OpenGL::scale(float sx, float sy)
- {
- if (mModelViewMatrices.size() == 1)
- return;
- Matrix& m = mModelViewMatrices.back();
- m.scale(sx, sy);
- mModelViewMatrix.scale(sx, sy);
- }
-
- void OpenGL::rotate(float r)
- {
- if (mModelViewMatrices.size() == 1)
- return;
- Matrix& m = mModelViewMatrices.back();
- m.rotate(r);
- mModelViewMatrix.rotate(r);
- }
-
- Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy)
- {
- Matrix m;
- 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;
- }
-
- const Matrix& OpenGL::getProjectionMatrix()
- {
- return mProjectionMatrix;
- }
-
- void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f)
- {
- mProjectionMatrix.setOrtho(l, r, b, t, n, f);
- }
-
- OpenGL::BlendMode OpenGL::getBlendMode()
- {
- return mBlendMode;
- }
-
- void OpenGL::setBlendMode(BlendMode mode)
- {
- if (mBlendMode == mode)
- return;
- mBlendMode = mode;
-
- // result = src * srcFac FUNC dst * dstFac
-
- GLenum func = GL_FUNC_ADD;
- GLenum srcRGB = GL_ONE;
- GLenum srcA = GL_ONE;
- GLenum dstRGB = GL_ZERO;
- GLenum dstA = GL_ZERO;
-
- switch (mode)
- {
- case BlendMode::ADDITIVE:
- srcRGB = GL_SRC_ALPHA;
- srcA = GL_SRC_ALPHA;
- dstRGB = GL_ONE;
- dstA = GL_ONE;
- break;
- case BlendMode::PREMULTIPLIEDALPHA:
- srcRGB = srcA = GL_ONE;
- dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA;
- break;
- case BlendMode::ALPHA:
- default:
- srcRGB = GL_SRC_ALPHA;
- srcA = GL_SRC_ALPHA;
- dstRGB = GL_ONE_MINUS_SRC_ALPHA;
- dstA = GL_ONE_MINUS_SRC_ALPHA;
-
- break;
- }
-
- glBlendEquation(func);
- glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
- }
-
- void OpenGL::useShader(Shaders::Shader* shader)
- {
- if (mShader != shader && shader)
- {
- glUseProgram(shader->getGLProgramID());
- mShader = shader;
-
- ++mStats.shaderSwitches;
- }
- }
-
- void OpenGL::unuseShader()
- {
- if (mShader)
- {
- glUseProgram(0);
- mShader = nullptr;
- }
- }
-
- Shaders::Shader* OpenGL::getShader()
- {
- return mShader;
- }
-
- void OpenGL::bindCanvas(Canvas* canvas)
- {
- if (mCanvas != canvas && canvas)
- {
- GLuint fbo = canvas->getGLFrameBuffer();
- bindFrameBuffer(fbo);
- int w = canvas->getWidth();
- int h = canvas->getHeight();
- glViewport(0, 0, w, h);
- setProjectionMatrix(0, w, 0, h, -1, 1);
-
- mCanvas = canvas;
-
- setBlendMode(OpenGL::BlendMode::ALPHA);
-
- ++mStats.canvasSwitches;
- }
- }
-
- /**
- * bind to default screen render buffer.
- * do some coordinates transform work
- * https://blog.csdn.net/liji_digital/article/details/79370841
- * https://blog.csdn.net/lyx2007825/article/details/8792475
- */
- void OpenGL::unbindCanvas()
- {
- // Default bind to default canvas.
- if (getCanvas() == SCREEN)
- return;
- // Get window size as viewport.
- Window* wnd = Window::get();
+ setClearColor(0, 0, 0, 0xff);
+ setColor(0xff, 0xff, 0xff, 0xff);
+ setBlendMode(OpenGL::BlendMode::ALPHA);
+ }
+
+ void OpenGL::enable(GLenum cap)
+ {
+ glEnable(cap);
+ }
+
+ void OpenGL::disable(GLenum cap)
+ {
+ glDisable(cap);
+ }
+
+ void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+ {
+ glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
+ }
+
+ void OpenGL::popColor()
+ {
+ glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
+ }
+
+ void OpenGL::flushError()
+ {
+ while (glGetError() != GL_NO_ERROR);
+ }
+
+ GLuint OpenGL::genTexture()
+ {
+ GLuint t;
+ glGenTextures(1, &t);
+ return t;
+ }
+
+ void OpenGL::bindTexture2D(GLuint texture)
+ {
+ glBindTexture(GL_TEXTURE_2D, texture);
+ }
+
+ void OpenGL::deleteTexture(GLuint texture)
+ {
+ glDeleteTextures(1, &texture);
+ }
+
+ void OpenGL::setTexParameter(GLenum pname, GLint param)
+ {
+ glTexParameteri(GL_TEXTURE_2D, pname, param);
+ }
+
+ void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels);
+ }
+
+ void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+ {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels);
+ }
+
+ void OpenGL::activeTextureUnit(unsigned int unit)
+ {
+ // glActiveTexture selects which texture unit subsequent texture state calls will affect.
+ glActiveTexture(GL_TEXTURE0 + unit);
+ }
+
+ void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count)
+ {
+ glDrawArrays(mode, first, count);
+ ++mStats.drawCalls;
+ }
+
+ void OpenGL::drawBuffer(GLenum mode)
+ {
+
+ }
+
+ void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+ {
+
+ }
+
+ void OpenGL::enableClientState(GLenum arr)
+ {
+ glEnableClientState(arr);
+ }
+
+ void OpenGL::disableClientState(GLenum arr)
+ {
+ glDisableClientState(arr);
+ }
+
+ GLuint OpenGL::genFrameBuffer()
+ {
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ return fbo;
+ }
+
+ void OpenGL::bindFrameBuffer(GLuint fbo)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ }
+
+ void OpenGL::ortho(int w, float radio)
+ {
+ glOrtho(0, w, w*radio, 0, -1, 1);
+ }
+
+ void OpenGL::orthox(int w, int h)
+ {
+ glOrtho(0, w, h, 0, -1, 1);
+ }
+
+ void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a)
+ {
+ setColor(Color(r, g, b, a));
+ }
+
+ void OpenGL::setColor(Color c)
+ {
+ mColor = c;
+ glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f);
+ }
+
+ Color OpenGL::getColor()
+ {
+ return mColor;
+ }
+
+ void OpenGL::clearMatrix()
+ {
+ mModelViewMatrices.clear();
+ mModelViewMatrices.push_back(Matrix());
+ mModelViewMatrix.setIdentity();
+ }
+
+ void OpenGL::pushMatrix()
+ {
+ mModelViewMatrices.push_back(Matrix());
+ }
+
+ void OpenGL::popMatrix()
+ {
+ if (mModelViewMatrices.size() == 1)
+ return;
+ mModelViewMatrices.pop_back();
+ mModelViewMatrix.setIdentity();
+ for (Matrix& m : mModelViewMatrices)
+ mModelViewMatrix *= m;
+ }
+
+ void OpenGL::translate(float x, float y)
+ {
+ if (mModelViewMatrices.size() == 1)
+ return;
+ Matrix& m = mModelViewMatrices.back();
+ m.translate(x, y);
+ mModelViewMatrix.translate(x, y);
+ }
+
+ void OpenGL::scale(float sx, float sy)
+ {
+ if (mModelViewMatrices.size() == 1)
+ return;
+ Matrix& m = mModelViewMatrices.back();
+ m.scale(sx, sy);
+ mModelViewMatrix.scale(sx, sy);
+ }
+
+ void OpenGL::rotate(float r)
+ {
+ if (mModelViewMatrices.size() == 1)
+ return;
+ Matrix& m = mModelViewMatrices.back();
+ m.rotate(r);
+ mModelViewMatrix.rotate(r);
+ }
+
+ Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy)
+ {
+ Matrix m;
+ 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;
+ }
+
+ const Matrix& OpenGL::getProjectionMatrix()
+ {
+ return mProjectionMatrix;
+ }
+
+ void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f)
+ {
+ mProjectionMatrix.setOrtho(l, r, b, t, n, f);
+ }
+
+ OpenGL::BlendMode OpenGL::getBlendMode()
+ {
+ return mBlendMode;
+ }
+
+ void OpenGL::setBlendMode(BlendMode mode)
+ {
+ if (mBlendMode == mode)
+ return;
+ mBlendMode = mode;
+
+ // result = src * srcFac FUNC dst * dstFac
+
+ GLenum func = GL_FUNC_ADD;
+ GLenum srcRGB = GL_ONE;
+ GLenum srcA = GL_ONE;
+ GLenum dstRGB = GL_ZERO;
+ GLenum dstA = GL_ZERO;
+
+ switch (mode)
+ {
+ case BlendMode::ADDITIVE:
+ srcRGB = GL_SRC_ALPHA;
+ srcA = GL_SRC_ALPHA;
+ dstRGB = GL_ONE;
+ dstA = GL_ONE;
+ break;
+ case BlendMode::PREMULTIPLIEDALPHA:
+ srcRGB = srcA = GL_ONE;
+ dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case BlendMode::ALPHA:
+ default:
+ srcRGB = GL_SRC_ALPHA;
+ srcA = GL_SRC_ALPHA;
+ dstRGB = GL_ONE_MINUS_SRC_ALPHA;
+ dstA = GL_ONE_MINUS_SRC_ALPHA;
+
+ break;
+ }
+
+ glBlendEquation(func);
+ glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
+ }
+
+ void OpenGL::useShader(Shaders::Shader* shader)
+ {
+ if (mShader != shader && shader)
+ {
+ glUseProgram(shader->getGLProgramID());
+ mShader = shader;
+
+ ++mStats.shaderSwitches;
+ }
+ }
+
+ void OpenGL::unuseShader()
+ {
+ if (mShader)
+ {
+ glUseProgram(0);
+ mShader = nullptr;
+ }
+ }
+
+ Shaders::Shader* OpenGL::getShader()
+ {
+ return mShader;
+ }
+
+ void OpenGL::bindCanvas(Canvas* canvas)
+ {
+ if (mCanvas != canvas && canvas)
+ {
+ GLuint fbo = canvas->getGLFrameBuffer();
+ bindFrameBuffer(fbo);
+ int w = canvas->getWidth();
+ int h = canvas->getHeight();
+ glViewport(0, 0, w, h);
+ setProjectionMatrix(0, w, 0, h, -1, 1);
+
+ mCanvas = canvas;
+
+ setBlendMode(OpenGL::BlendMode::ALPHA);
+
+ ++mStats.canvasSwitches;
+ }
+ }
+
+ /**
+ * bind to default screen render buffer.
+ * do some coordinates transform work
+ * https://blog.csdn.net/liji_digital/article/details/79370841
+ * https://blog.csdn.net/lyx2007825/article/details/8792475
+ */
+ void OpenGL::unbindCanvas()
+ {
+ // Default bind to default canvas.
+ if (getCanvas() == SCREEN)
+ return;
+ // Get window size as viewport.
+ Window* wnd = Window::get();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- int w = wnd->getW(), h = wnd->getH();
- glViewport(0, 0, w, h);
- setProjectionMatrix(0, w, h, 0, -1, 1);
+ int w = wnd->getW(), h = wnd->getH();
+ glViewport(0, 0, w, h);
+ setProjectionMatrix(0, w, h, 0, -1, 1);
setBlendMode(OpenGL::BlendMode::ALPHA);
- mCanvas = SCREEN;
- }
-
- Canvas* OpenGL::getCanvas()
- {
- return mCanvas;
- }
-
- void OpenGL::setFont(Fonts::Font* font)
- {
- if (mFont != font && font)
- {
- mFont = font;
-
- ++mStats.fontSwitches;
- }
- }
-
- void OpenGL::unsetFont()
- {
- mFont = nullptr;
- }
-
- Fonts::Font* OpenGL::getFont()
- {
- return mFont;
- }
-
- void OpenGL::resetStats()
- {
- mStats.drawCalls = 0;
- mStats.canvasSwitches = 0;
- mStats.shaderSwitches = 0;
- mStats.fontSwitches = 0;
- }
-
- OpenGL::Stats& OpenGL::getStats()
- {
- return mStats;
- }
-
- } // namespace Graphics
+ mCanvas = SCREEN;
+ }
+
+ Canvas* OpenGL::getCanvas()
+ {
+ return mCanvas;
+ }
+
+ void OpenGL::setFont(Fonts::Font* font)
+ {
+ if (mFont != font && font)
+ {
+ mFont = font;
+
+ ++mStats.fontSwitches;
+ }
+ }
+
+ void OpenGL::unsetFont()
+ {
+ mFont = nullptr;
+ }
+
+ Fonts::Font* OpenGL::getFont()
+ {
+ return mFont;
+ }
+
+ void OpenGL::resetStats()
+ {
+ mStats.drawCalls = 0;
+ mStats.canvasSwitches = 0;
+ mStats.shaderSwitches = 0;
+ mStats.fontSwitches = 0;
+ }
+
+ OpenGL::Stats& OpenGL::getStats()
+ {
+ return mStats;
+ }
+
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/opengl.h b/src/libjin/graphics/opengl.h
index e97ebb6..c0a8a5d 100644
--- a/src/libjin/graphics/opengl.h
+++ b/src/libjin/graphics/opengl.h
@@ -13,258 +13,258 @@
namespace JinEngine
{
- namespace Graphics
- {
- // Wrap OpenGL API.
+ namespace Graphics
+ {
+ // Wrap OpenGL API.
- namespace Shaders { class Shader; };
- namespace Fonts { class Font; };
+ namespace Shaders { class Shader; };
+ namespace Fonts { class Font; };
- class Texture;
+ class Texture;
- class Canvas;
+ class Canvas;
- class OpenGL
- {
- public:
- ///
- /// Blend mode.
- /// https://www.andersriggelsen.dk/glblendfunc.php
- ///
- enum class BlendMode
- {
- ALPHA = 1,
- ADDITIVE = 2,
- PREMULTIPLIEDALPHA = 3,
- };
+ class OpenGL
+ {
+ public:
+ ///
+ /// Blend mode.
+ /// https://www.andersriggelsen.dk/glblendfunc.php
+ ///
+ enum class BlendMode
+ {
+ ALPHA = 1,
+ ADDITIVE = 2,
+ PREMULTIPLIEDALPHA = 3,
+ };
- struct Stats
- {
- int drawCalls;
- //int drawCallsBatched;
- int canvasSwitches;
- int shaderSwitches;
- int fontSwitches;
- int textures;
- int canvases;
- int fonts;
- //int64 textureMemory;
- };
+ struct Stats
+ {
+ int drawCalls;
+ //int drawCallsBatched;
+ int canvasSwitches;
+ int shaderSwitches;
+ int fontSwitches;
+ int textures;
+ int canvases;
+ int fonts;
+ //int64 textureMemory;
+ };
- static Canvas* const SCREEN;
+ static Canvas* const SCREEN;
- OpenGL();
- ~OpenGL();
+ OpenGL();
+ ~OpenGL();
- bool loadGL();
+ bool loadGL();
- void init();
+ void init();
- void enable(GLenum cap);
+ void enable(GLenum cap);
- void disable(GLenum cap);
+ void disable(GLenum cap);
- void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
+ void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
- void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255);
+ void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255);
- void popColor();
-
- void flushError();
-
- GLuint genTexture();
-
- void deleteTexture(GLuint texture);
-
- void bindTexture2D(GLuint texture = 0);
-
- void setTexParameter(GLenum pname, GLint param);
-
- void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL);
-
- void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
-
- void activeTextureUnit(unsigned int unit = 0);
+ void popColor();
+
+ void flushError();
+
+ GLuint genTexture();
+
+ void deleteTexture(GLuint texture);
+
+ void bindTexture2D(GLuint texture = 0);
+
+ void setTexParameter(GLenum pname, GLint param);
+
+ void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL);
+
+ void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+
+ void activeTextureUnit(unsigned int unit = 0);
- void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
- void drawBuffer(GLenum mode);
+ void drawBuffer(GLenum mode);
- void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
- void enableClientState(GLenum arr);
+ void enableClientState(GLenum arr);
- void disableClientState(GLenum arr);
+ void disableClientState(GLenum arr);
- GLuint genFrameBuffer();
+ GLuint genFrameBuffer();
- void bindFrameBuffer(GLuint fbo);
+ void bindFrameBuffer(GLuint fbo);
- void ortho(int w, float radio);
+ void ortho(int w, float radio);
- void orthox(int w, int h);
+ void orthox(int w, int h);
- void setColor(Channel r, Channel g, Channel b, Channel a);
+ void setColor(Channel r, Channel g, Channel b, Channel a);
- void setColor(Color c);
+ void setColor(Color c);
- Color getColor();
+ Color getColor();
- void clearMatrix();
+ void clearMatrix();
- void pushMatrix();
+ void pushMatrix();
- void translate(float x, float y);
+ void translate(float x, float y);
- void scale(float sx, float sy);
+ void scale(float sx, float sy);
- void rotate(float r);
+ void rotate(float r);
- void popMatrix();
+ void popMatrix();
- ///
- ///
- ///
- 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);
+ ///
+ ///
+ ///
+ 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);
- ///
- /// Get model view matrix.
- ///
- Math::Matrix getModelViewMatrix();
+ ///
+ /// Get model view matrix.
+ ///
+ Math::Matrix getModelViewMatrix();
- ///
- /// Set orthogonal matrix.
- ///
- void setProjectionMatrix(float l, float r, float b, float t, float n, float f);
+ ///
+ /// Set orthogonal matrix.
+ ///
+ void setProjectionMatrix(float l, float r, float b, float t, float n, float f);
- ///
- /// Get orthogonal matrix.
- ///
- const Math::Matrix& getProjectionMatrix();
+ ///
+ /// Get orthogonal matrix.
+ ///
+ const Math::Matrix& getProjectionMatrix();
- ///
- ///
- ///
- void useShader(Shaders::Shader* shader);
+ ///
+ ///
+ ///
+ void useShader(Shaders::Shader* shader);
- ///
- ///
- ///
- void unuseShader();
+ ///
+ ///
+ ///
+ void unuseShader();
- ///
- ///
- ///
- Shaders::Shader* getShader();
+ ///
+ ///
+ ///
+ Shaders::Shader* getShader();
- ///
- ///
- ///
- void setFont(Fonts::Font* font);
+ ///
+ ///
+ ///
+ void setFont(Fonts::Font* font);
- ///
- ///
- ///
- void unsetFont();
+ ///
+ ///
+ ///
+ void unsetFont();
- ///
- ///
- ///
- Fonts::Font* getFont();
+ ///
+ ///
+ ///
+ Fonts::Font* getFont();
- ///
- ///
- ///
- void bindCanvas(Canvas* canvas);
+ ///
+ ///
+ ///
+ void bindCanvas(Canvas* canvas);
- ///
- ///
- ///
- void unbindCanvas();
-
- ///
- ///
- ///
- Canvas* getCanvas();
+ ///
+ ///
+ ///
+ void unbindCanvas();
+
+ ///
+ ///
+ ///
+ Canvas* getCanvas();
- ///
- ///
- ///
- void setBlendMode(BlendMode mode);
+ ///
+ ///
+ ///
+ void setBlendMode(BlendMode mode);
- ///
- ///
- ///
- BlendMode getBlendMode();
-
- ///
- ///
- ///
- void resetStats();
-
- ///
- ///
- ///
- Stats& getStats();
-
- private:
-
- ///
- ///
- ///
- std::vector<Math::Matrix> mModelViewMatrices;
-
- ///
- ///
- ///
- Math::Matrix mModelViewMatrix;
-
- ///
- ///
- ///
- Math::Matrix mProjectionMatrix;
-
- ///
- ///
- ///
- BlendMode mBlendMode;
-
- ///
- ///
- ///
- Color mColor;
-
- ///
- ///
- ///
- Canvas* mCanvas;
-
- ///
- ///
- ///
- Shaders::Shader* mShader;
-
- ///
- ///
- ///
- Fonts::Font* mFont;
-
- ///
- ///
- ///
- Stats mStats;
-
- };
-
- // Singleton.
- extern OpenGL gl;
-
- } // namespace Graphics
+ ///
+ ///
+ ///
+ BlendMode getBlendMode();
+
+ ///
+ ///
+ ///
+ void resetStats();
+
+ ///
+ ///
+ ///
+ Stats& getStats();
+
+ private:
+
+ ///
+ ///
+ ///
+ std::vector<Math::Matrix> mModelViewMatrices;
+
+ ///
+ ///
+ ///
+ Math::Matrix mModelViewMatrix;
+
+ ///
+ ///
+ ///
+ Math::Matrix mProjectionMatrix;
+
+ ///
+ ///
+ ///
+ BlendMode mBlendMode;
+
+ ///
+ ///
+ ///
+ Color mColor;
+
+ ///
+ ///
+ ///
+ Canvas* mCanvas;
+
+ ///
+ ///
+ ///
+ Shaders::Shader* mShader;
+
+ ///
+ ///
+ ///
+ Fonts::Font* mFont;
+
+ ///
+ ///
+ ///
+ Stats mStats;
+
+ };
+
+ // Singleton.
+ extern OpenGL gl;
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // __JE_OPENGL_H__ \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle.cpp b/src/libjin/graphics/particles/particle.cpp
index 74600e0..ba07344 100644
--- a/src/libjin/graphics/particles/particle.cpp
+++ b/src/libjin/graphics/particles/particle.cpp
@@ -11,180 +11,180 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
-
- static RandomGenerator rng(0xEA44944);
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // ScaledRangedValue
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- ScaledRangedValue::ScaledRangedValue(Percentage* points, uint n)
- {
- for (int i = 0; i < n; ++i)
- {
- float x = points[2 * i].value;
- float y = points[2 * i + 1].value;
- addPoint(x, y);
- }
- }
-
- void ScaledRangedValue::set(Math::Percentage* points, uint n)
- {
- clear();
- for (int i = 0; i < n; ++i)
- {
- float x = points[2 * i].value;
- float y = points[2 * i + 1].value;
- addPoint(x, y);
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // GradientColorValue
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- GradientColorValue::GradientColorValue()
- : mCount(0)
- {
- }
-
- void GradientColorValue::addColor(Color col, Percentage time)
- {
- mColors.push_back(col);
- mTimeline.push_back(time);
- ++mCount;
- }
-
- Color GradientColorValue::getColor(Percentage time)
- {
- int endIndex = -1;
- int n = mCount;
- for (int i = 1; i < n; i++) {
- Percentage t = mTimeline[i];
- if (t.value > time.value) {
- endIndex = i;
- break;
- }
- }
- if (endIndex == -1) return mColors[n - 1];
- int startIndex = endIndex - 1;
- Color& startValue = mColors[startIndex];
- Color& endValue = mColors[endIndex];
- float t = time.value;
- float start = mTimeline[startIndex].value;
- float end = mTimeline[endIndex].value;
- Color c;
- c.r = startValue.r + (endValue.r - startValue.r) * ((t - start) / (end - start));
- c.g = startValue.g + (endValue.g - startValue.g) * ((t - start) / (end - start));
- c.b = startValue.b + (endValue.b - startValue.b) * ((t - start) / (end - start));
- c.a = startValue.a + (endValue.a - startValue.a) * ((t - start) / (end - start));
- return c;
- }
-
- void GradientColorValue::insertColor(uint i, Color col, Math::Percentage time)
- {
- mColors.insert(mColors.begin() + i, col);
- mTimeline.insert(mTimeline.begin() + i, time);
- ++mCount;
- }
-
- void GradientColorValue::removeColor(uint i)
- {
- mColors.erase(mColors.begin() + i);
- mTimeline.erase(mTimeline.begin() + i);
- --mCount;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // Particle
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- Particle::Particle()
- {
- reset();
- }
-
- void Particle::reset()
- {
- updateFlags = ParticleUpdateMask::NONE;
- transform.set(0, 0, 1, 1, 0, 0, 0);
- lifeTime = 1.0f;
- life = 0.0f;
- velocity.set(0, 0);
- linearAcceleration.set(0, 0);
- radialAcceleration = 0.0f;
- angularSpeed = 0;
- color = Color::WHITE;
- alive = true;
- spriteIndex = 0;
- }
-
- void Particle::update(float dt)
- {
- life += dt;
- alive = life < lifeTime;
- if (!alive)
- return;
- float t = life / lifeTime;
- if ((updateFlags & UPDATE_COLOR) != 0)
- color = def->colorDef.overTime.value.getColor(t);
- // transparency
- if (def->transparencyDef.overTime.enable)
- color.a = 0xff * def->transparencyDef.overTime.value.getValue(t);
- else
- color.a = 0xff * def->transparencyDef.transparency.value;
- if ((updateFlags & UPDATE_SCALE) != 0)
- {
- // Lerp scale.
- float scale = def->scaleDef.overTime.value.getValue(t);
- transform.setScale(scale, scale);
- }
- if ((updateFlags & UPDATE_POSITION) != 0)
- {
- // Calculate position.
- if((updateFlags & UPDATE_VELOCITY) != 0)
- velocity += linearAcceleration * dt;
- transform.move(velocity * dt);
- }
- if ((updateFlags & UPDATE_ROTATION) != 0)
- {
- // Calculate rotation.
- angularSpeed += radialAcceleration * dt;
- transform.rotate(angularSpeed * dt);
- }
- if ((updateFlags & UPDATE_SPRITE) != 0)
- {
- int n = def->spritesDef.sprites.size();
- if (def->spritesDef.mode == SpriteMode::ANIMATED)
- spriteIndex = lerp<int>(0, n - 1, t);
- //jin_log_info("sprite index %d", spriteIndex);
- }
- }
-
- void Particle::render()
- {
- // Set blend.
- OpenGL::BlendMode blend = gl.getBlendMode();
- if(def->blendDef.additive)
- gl.setBlendMode(OpenGL::BlendMode::ADDITIVE);
- Color c = gl.getColor();
- gl.setColor(color);
- const Sprite* sprite = def->spritesDef.sprites[spriteIndex];
- if (sprite != nullptr)
- {
- Vector2<float>& position = transform.getPosition();
- Vector2<float>& scale = transform.getScale();
- float r = transform.getRotation();
- sprite->render(position.x(), position.y(), scale.x(), scale.y(), r);
- }
- gl.setColor(c);
- gl.setBlendMode(blend);
- }
-
- }
- }
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ static RandomGenerator rng(0xEA44944);
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ScaledRangedValue
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ScaledRangedValue::ScaledRangedValue(Percentage* points, uint n)
+ {
+ for (int i = 0; i < n; ++i)
+ {
+ float x = points[2 * i].value;
+ float y = points[2 * i + 1].value;
+ addPoint(x, y);
+ }
+ }
+
+ void ScaledRangedValue::set(Math::Percentage* points, uint n)
+ {
+ clear();
+ for (int i = 0; i < n; ++i)
+ {
+ float x = points[2 * i].value;
+ float y = points[2 * i + 1].value;
+ addPoint(x, y);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GradientColorValue
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ GradientColorValue::GradientColorValue()
+ : mCount(0)
+ {
+ }
+
+ void GradientColorValue::addColor(Color col, Percentage time)
+ {
+ mColors.push_back(col);
+ mTimeline.push_back(time);
+ ++mCount;
+ }
+
+ Color GradientColorValue::getColor(Percentage time)
+ {
+ int endIndex = -1;
+ int n = mCount;
+ for (int i = 1; i < n; i++) {
+ Percentage t = mTimeline[i];
+ if (t.value > time.value) {
+ endIndex = i;
+ break;
+ }
+ }
+ if (endIndex == -1) return mColors[n - 1];
+ int startIndex = endIndex - 1;
+ Color& startValue = mColors[startIndex];
+ Color& endValue = mColors[endIndex];
+ float t = time.value;
+ float start = mTimeline[startIndex].value;
+ float end = mTimeline[endIndex].value;
+ Color c;
+ c.r = startValue.r + (endValue.r - startValue.r) * ((t - start) / (end - start));
+ c.g = startValue.g + (endValue.g - startValue.g) * ((t - start) / (end - start));
+ c.b = startValue.b + (endValue.b - startValue.b) * ((t - start) / (end - start));
+ c.a = startValue.a + (endValue.a - startValue.a) * ((t - start) / (end - start));
+ return c;
+ }
+
+ void GradientColorValue::insertColor(uint i, Color col, Math::Percentage time)
+ {
+ mColors.insert(mColors.begin() + i, col);
+ mTimeline.insert(mTimeline.begin() + i, time);
+ ++mCount;
+ }
+
+ void GradientColorValue::removeColor(uint i)
+ {
+ mColors.erase(mColors.begin() + i);
+ mTimeline.erase(mTimeline.begin() + i);
+ --mCount;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ Particle::Particle()
+ {
+ reset();
+ }
+
+ void Particle::reset()
+ {
+ updateFlags = ParticleUpdateMask::NONE;
+ transform.set(0, 0, 1, 1, 0, 0, 0);
+ lifeTime = 1.0f;
+ life = 0.0f;
+ velocity.set(0, 0);
+ linearAcceleration.set(0, 0);
+ radialAcceleration = 0.0f;
+ angularSpeed = 0;
+ color = Color::WHITE;
+ alive = true;
+ spriteIndex = 0;
+ }
+
+ void Particle::update(float dt)
+ {
+ life += dt;
+ alive = life < lifeTime;
+ if (!alive)
+ return;
+ float t = life / lifeTime;
+ if ((updateFlags & UPDATE_COLOR) != 0)
+ color = def->colorDef.overTime.value.getColor(t);
+ // transparency
+ if (def->transparencyDef.overTime.enable)
+ color.a = 0xff * def->transparencyDef.overTime.value.getValue(t);
+ else
+ color.a = 0xff * def->transparencyDef.transparency.value;
+ if ((updateFlags & UPDATE_SCALE) != 0)
+ {
+ // Lerp scale.
+ float scale = def->scaleDef.overTime.value.getValue(t);
+ transform.setScale(scale, scale);
+ }
+ if ((updateFlags & UPDATE_POSITION) != 0)
+ {
+ // Calculate position.
+ if((updateFlags & UPDATE_VELOCITY) != 0)
+ velocity += linearAcceleration * dt;
+ transform.move(velocity * dt);
+ }
+ if ((updateFlags & UPDATE_ROTATION) != 0)
+ {
+ // Calculate rotation.
+ angularSpeed += radialAcceleration * dt;
+ transform.rotate(angularSpeed * dt);
+ }
+ if ((updateFlags & UPDATE_SPRITE) != 0)
+ {
+ int n = def->spritesDef.sprites.size();
+ if (def->spritesDef.mode == SpriteMode::ANIMATED)
+ spriteIndex = lerp<int>(0, n - 1, t);
+ //jin_log_info("sprite index %d", spriteIndex);
+ }
+ }
+
+ void Particle::render()
+ {
+ // Set blend.
+ OpenGL::BlendMode blend = gl.getBlendMode();
+ if(def->blendDef.additive)
+ gl.setBlendMode(OpenGL::BlendMode::ADDITIVE);
+ Color c = gl.getColor();
+ gl.setColor(color);
+ const Sprite* sprite = def->spritesDef.sprites[spriteIndex];
+ if (sprite != nullptr)
+ {
+ Vector2<float>& position = transform.getPosition();
+ Vector2<float>& scale = transform.getScale();
+ float r = transform.getRotation();
+ sprite->render(position.x(), position.y(), scale.x(), scale.y(), r);
+ }
+ gl.setColor(c);
+ gl.setBlendMode(blend);
+ }
+
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle.h b/src/libjin/graphics/particles/particle.h
index 081ad26..25db6ae 100644
--- a/src/libjin/graphics/particles/particle.h
+++ b/src/libjin/graphics/particles/particle.h
@@ -12,211 +12,211 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
-
- class ParticleEmitter;
-
- class ScaledRangedValue : public Math::RangedValue
- {
- public:
- ScaledRangedValue() {};
- ScaledRangedValue(Math::Percentage* points, uint n);
- void set(Math::Percentage* points, uint n);
-
- };
-
- class GradientColorValue
- {
- public:
- GradientColorValue();
-
- void addColor(Color col, Math::Percentage time);
- Color getColor(Math::Percentage time);
- void insertColor(uint i, Color col, Math::Percentage time);
- void removeColor(uint i);
-
- private:
- std::vector<Color> mColors;
- std::vector<Math::Percentage> mTimeline;
- uint mCount;
-
- };
-
- ///
- ///
- ///
- struct LifeTimeDef
- {
- bool enableRandom = false;
- Struct(life,
- struct
- {
- float floor, ceil;
- } random;
- float life = 1.0f;
- );
- };
-
- struct ScaleDef
- {
- float scale = 1;
- Struct(overTime,
- bool enable = false;
- ScaledRangedValue value;
- );
- };
-
- struct ColorDef
- {
- Color color = Color::WHITE;
- Struct(overTime,
- bool enable = false;
- GradientColorValue value;
- );
- };
-
- struct TransparencyDef
- {
- Math::Percentage transparency = 1.f;
- Struct(overTime,
- bool enable = false;
- ScaledRangedValue value;
- );
- };
-
- struct linearAccelarationDef
- {
- Math::Vector2<float> linearAccelaration;
- };
-
- struct RadialAccelarationDef
- {
- float radialAccelaration = 0.f;
- };
-
- struct AngularSpeedDef
- {
- bool enableRandom = false;
- Struct(angularSpeed,
- struct
- {
- float floor = 0;
- float ceil = 0;
- } random;
- float angularSpeed = 0;
- );
- };
-
- enum SpriteMode
- {
- SINGLE = 1,
- RANDOM = 2,
- ANIMATED = 3,
- };
-
- struct SpritesDef
- {
- SpriteMode mode = SpriteMode::SINGLE;
- std::vector<const Sprite*> sprites;
- };
-
- struct BlendDef
- {
- bool additive = false;
- };
-
- ///
- ///
- ///
- struct ParticleDef
- {
- public:
- // Basic definitions.
- LifeTimeDef lifeTimeDef; ///<
- linearAccelarationDef linearAccelarationDef; ///<
- RadialAccelarationDef radialAccelarationDef; ///<
- AngularSpeedDef angularSpeedDef; ///<
- SpritesDef spritesDef; ///<
- BlendDef blendDef; ///<
- // Optional definitions.
- ScaleDef scaleDef; ///<
- ColorDef colorDef; ///<
- TransparencyDef transparencyDef; ///<
-
- private:
- friend class ParticleEmitter;
-
- };
-
- ///
- /// A single particle contains various properties of particle, such as position, accelaration, color
- /// and other attributes changed over time.
- ///
- class Particle : public Renderable, public Game::GameObject
- {
- public:
- enum ParticleUpdateMask
- {
- NONE = 0,
- UPDATE_COLOR = 1 << 0,
- UPDATE_SCALE = 1 << 1,
- UPDATE_POSITION = 1 << 2,
- UPDATE_ROTATION = 1 << 3,
- UPDATE_SPRITE = 1 << 4,
- UPDATE_VELOCITY = 1 << 5,
- };
-
- ///
- /// Default constructor.
- ///
- Particle();
-
- ///
- /// Reset to default.
- ///
- void reset();
-
- ///
- ///
- ///
- void update(float dt);
-
- ///
- ///
- ///
- void render();
-
- // Methods end.
-
- ParticleDef* def;
-
- uint updateFlags = ParticleUpdateMask::NONE;
-
- float lifeTime = 1.0f;
-
- float life = 0.0f;
-
- int spriteIndex = 0;
-
- Color color = Color::WHITE;
-
- Math::Transform transform;
-
- Math::Vector2<float> velocity;
- Math::Vector2<float> linearAcceleration;
-
- float angularSpeed;
- float radialAcceleration = 0;
-
- bool alive = true;
-
- };
-
- } // namespace Particles
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ class ParticleEmitter;
+
+ class ScaledRangedValue : public Math::RangedValue
+ {
+ public:
+ ScaledRangedValue() {};
+ ScaledRangedValue(Math::Percentage* points, uint n);
+ void set(Math::Percentage* points, uint n);
+
+ };
+
+ class GradientColorValue
+ {
+ public:
+ GradientColorValue();
+
+ void addColor(Color col, Math::Percentage time);
+ Color getColor(Math::Percentage time);
+ void insertColor(uint i, Color col, Math::Percentage time);
+ void removeColor(uint i);
+
+ private:
+ std::vector<Color> mColors;
+ std::vector<Math::Percentage> mTimeline;
+ uint mCount;
+
+ };
+
+ ///
+ ///
+ ///
+ struct LifeTimeDef
+ {
+ bool enableRandom = false;
+ Struct(life,
+ struct
+ {
+ float floor, ceil;
+ } random;
+ float life = 1.0f;
+ );
+ };
+
+ struct ScaleDef
+ {
+ float scale = 1;
+ Struct(overTime,
+ bool enable = false;
+ ScaledRangedValue value;
+ );
+ };
+
+ struct ColorDef
+ {
+ Color color = Color::WHITE;
+ Struct(overTime,
+ bool enable = false;
+ GradientColorValue value;
+ );
+ };
+
+ struct TransparencyDef
+ {
+ Math::Percentage transparency = 1.f;
+ Struct(overTime,
+ bool enable = false;
+ ScaledRangedValue value;
+ );
+ };
+
+ struct linearAccelarationDef
+ {
+ Math::Vector2<float> linearAccelaration;
+ };
+
+ struct RadialAccelarationDef
+ {
+ float radialAccelaration = 0.f;
+ };
+
+ struct AngularSpeedDef
+ {
+ bool enableRandom = false;
+ Struct(angularSpeed,
+ struct
+ {
+ float floor = 0;
+ float ceil = 0;
+ } random;
+ float angularSpeed = 0;
+ );
+ };
+
+ enum SpriteMode
+ {
+ SINGLE = 1,
+ RANDOM = 2,
+ ANIMATED = 3,
+ };
+
+ struct SpritesDef
+ {
+ SpriteMode mode = SpriteMode::SINGLE;
+ std::vector<const Sprite*> sprites;
+ };
+
+ struct BlendDef
+ {
+ bool additive = false;
+ };
+
+ ///
+ ///
+ ///
+ struct ParticleDef
+ {
+ public:
+ // Basic definitions.
+ LifeTimeDef lifeTimeDef; ///<
+ linearAccelarationDef linearAccelarationDef; ///<
+ RadialAccelarationDef radialAccelarationDef; ///<
+ AngularSpeedDef angularSpeedDef; ///<
+ SpritesDef spritesDef; ///<
+ BlendDef blendDef; ///<
+ // Optional definitions.
+ ScaleDef scaleDef; ///<
+ ColorDef colorDef; ///<
+ TransparencyDef transparencyDef; ///<
+
+ private:
+ friend class ParticleEmitter;
+
+ };
+
+ ///
+ /// A single particle contains various properties of particle, such as position, accelaration, color
+ /// and other attributes changed over time.
+ ///
+ class Particle : public Renderable, public Game::GameObject
+ {
+ public:
+ enum ParticleUpdateMask
+ {
+ NONE = 0,
+ UPDATE_COLOR = 1 << 0,
+ UPDATE_SCALE = 1 << 1,
+ UPDATE_POSITION = 1 << 2,
+ UPDATE_ROTATION = 1 << 3,
+ UPDATE_SPRITE = 1 << 4,
+ UPDATE_VELOCITY = 1 << 5,
+ };
+
+ ///
+ /// Default constructor.
+ ///
+ Particle();
+
+ ///
+ /// Reset to default.
+ ///
+ void reset();
+
+ ///
+ ///
+ ///
+ void update(float dt);
+
+ ///
+ ///
+ ///
+ void render();
+
+ // Methods end.
+
+ ParticleDef* def;
+
+ uint updateFlags = ParticleUpdateMask::NONE;
+
+ float lifeTime = 1.0f;
+
+ float life = 0.0f;
+
+ int spriteIndex = 0;
+
+ Color color = Color::WHITE;
+
+ Math::Transform transform;
+
+ Math::Vector2<float> velocity;
+ Math::Vector2<float> linearAcceleration;
+
+ float angularSpeed;
+ float radialAcceleration = 0;
+
+ bool alive = true;
+
+ };
+
+ } // namespace Particles
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle_emitter.cpp b/src/libjin/graphics/particles/particle_emitter.cpp
index 725b826..56dfb23 100644
--- a/src/libjin/graphics/particles/particle_emitter.cpp
+++ b/src/libjin/graphics/particles/particle_emitter.cpp
@@ -9,110 +9,110 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
+ namespace Graphics
+ {
+ namespace Particles
+ {
- static const uint8 ACCURACY_4 = 4;
- static const uint8 ACCURACY_5 = 5;
- static const uint8 ACCURACY_6 = 6;
+ static const uint8 ACCURACY_4 = 4;
+ static const uint8 ACCURACY_5 = 5;
+ static const uint8 ACCURACY_6 = 6;
- // Particle emitter
- static RandomGenerator rng(0xEA44944);
+ // Particle emitter
+ static RandomGenerator rng(0xEA44944);
- ParticleEmitter::ParticleEmitter(ParticleSystem& ps)
- : mPS(ps)
- , mDef(ps.mDef.emitterDef)
- , mPDef(ps.mDef.particleDef)
- , mTime(0)
- {
- }
+ ParticleEmitter::ParticleEmitter(ParticleSystem& ps)
+ : mPS(ps)
+ , mDef(ps.mDef.emitterDef)
+ , mPDef(ps.mDef.particleDef)
+ , mTime(0)
+ {
+ }
- void ParticleEmitter::update(float dt)
- {
- mTime += dt;
- 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::update(float dt)
+ {
+ mTime += dt;
+ 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();
- p->def = &mPDef;
- // 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);
- x += mPS.mPosition.x();
- y += mPS.mPosition.y();
- p->transform.setPosition(x, y);
- }
- else
- {
- p->transform.setPosition(mDef.positionDef.position.position + mPS.mPosition);
- }
- // 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->velocity.set(f*cos(r), f*sin(r));
- if (f != 0) p->updateFlags |= Particle::UPDATE_POSITION;
- // Init life time.
- if (mPDef.lifeTimeDef.enableRandom)
- p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.ceil, ACCURACY_4);
- else
- p->lifeTime = mPDef.lifeTimeDef.life.life;
- // Init linear accelaration.
- p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration;
- if(!p->linearAcceleration.isZero())
- p->updateFlags |= (Particle::UPDATE_VELOCITY | Particle::UPDATE_POSITION);
- // 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;
- if (p->angularSpeed != 0)
- p->updateFlags |= Particle::UPDATE_ROTATION;
- // Scale over time.
- if (mPDef.scaleDef.overTime.enable)
- p->updateFlags |= Particle::UPDATE_SCALE;
- else
- p->transform.setScale(mPDef.scaleDef.scale, mPDef.scaleDef.scale);
- // Color over time.
- if (mPDef.colorDef.overTime.enable)
- p->updateFlags |= Particle::UPDATE_COLOR;
- else
- p->color = mPDef.colorDef.color;
- // Sprite
- if (mPDef.spritesDef.mode != SpriteMode::SINGLE)
- {
- p->updateFlags |= Particle::UPDATE_SPRITE;
- if (mPDef.spritesDef.mode == SpriteMode::RANDOM)
- p->spriteIndex = rng.rand(0, mPDef.spritesDef.sprites.size() - 1);
- }
- }
+ void ParticleEmitter::emit()
+ {
+ Particle* p = mPS.claim();
+ if (p == nullptr)
+ return;
+ p->reset();
+ p->def = &mPDef;
+ // 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);
+ x += mPS.mPosition.x();
+ y += mPS.mPosition.y();
+ p->transform.setPosition(x, y);
+ }
+ else
+ {
+ p->transform.setPosition(mDef.positionDef.position.position + mPS.mPosition);
+ }
+ // 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->velocity.set(f*cos(r), f*sin(r));
+ if (f != 0) p->updateFlags |= Particle::UPDATE_POSITION;
+ // Init life time.
+ if (mPDef.lifeTimeDef.enableRandom)
+ p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.ceil, ACCURACY_4);
+ else
+ p->lifeTime = mPDef.lifeTimeDef.life.life;
+ // Init linear accelaration.
+ p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration;
+ if(!p->linearAcceleration.isZero())
+ p->updateFlags |= (Particle::UPDATE_VELOCITY | Particle::UPDATE_POSITION);
+ // 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;
+ if (p->angularSpeed != 0)
+ p->updateFlags |= Particle::UPDATE_ROTATION;
+ // Scale over time.
+ if (mPDef.scaleDef.overTime.enable)
+ p->updateFlags |= Particle::UPDATE_SCALE;
+ else
+ p->transform.setScale(mPDef.scaleDef.scale, mPDef.scaleDef.scale);
+ // Color over time.
+ if (mPDef.colorDef.overTime.enable)
+ p->updateFlags |= Particle::UPDATE_COLOR;
+ else
+ p->color = mPDef.colorDef.color;
+ // Sprite
+ if (mPDef.spritesDef.mode != SpriteMode::SINGLE)
+ {
+ p->updateFlags |= Particle::UPDATE_SPRITE;
+ if (mPDef.spritesDef.mode == SpriteMode::RANDOM)
+ p->spriteIndex = rng.rand(0, mPDef.spritesDef.sprites.size() - 1);
+ }
+ }
- }
- }
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle_emitter.h b/src/libjin/graphics/particles/particle_emitter.h
index 9f9465a..8e386da 100644
--- a/src/libjin/graphics/particles/particle_emitter.h
+++ b/src/libjin/graphics/particles/particle_emitter.h
@@ -8,129 +8,129 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
-
- struct PositionDef
- {
- bool enableRandom = false;
- Struct(position,
- struct
- {
- Math::Vector2<float> floor;
- Math::Vector2<float> ceil;
- } random;
- Math::Vector2<float> position;
- );
- };
-
- struct DirectionDef
- {
- bool enableRandom = false;
- Struct(direction,
- struct
- {
- float floor = 0;
- float ceil = 0;
- } random;
- float direction = 0;
- );
- };
-
- ///
- /// How many particles emitted per second.
- ///
- struct EmitRateDef
- {
- bool enableRandom = false;
- Struct(rate,
- struct
- {
- float floor = 1;
- float ceil = 1;
- } random;
- float rate = 1;
- );
- };
-
- ///
- /// 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
- {
- EmitRateDef emitRateDef; ///< Emit rate.
-
- PositionDef positionDef; ///< Emit position(relativily to the particle system center).
- DirectionDef directionDef; ///< Emit direction.
- ForceDef forceDef; ///< Emit force.
- };
-
- class ParticleSystem;
-
- ///
- /// Emit a single particle.
- ///
- class ParticleEmitter
- {
- public:
- ///
- ///
- ///
- ParticleEmitter(ParticleSystem& ps);
-
- ///
- ///
- ///
- void update(float dt);
-
- private:
- ///
- ///
- ///
- ParticleSystem& mPS;
-
- ParticleEmitterDef& mDef;
-
- ParticleDef& mPDef;
-
- ///
- /// 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();
-
- ///
- ///
- ///
- float mTime;
-
- ///
- ///
- ///
- float mInterval;
-
- };
-
- } // namespace Particles
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ struct PositionDef
+ {
+ bool enableRandom = false;
+ Struct(position,
+ struct
+ {
+ Math::Vector2<float> floor;
+ Math::Vector2<float> ceil;
+ } random;
+ Math::Vector2<float> position;
+ );
+ };
+
+ struct DirectionDef
+ {
+ bool enableRandom = false;
+ Struct(direction,
+ struct
+ {
+ float floor = 0;
+ float ceil = 0;
+ } random;
+ float direction = 0;
+ );
+ };
+
+ ///
+ /// How many particles emitted per second.
+ ///
+ struct EmitRateDef
+ {
+ bool enableRandom = false;
+ Struct(rate,
+ struct
+ {
+ float floor = 1;
+ float ceil = 1;
+ } random;
+ float rate = 1;
+ );
+ };
+
+ ///
+ /// 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
+ {
+ EmitRateDef emitRateDef; ///< Emit rate.
+
+ PositionDef positionDef; ///< Emit position(relativily to the particle system center).
+ DirectionDef directionDef; ///< Emit direction.
+ ForceDef forceDef; ///< Emit force.
+ };
+
+ class ParticleSystem;
+
+ ///
+ /// Emit a single particle.
+ ///
+ class ParticleEmitter
+ {
+ public:
+ ///
+ ///
+ ///
+ ParticleEmitter(ParticleSystem& ps);
+
+ ///
+ ///
+ ///
+ void update(float dt);
+
+ private:
+ ///
+ ///
+ ///
+ ParticleSystem& mPS;
+
+ ParticleEmitterDef& mDef;
+
+ ParticleDef& mPDef;
+
+ ///
+ /// 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();
+
+ ///
+ ///
+ ///
+ float mTime;
+
+ ///
+ ///
+ ///
+ float mInterval;
+
+ };
+
+ } // namespace Particles
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle_pool.h b/src/libjin/graphics/particles/particle_pool.h
index 618a965..b72a1ab 100644
--- a/src/libjin/graphics/particles/particle_pool.h
+++ b/src/libjin/graphics/particles/particle_pool.h
@@ -7,18 +7,18 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
+ namespace Graphics
+ {
+ namespace Particles
+ {
- ///
- /// Particle pool for reducing memory fragmentation.
- ///
- typedef Pool<Particle> ParticlePool;
+ ///
+ /// Particle pool for reducing memory fragmentation.
+ ///
+ typedef Pool<Particle> ParticlePool;
- } // namespace Particles
- } // namespace Graphics
+ } // namespace Particles
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle_system.cpp b/src/libjin/graphics/particles/particle_system.cpp
index 984f42b..2552c5a 100644
--- a/src/libjin/graphics/particles/particle_system.cpp
+++ b/src/libjin/graphics/particles/particle_system.cpp
@@ -6,261 +6,261 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
-
- ParticleSystem::ParticleSystem(uint maxCount)
- : mEmitter(*this)
- , mParticlePool(maxCount, sizeof(Particle))
- {
- }
-
- ParticleSystem::ParticleSystem(const ParticleSystemDef& def)
- : mDef(def)
- , mEmitter(*this)
- , mParticlePool(def.maxParticleCount, sizeof(Particle))
- {
- }
-
- ParticleSystem::~ParticleSystem()
- {
- }
-
- void ParticleSystem::setPosition(float x, float y)
- {
- mPosition.x() = x;
- mPosition.y() = y;
- }
-
- 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()
- {
- for (Particle* p : mAliveParticles)
- p->render();
- }
-
- Particle* ParticleSystem::claim()
- {
- Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle();
- mAliveParticles.push_back(p);
- //jin_log_info("particle count %d", mAliveParticles.size());
- return p;
- }
-
- void ParticleSystem::recycle(int i, Particle* p)
- {
- if (i >= mAliveParticles.size())
- return;
- mAliveParticles.erase(mAliveParticles.begin() + i);
- mParticlePool.Delete(p);
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // Particle Emitter modification.
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ParticleSystem::setEmitRate(float floor, float ceil)
- {
- mDef.emitterDef.emitRateDef.enableRandom = true;
- mDef.emitterDef.emitRateDef.rate.random.floor = floor;
- mDef.emitterDef.emitRateDef.rate.random.ceil = ceil;
- }
-
- void ParticleSystem::setEmitRate(float rate)
- {
- mDef.emitterDef.emitRateDef.enableRandom = false;
- mDef.emitterDef.emitRateDef.rate.rate = rate;
- }
-
- void ParticleSystem::setEmitForce(float floor, float ceil)
- {
- mDef.emitterDef.forceDef.enableRandom = true;
- mDef.emitterDef.forceDef.force.random.floor = floor;
- mDef.emitterDef.forceDef.force.random.ceil = ceil;
- }
-
- void ParticleSystem::setEmitForce(float force)
- {
- mDef.emitterDef.forceDef.enableRandom = false;
- mDef.emitterDef.forceDef.force.force = force;
- }
-
- void ParticleSystem::setEmitDirection(float floor, float ceil)
- {
- mDef.emitterDef.directionDef.enableRandom = true;
- mDef.emitterDef.directionDef.direction.random.floor = floor;
- mDef.emitterDef.directionDef.direction.random.ceil = ceil;
- }
-
- void ParticleSystem::setEmitDirection(float dir)
- {
- mDef.emitterDef.directionDef.enableRandom = false;
- mDef.emitterDef.directionDef.direction.direction = dir;
- }
-
- void ParticleSystem::setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil)
- {
- mDef.emitterDef.positionDef.enableRandom = true;
- mDef.emitterDef.positionDef.position.random.floor = floor;
- mDef.emitterDef.positionDef.position.random.ceil = ceil;
- }
-
- void ParticleSystem::setEmitPosition(const Math::Vector2<float>& position)
- {
- mDef.emitterDef.positionDef.enableRandom = false;
- mDef.emitterDef.positionDef.position.position = position;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // Particle Emitter modification.
- //////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ParticleSystem::setParticleLife(float floor, float ceil)
- {
- mDef.particleDef.lifeTimeDef.enableRandom = true;
- mDef.particleDef.lifeTimeDef.life.random.floor = floor;
- mDef.particleDef.lifeTimeDef.life.random.ceil = ceil;
- }
-
- void ParticleSystem::setParticleLife(float time)
- {
- mDef.particleDef.lifeTimeDef.enableRandom = true;
- mDef.particleDef.lifeTimeDef.life.life = time;
- }
-
- void ParticleSystem::setParticleLinearAccelaration(Math::Vector2<float> ac)
- {
- mDef.particleDef.linearAccelarationDef.linearAccelaration = ac;
- }
-
- void ParticleSystem::setParticleRadialAccelaration(float ra)
- {
- mDef.particleDef.radialAccelarationDef.radialAccelaration = ra;
- }
-
- void ParticleSystem::setParticleAngularSpeed(float floor, float ceil)
- {
- mDef.particleDef.angularSpeedDef.enableRandom = true;
- mDef.particleDef.angularSpeedDef.angularSpeed.random.floor = floor;
- mDef.particleDef.angularSpeedDef.angularSpeed.random.ceil = ceil;
- }
-
- void ParticleSystem::setParticleAngularSpeed(float speed)
- {
- mDef.particleDef.angularSpeedDef.enableRandom = false;
- mDef.particleDef.angularSpeedDef.angularSpeed.angularSpeed = speed;
- }
-
- void ParticleSystem::setParticleSpritesMode(SpriteMode mode)
- {
- mDef.particleDef.spritesDef.mode = mode;
- }
-
- void ParticleSystem::addParticleSprite(const Sprite* sprite)
- {
- mDef.particleDef.spritesDef.sprites.push_back(sprite);
- }
-
- void ParticleSystem::addParticleSprites(uint count, ...)
- {
- va_list args;
- va_start(args, count);
- while (count--)
- {
- Sprite* spr = va_arg(args, Sprite*);
- addParticleSprite(spr);
- }
- va_end(args);
- }
-
- void ParticleSystem::addParticleSprites(const std::vector<const Sprite*>& sprs)
- {
- for (const Sprite* spr : sprs)
- {
- addParticleSprite(spr);
- }
- }
-
- void ParticleSystem::removeParticleSprite(uint i)
- {
- mDef.particleDef.spritesDef.sprites.erase(mDef.particleDef.spritesDef.sprites.begin() + i);
- }
-
- void ParticleSystem::enableParticleBlendAdditive(bool enable)
- {
- mDef.particleDef.blendDef.additive = enable;
- }
-
- void ParticleSystem::setParticleScale(float scale)
- {
- mDef.particleDef.scaleDef.overTime.enable = false;
- mDef.particleDef.scaleDef.scale = scale;
- }
-
- void ParticleSystem::addParticleScalePoint(float scale, float t)
- {
- mDef.particleDef.scaleDef.overTime.enable = true;
- mDef.particleDef.scaleDef.overTime.value.addPoint(t, scale);
- }
-
- void ParticleSystem::removeParticleScalePoint(uint i)
- {
- mDef.particleDef.scaleDef.overTime.value.removePoint(i);
- }
-
- void ParticleSystem::setParticleColor(Color tint)
- {
- mDef.particleDef.colorDef.overTime.enable = false;
- mDef.particleDef.colorDef.color = tint;
- }
-
- void ParticleSystem::addParticleColorPoint(Color tint, float t)
- {
- mDef.particleDef.colorDef.overTime.enable = true;
- mDef.particleDef.colorDef.overTime.value.addColor(tint, t);
- }
-
- void ParticleSystem::removeParticleColorPoint(uint i)
- {
- mDef.particleDef.colorDef.overTime.value.removeColor(i);
- }
-
- void ParticleSystem::setParticleTransparency(float transparency)
- {
- mDef.particleDef.transparencyDef.overTime.enable = false;
- mDef.particleDef.transparencyDef.transparency = transparency;
- }
-
- void ParticleSystem::addParticleTransparencyPoint(float transparency, float t)
- {
- mDef.particleDef.transparencyDef.overTime.enable = true;
- mDef.particleDef.transparencyDef.overTime.value.addPoint(t, transparency);
- }
-
- void ParticleSystem::removeParticleTransparencyPoint(uint i)
- {
- mDef.particleDef.transparencyDef.overTime.value.removePoint(i);
- }
-
- }
- }
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ ParticleSystem::ParticleSystem(uint maxCount)
+ : mEmitter(*this)
+ , mParticlePool(maxCount, sizeof(Particle))
+ {
+ }
+
+ ParticleSystem::ParticleSystem(const ParticleSystemDef& def)
+ : mDef(def)
+ , mEmitter(*this)
+ , mParticlePool(def.maxParticleCount, sizeof(Particle))
+ {
+ }
+
+ ParticleSystem::~ParticleSystem()
+ {
+ }
+
+ void ParticleSystem::setPosition(float x, float y)
+ {
+ mPosition.x() = x;
+ mPosition.y() = y;
+ }
+
+ 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()
+ {
+ for (Particle* p : mAliveParticles)
+ p->render();
+ }
+
+ Particle* ParticleSystem::claim()
+ {
+ Particle* p = new (mParticlePool.GetNextWithoutInitializing()) Particle();
+ mAliveParticles.push_back(p);
+ //jin_log_info("particle count %d", mAliveParticles.size());
+ return p;
+ }
+
+ void ParticleSystem::recycle(int i, Particle* p)
+ {
+ if (i >= mAliveParticles.size())
+ return;
+ mAliveParticles.erase(mAliveParticles.begin() + i);
+ mParticlePool.Delete(p);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle Emitter modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ParticleSystem::setEmitRate(float floor, float ceil)
+ {
+ mDef.emitterDef.emitRateDef.enableRandom = true;
+ mDef.emitterDef.emitRateDef.rate.random.floor = floor;
+ mDef.emitterDef.emitRateDef.rate.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitRate(float rate)
+ {
+ mDef.emitterDef.emitRateDef.enableRandom = false;
+ mDef.emitterDef.emitRateDef.rate.rate = rate;
+ }
+
+ void ParticleSystem::setEmitForce(float floor, float ceil)
+ {
+ mDef.emitterDef.forceDef.enableRandom = true;
+ mDef.emitterDef.forceDef.force.random.floor = floor;
+ mDef.emitterDef.forceDef.force.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitForce(float force)
+ {
+ mDef.emitterDef.forceDef.enableRandom = false;
+ mDef.emitterDef.forceDef.force.force = force;
+ }
+
+ void ParticleSystem::setEmitDirection(float floor, float ceil)
+ {
+ mDef.emitterDef.directionDef.enableRandom = true;
+ mDef.emitterDef.directionDef.direction.random.floor = floor;
+ mDef.emitterDef.directionDef.direction.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitDirection(float dir)
+ {
+ mDef.emitterDef.directionDef.enableRandom = false;
+ mDef.emitterDef.directionDef.direction.direction = dir;
+ }
+
+ void ParticleSystem::setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil)
+ {
+ mDef.emitterDef.positionDef.enableRandom = true;
+ mDef.emitterDef.positionDef.position.random.floor = floor;
+ mDef.emitterDef.positionDef.position.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setEmitPosition(const Math::Vector2<float>& position)
+ {
+ mDef.emitterDef.positionDef.enableRandom = false;
+ mDef.emitterDef.positionDef.position.position = position;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle Emitter modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ParticleSystem::setParticleLife(float floor, float ceil)
+ {
+ mDef.particleDef.lifeTimeDef.enableRandom = true;
+ mDef.particleDef.lifeTimeDef.life.random.floor = floor;
+ mDef.particleDef.lifeTimeDef.life.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setParticleLife(float time)
+ {
+ mDef.particleDef.lifeTimeDef.enableRandom = true;
+ mDef.particleDef.lifeTimeDef.life.life = time;
+ }
+
+ void ParticleSystem::setParticleLinearAccelaration(Math::Vector2<float> ac)
+ {
+ mDef.particleDef.linearAccelarationDef.linearAccelaration = ac;
+ }
+
+ void ParticleSystem::setParticleRadialAccelaration(float ra)
+ {
+ mDef.particleDef.radialAccelarationDef.radialAccelaration = ra;
+ }
+
+ void ParticleSystem::setParticleAngularSpeed(float floor, float ceil)
+ {
+ mDef.particleDef.angularSpeedDef.enableRandom = true;
+ mDef.particleDef.angularSpeedDef.angularSpeed.random.floor = floor;
+ mDef.particleDef.angularSpeedDef.angularSpeed.random.ceil = ceil;
+ }
+
+ void ParticleSystem::setParticleAngularSpeed(float speed)
+ {
+ mDef.particleDef.angularSpeedDef.enableRandom = false;
+ mDef.particleDef.angularSpeedDef.angularSpeed.angularSpeed = speed;
+ }
+
+ void ParticleSystem::setParticleSpritesMode(SpriteMode mode)
+ {
+ mDef.particleDef.spritesDef.mode = mode;
+ }
+
+ void ParticleSystem::addParticleSprite(const Sprite* sprite)
+ {
+ mDef.particleDef.spritesDef.sprites.push_back(sprite);
+ }
+
+ void ParticleSystem::addParticleSprites(uint count, ...)
+ {
+ va_list args;
+ va_start(args, count);
+ while (count--)
+ {
+ Sprite* spr = va_arg(args, Sprite*);
+ addParticleSprite(spr);
+ }
+ va_end(args);
+ }
+
+ void ParticleSystem::addParticleSprites(const std::vector<const Sprite*>& sprs)
+ {
+ for (const Sprite* spr : sprs)
+ {
+ addParticleSprite(spr);
+ }
+ }
+
+ void ParticleSystem::removeParticleSprite(uint i)
+ {
+ mDef.particleDef.spritesDef.sprites.erase(mDef.particleDef.spritesDef.sprites.begin() + i);
+ }
+
+ void ParticleSystem::enableParticleBlendAdditive(bool enable)
+ {
+ mDef.particleDef.blendDef.additive = enable;
+ }
+
+ void ParticleSystem::setParticleScale(float scale)
+ {
+ mDef.particleDef.scaleDef.overTime.enable = false;
+ mDef.particleDef.scaleDef.scale = scale;
+ }
+
+ void ParticleSystem::addParticleScalePoint(float scale, float t)
+ {
+ mDef.particleDef.scaleDef.overTime.enable = true;
+ mDef.particleDef.scaleDef.overTime.value.addPoint(t, scale);
+ }
+
+ void ParticleSystem::removeParticleScalePoint(uint i)
+ {
+ mDef.particleDef.scaleDef.overTime.value.removePoint(i);
+ }
+
+ void ParticleSystem::setParticleColor(Color tint)
+ {
+ mDef.particleDef.colorDef.overTime.enable = false;
+ mDef.particleDef.colorDef.color = tint;
+ }
+
+ void ParticleSystem::addParticleColorPoint(Color tint, float t)
+ {
+ mDef.particleDef.colorDef.overTime.enable = true;
+ mDef.particleDef.colorDef.overTime.value.addColor(tint, t);
+ }
+
+ void ParticleSystem::removeParticleColorPoint(uint i)
+ {
+ mDef.particleDef.colorDef.overTime.value.removeColor(i);
+ }
+
+ void ParticleSystem::setParticleTransparency(float transparency)
+ {
+ mDef.particleDef.transparencyDef.overTime.enable = false;
+ mDef.particleDef.transparencyDef.transparency = transparency;
+ }
+
+ void ParticleSystem::addParticleTransparencyPoint(float transparency, float t)
+ {
+ mDef.particleDef.transparencyDef.overTime.enable = true;
+ mDef.particleDef.transparencyDef.overTime.value.addPoint(t, transparency);
+ }
+
+ void ParticleSystem::removeParticleTransparencyPoint(uint i)
+ {
+ mDef.particleDef.transparencyDef.overTime.value.removePoint(i);
+ }
+
+ }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/particles/particle_system.h b/src/libjin/graphics/particles/particle_system.h
index 83351a9..d3e3369 100644
--- a/src/libjin/graphics/particles/particle_system.h
+++ b/src/libjin/graphics/particles/particle_system.h
@@ -14,182 +14,182 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Particles
- {
-
- ///
- /// Definition of particle system.
- ///
- struct ParticleSystemDef
- {
- ParticleSystemDef() {}
- uint maxParticleCount = 1; ///< Max count of particles in pool. 1 by default.
- ParticleEmitterDef emitterDef; ///< Particle emitter definition.
- ParticleDef particleDef; ///< Particle definition.
- };
-
- ///
- /// Particle emitter, handle all particles it emitts.
- ///
- class ParticleSystem : public Renderable, public Game::GameObject
- {
- public:
- ///
- /// Particle system constructor
- ///
- /// @param def Definition of particle system.
- ///
- ParticleSystem(const ParticleSystemDef& def);
-
- ///
- ///
- ///
- ParticleSystem(uint maxCount = 64);
-
- ///
- ///
- ///
- ParticleSystem(const std::string & config);
-
- ///
- /// Particle system destructor.
- ///
- ~ParticleSystem();
-
- ///
- ///
- ///
- void setDefinition(const ParticleSystemDef& def);
-
- ///
- /// Load definition from config.
- ///
- void setDefinition(const std::string& config);
-
- ///
- /// Update particle system and all alive particles.
- ///
- void update(float dt);
-
- ///
- /// Render particle system.
- ///
- void render();
-
- ///
- /// Set particle system position.
- ///
- void setPosition(float x, float y);
-
- ///
- /// Set scale.
- ///
- void setScale(float sx, float sy);
-
- ///
- /// Pause particle spawn.
- ///
- void pause(bool isPause);
-
- ///
- /// Clear all particles.
- ///
- void clear();
-
- //////////////////////////////////////////////////////////////////////////////////////////////////
- // Particle Emitter modification.
- //////////////////////////////////////////////////////////////////////////////////////////////////
-
- void setEmitRate(float floor, float ceil);
- void setEmitRate(float rate);
-
- void setEmitForce(float floor, float ceil);
- void setEmitForce(float force);
-
- void setEmitDirection(float floor, float ceil);
- void setEmitDirection(float dir);
-
- void setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil);
- void setEmitPosition(const Math::Vector2<float>& position);
-
- //////////////////////////////////////////////////////////////////////////////////////////////////
- // Particle modification.
- //////////////////////////////////////////////////////////////////////////////////////////////////
-
- void setParticleLife(float floor, float ceil);
- void setParticleLife(float time);
-
- void setParticleLinearAccelaration(Math::Vector2<float> ac);
-
- void setParticleRadialAccelaration(float ra);
-
- void setParticleAngularSpeed(float floor, float ceil);
- void setParticleAngularSpeed(float speed);
-
- void setParticleSpritesMode(SpriteMode mode);
- void addParticleSprite(const Sprite* sprite);
- void addParticleSprites(uint count, ...);
- void addParticleSprites(const std::vector<const Sprite*>& sprs);
- void removeParticleSprite(uint i);
-
- void enableParticleBlendAdditive(bool enable);
-
- void setParticleScale(float scale);
- void addParticleScalePoint(float scale, float t);
- void removeParticleScalePoint(uint i);
-
- void setParticleColor(Color tint);
- void addParticleColorPoint(Color tint, float t);
- void removeParticleColorPoint(uint i);
-
- void setParticleTransparency(float transparency);
- void addParticleTransparencyPoint(float transparency, float t);
- void removeParticleTransparencyPoint(uint i);
+ namespace Graphics
+ {
+ namespace Particles
+ {
+
+ ///
+ /// Definition of particle system.
+ ///
+ struct ParticleSystemDef
+ {
+ ParticleSystemDef() {}
+ uint maxParticleCount = 1; ///< Max count of particles in pool. 1 by default.
+ ParticleEmitterDef emitterDef; ///< Particle emitter definition.
+ ParticleDef particleDef; ///< Particle definition.
+ };
+
+ ///
+ /// Particle emitter, handle all particles it emitts.
+ ///
+ class ParticleSystem : public Renderable, public Game::GameObject
+ {
+ public:
+ ///
+ /// Particle system constructor
+ ///
+ /// @param def Definition of particle system.
+ ///
+ ParticleSystem(const ParticleSystemDef& def);
+
+ ///
+ ///
+ ///
+ ParticleSystem(uint maxCount = 64);
+
+ ///
+ ///
+ ///
+ ParticleSystem(const std::string & config);
+
+ ///
+ /// Particle system destructor.
+ ///
+ ~ParticleSystem();
+
+ ///
+ ///
+ ///
+ void setDefinition(const ParticleSystemDef& def);
+
+ ///
+ /// Load definition from config.
+ ///
+ void setDefinition(const std::string& config);
+
+ ///
+ /// Update particle system and all alive particles.
+ ///
+ void update(float dt);
+
+ ///
+ /// Render particle system.
+ ///
+ void render();
+
+ ///
+ /// Set particle system position.
+ ///
+ void setPosition(float x, float y);
+
+ ///
+ /// Set scale.
+ ///
+ void setScale(float sx, float sy);
+
+ ///
+ /// Pause particle spawn.
+ ///
+ void pause(bool isPause);
+
+ ///
+ /// Clear all particles.
+ ///
+ void clear();
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle Emitter modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void setEmitRate(float floor, float ceil);
+ void setEmitRate(float rate);
+
+ void setEmitForce(float floor, float ceil);
+ void setEmitForce(float force);
+
+ void setEmitDirection(float floor, float ceil);
+ void setEmitDirection(float dir);
+
+ void setEmitPosition(const Math::Vector2<float>& floor, const Math::Vector2<float>& ceil);
+ void setEmitPosition(const Math::Vector2<float>& position);
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ // Particle modification.
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void setParticleLife(float floor, float ceil);
+ void setParticleLife(float time);
+
+ void setParticleLinearAccelaration(Math::Vector2<float> ac);
+
+ void setParticleRadialAccelaration(float ra);
+
+ void setParticleAngularSpeed(float floor, float ceil);
+ void setParticleAngularSpeed(float speed);
+
+ void setParticleSpritesMode(SpriteMode mode);
+ void addParticleSprite(const Sprite* sprite);
+ void addParticleSprites(uint count, ...);
+ void addParticleSprites(const std::vector<const Sprite*>& sprs);
+ void removeParticleSprite(uint i);
+
+ void enableParticleBlendAdditive(bool enable);
+
+ void setParticleScale(float scale);
+ void addParticleScalePoint(float scale, float t);
+ void removeParticleScalePoint(uint i);
+
+ void setParticleColor(Color tint);
+ void addParticleColorPoint(Color tint, float t);
+ void removeParticleColorPoint(uint i);
+
+ void setParticleTransparency(float transparency);
+ void addParticleTransparencyPoint(float transparency, float t);
+ void removeParticleTransparencyPoint(uint i);
- private:
- friend class ParticleEmitter;
-
- ///
- /// Particle system position.
- ///
- Math::Vector2<float> mPosition;
+ private:
+ friend class ParticleEmitter;
+
+ ///
+ /// Particle system position.
+ ///
+ Math::Vector2<float> mPosition;
- ///
- ///
- ///
- Particle* claim();
+ ///
+ ///
+ ///
+ Particle* claim();
- ///
- ///
- ///
- void recycle(int i, Particle* p);
+ ///
+ ///
+ ///
+ void recycle(int i, Particle* p);
- ///
- /// Particle system definition.
- ///
- ParticleSystemDef mDef;
+ ///
+ /// Particle system definition.
+ ///
+ ParticleSystemDef mDef;
- ///
- /// Particle emitter.
- ///
- ParticleEmitter mEmitter;
+ ///
+ /// Particle emitter.
+ ///
+ ParticleEmitter mEmitter;
- ///
- /// Particle pool.
- ///
- ParticlePool mParticlePool;
+ ///
+ /// Particle pool.
+ ///
+ ParticlePool mParticlePool;
- ///
- /// Alive particles, that means these particles could join to the life cycle loop.
- ///
- std::vector<Particle*> mAliveParticles;
+ ///
+ /// Alive particles, that means these particles could join to the life cycle loop.
+ ///
+ std::vector<Particle*> mAliveParticles;
- };
+ };
- } // namespace Particles
- } // namespace Graphics
+ } // namespace Particles
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/renderable.h b/src/libjin/graphics/renderable.h
index ca9888e..8d8772c 100644
--- a/src/libjin/graphics/renderable.h
+++ b/src/libjin/graphics/renderable.h
@@ -3,39 +3,39 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- namespace Shaders { class Shader; };
-
- enum class Origin
- {
- TOPLEFT,
- TOPCENTER,
- TOPRIGHT,
- MIDDLELEFT,
- MIDDLECENTER,
- MIDDLERIGHT,
- BOTTOMLEFT,
- BOTTOMCENTER,
- BOTTOMRIGHT
- };
-
- class Renderable
- {
- public:
- //void setShader(const Shaders::Shader* shader);
-
- virtual void render(float x, float y, float sx, float sy, float r) const {};
- virtual void render(float x, float y, float sx, float sy, float r, float ox, float oy) const {};
- virtual void render(float x, float y, float sx, float sy, float r, Origin origin) const {};
-
- protected:
- //const Shaders::Shader* mShader;
-
- };
-
- }
+ namespace Graphics
+ {
+
+ namespace Shaders { class Shader; };
+
+ enum class Origin
+ {
+ TOPLEFT,
+ TOPCENTER,
+ TOPRIGHT,
+ MIDDLELEFT,
+ MIDDLECENTER,
+ MIDDLERIGHT,
+ BOTTOMLEFT,
+ BOTTOMCENTER,
+ BOTTOMRIGHT
+ };
+
+ class Renderable
+ {
+ public:
+ //void setShader(const Shaders::Shader* shader);
+
+ virtual void render(float x, float y, float sx, float sy, float r) const {};
+ virtual void render(float x, float y, float sx, float sy, float r, float ox, float oy) const {};
+ virtual void render(float x, float y, float sx, float sy, float r, Origin origin) const {};
+
+ protected:
+ //const Shaders::Shader* mShader;
+
+ };
+
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/shaders/built-in/default.shader.h b/src/libjin/graphics/shaders/built-in/default.shader.h
index 3f57c44..0a7267b 100644
--- a/src/libjin/graphics/shaders/built-in/default.shader.h
+++ b/src/libjin/graphics/shaders/built-in/default.shader.h
@@ -5,7 +5,7 @@ static const char* default_shader = R"(
Vertex vert(Vertex v)
{
- return v;
+ return v;
}
#END_VERTEX_SHADER
@@ -14,7 +14,7 @@ Vertex vert(Vertex v)
Color frag(Color col, Texture tex, Vertex v)
{
- return col * texel(tex, v.uv);
+ return col * texel(tex, v.uv);
}
#END_FRAGMENT_SHADER
diff --git a/src/libjin/graphics/shaders/built-in/font.shader.h b/src/libjin/graphics/shaders/built-in/font.shader.h
index e04c225..9d15284 100644
--- a/src/libjin/graphics/shaders/built-in/font.shader.h
+++ b/src/libjin/graphics/shaders/built-in/font.shader.h
@@ -5,7 +5,7 @@ static const char* font_shader = R"(
Vertex vert(Vertex v)
{
- return v;
+ return v;
}
#END_VERTEX_SHADER
@@ -14,7 +14,7 @@ Vertex vert(Vertex v)
Color frag(Color col, Texture tex, Vertex v)
{
- return Color(col.rgb, texel(tex, v.uv).a);
+ return Color(col.rgb, texel(tex, v.uv).a);
}
#END_FRAGMENT_SHADER
diff --git a/src/libjin/graphics/shaders/built-in/texture.shader.h b/src/libjin/graphics/shaders/built-in/texture.shader.h
index d1fc86f..9e4a545 100644
--- a/src/libjin/graphics/shaders/built-in/texture.shader.h
+++ b/src/libjin/graphics/shaders/built-in/texture.shader.h
@@ -5,7 +5,7 @@ static const char* texture_shader = R"(
Vertex vert(Vertex v)
{
- return v;
+ return v;
}
#END_VERTEX_SHADER
@@ -14,7 +14,7 @@ Vertex vert(Vertex v)
Color frag(Color col, Texture tex, Vertex v)
{
- return col * texel(tex, v.uv);
+ return col * texel(tex, v.uv);
}
#END_FRAGMENT_SHADER
diff --git a/src/libjin/graphics/shaders/jsl_compiler.cpp b/src/libjin/graphics/shaders/jsl_compiler.cpp
index 44908e8..ea247c0 100644
--- a/src/libjin/graphics/shaders/jsl_compiler.cpp
+++ b/src/libjin/graphics/shaders/jsl_compiler.cpp
@@ -11,146 +11,146 @@ using namespace JinEngine::Filesystem;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Shaders
- {
+ namespace Graphics
+ {
+ namespace Shaders
+ {
- ///
- /// Uniforms:
- /// jin_ProjectionMatrix --+
- /// jin_ModelViewMatrix |- Uniforms
- /// jin_MainTexture |
- /// jin_RenderTargetSize |
- /// jin_Time --+
- ///
- /// Built-in variables in vertex shader:
- /// jin_VertexCoords --+
- /// jin_TextureCoords |- Attributes
- /// jin_VertexColor --+
- /// jin_Color ---- GLSL built in
- ///
- /// Built-in variables in fragment shader:
- /// jin_Color --+
- /// jin_XY |- Inputs
- /// jin_UV |
- /// jin_COLOR --+
- ///
+ ///
+ /// Uniforms:
+ /// jin_ProjectionMatrix --+
+ /// jin_ModelViewMatrix |- Uniforms
+ /// jin_MainTexture |
+ /// jin_RenderTargetSize |
+ /// jin_Time --+
+ ///
+ /// Built-in variables in vertex shader:
+ /// jin_VertexCoords --+
+ /// jin_TextureCoords |- Attributes
+ /// jin_VertexColor --+
+ /// jin_Color ---- GLSL built in
+ ///
+ /// Built-in variables in fragment shader:
+ /// jin_Color --+
+ /// jin_XY |- Inputs
+ /// jin_UV |
+ /// jin_COLOR --+
+ ///
- JinEngine::String SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix";
- JinEngine::String SHADER_MODELVIEW_MATRIX = "jin_ModelViewMatrix";
- JinEngine::String SHADER_MAIN_TEXTURE = "jin_MainTexture";
- JinEngine::String SHADER_VERTEX_COORDS = "jin_VertexCoords";
- JinEngine::String SHADER_TEXTURE_COORDS = "jin_TextureCoords";
- JinEngine::String SHADER_VERTEX_COLOR = "jin_VertexColor";
- JinEngine::String SHADER_TIME = "jin_Time";
- JinEngine::String SHADER_RENDERTARGET_SIZE = "jin_RenderTargetSize";
- JinEngine::String SHADER_VERSION = "#version 130 core \n";
- JinEngine::String SHADER_DEFINITIONS =
- // Types
- "#define Number float \n"
- "#define Texture sampler2D \n"
- "#define Canvas sampler2D \n"
- "#define Color vec4 \n"
- "#define Vec2 vec2 \n"
- "#define Vec3 vec3 \n"
- "#define Vec4 vec4 \n"
- // Functions
- "#define texel texture2D \n"
- // Structs
- "struct Vertex \n"
- "{ \n"
- " vec2 xy; \n"
- " vec2 uv; \n"
- " vec4 color; \n"
- "}; \n"
- "\n";
- JinEngine::String SHADER_UNIFORMS =
- "uniform Texture " + SHADER_MAIN_TEXTURE + "; \n" // Main texture goes first.
- "uniform mat4 " + SHADER_PROJECTION_MATRIX + "; \n"
- "uniform mat4 " + SHADER_MODELVIEW_MATRIX + "; \n"
- "uniform vec2 " + SHADER_TIME + "; \n"
- "uniform vec2 " + SHADER_RENDERTARGET_SIZE + "; \n";
+ JinEngine::String SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix";
+ JinEngine::String SHADER_MODELVIEW_MATRIX = "jin_ModelViewMatrix";
+ JinEngine::String SHADER_MAIN_TEXTURE = "jin_MainTexture";
+ JinEngine::String SHADER_VERTEX_COORDS = "jin_VertexCoords";
+ JinEngine::String SHADER_TEXTURE_COORDS = "jin_TextureCoords";
+ JinEngine::String SHADER_VERTEX_COLOR = "jin_VertexColor";
+ JinEngine::String SHADER_TIME = "jin_Time";
+ JinEngine::String SHADER_RENDERTARGET_SIZE = "jin_RenderTargetSize";
+ JinEngine::String SHADER_VERSION = "#version 130 core \n";
+ JinEngine::String SHADER_DEFINITIONS =
+ // Types
+ "#define Number float \n"
+ "#define Texture sampler2D \n"
+ "#define Canvas sampler2D \n"
+ "#define Color vec4 \n"
+ "#define Vec2 vec2 \n"
+ "#define Vec3 vec3 \n"
+ "#define Vec4 vec4 \n"
+ // Functions
+ "#define texel texture2D \n"
+ // Structs
+ "struct Vertex \n"
+ "{ \n"
+ " vec2 xy; \n"
+ " vec2 uv; \n"
+ " vec4 color; \n"
+ "}; \n"
+ "\n";
+ JinEngine::String SHADER_UNIFORMS =
+ "uniform Texture " + SHADER_MAIN_TEXTURE + "; \n" // Main texture goes first.
+ "uniform mat4 " + SHADER_PROJECTION_MATRIX + "; \n"
+ "uniform mat4 " + SHADER_MODELVIEW_MATRIX + "; \n"
+ "uniform vec2 " + SHADER_TIME + "; \n"
+ "uniform vec2 " + SHADER_RENDERTARGET_SIZE + "; \n";
- JinEngine::String JSLCompiler::formatVertexShader(const JinEngine::String& vert)
- {
- static JinEngine::String vert_part1 =
- SHADER_VERSION +
- SHADER_DEFINITIONS +
- SHADER_UNIFORMS +
- "in vec2 " + SHADER_VERTEX_COORDS + "; \n"
- "in vec2 " + SHADER_TEXTURE_COORDS + "; \n"
- "in vec4 " + SHADER_VERTEX_COLOR + "; \n"; // Color data in unsigned byte.
- static JinEngine::String vert_part2 =
- "\n"
- "out vec4 jin_Color; \n"
- "out vec2 jin_XY; \n"
- "out vec2 jin_UV; \n"
- "out vec4 jin_COLOR; \n"
- "void main()\n"
- "{\n"
- " vec4 v = " + SHADER_MODELVIEW_MATRIX + " * vec4(" + SHADER_VERTEX_COORDS + ", 0, 1.0); \n"
- " Vertex _v = vert(Vertex(v.xy, " + SHADER_TEXTURE_COORDS + ", " + SHADER_VERTEX_COLOR + ")); \n"
- " gl_Position = " + SHADER_PROJECTION_MATRIX + " * vec4(_v.xy, 0, 1.0f); \n"
- " jin_Color = gl_Color; \n"
- " jin_XY = _v.xy; \n"
- " jin_UV = _v.uv; \n"
- " jin_COLOR = _v.color; \n"
- "}";
- return vert_part1 + vert + vert_part2;
- }
+ JinEngine::String JSLCompiler::formatVertexShader(const JinEngine::String& vert)
+ {
+ static JinEngine::String vert_part1 =
+ SHADER_VERSION +
+ SHADER_DEFINITIONS +
+ SHADER_UNIFORMS +
+ "in vec2 " + SHADER_VERTEX_COORDS + "; \n"
+ "in vec2 " + SHADER_TEXTURE_COORDS + "; \n"
+ "in vec4 " + SHADER_VERTEX_COLOR + "; \n"; // Color data in unsigned byte.
+ static JinEngine::String vert_part2 =
+ "\n"
+ "out vec4 jin_Color; \n"
+ "out vec2 jin_XY; \n"
+ "out vec2 jin_UV; \n"
+ "out vec4 jin_COLOR; \n"
+ "void main()\n"
+ "{\n"
+ " vec4 v = " + SHADER_MODELVIEW_MATRIX + " * vec4(" + SHADER_VERTEX_COORDS + ", 0, 1.0); \n"
+ " Vertex _v = vert(Vertex(v.xy, " + SHADER_TEXTURE_COORDS + ", " + SHADER_VERTEX_COLOR + ")); \n"
+ " gl_Position = " + SHADER_PROJECTION_MATRIX + " * vec4(_v.xy, 0, 1.0f); \n"
+ " jin_Color = gl_Color; \n"
+ " jin_XY = _v.xy; \n"
+ " jin_UV = _v.uv; \n"
+ " jin_COLOR = _v.color; \n"
+ "}";
+ return vert_part1 + vert + vert_part2;
+ }
- JinEngine::String JSLCompiler::formatFragmentShader(const JinEngine::String& frag)
- {
- static JinEngine::String frag_part1 =
- SHADER_VERSION +
- SHADER_DEFINITIONS +
- SHADER_UNIFORMS +
- "in vec4 jin_Color; \n"
- "in vec2 jin_XY; \n"
- "in vec2 jin_UV; \n"
- "in vec4 jin_COLOR; \n";
- static JinEngine::String frag_part2 =
- "\n"
- "out vec4 jin_OutColor; \n"
- "void main() \n"
- "{ \n"
- " jin_OutColor = frag(jin_Color, " + SHADER_MAIN_TEXTURE + ", Vertex(jin_XY, jin_UV, jin_COLOR)); \n"
- "} \n";
- return frag_part1 + frag + frag_part2;
- }
+ JinEngine::String JSLCompiler::formatFragmentShader(const JinEngine::String& frag)
+ {
+ static JinEngine::String frag_part1 =
+ SHADER_VERSION +
+ SHADER_DEFINITIONS +
+ SHADER_UNIFORMS +
+ "in vec4 jin_Color; \n"
+ "in vec2 jin_XY; \n"
+ "in vec2 jin_UV; \n"
+ "in vec4 jin_COLOR; \n";
+ static JinEngine::String frag_part2 =
+ "\n"
+ "out vec4 jin_OutColor; \n"
+ "void main() \n"
+ "{ \n"
+ " jin_OutColor = frag(jin_Color, " + SHADER_MAIN_TEXTURE + ", Vertex(jin_XY, jin_UV, jin_COLOR)); \n"
+ "} \n";
+ return frag_part1 + frag + frag_part2;
+ }
- bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader)
- {
- // parse shader source, need some optimizations
- int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER");
- int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER");
- int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER");
- int loc_END_FRAGMENT_SHADER = jsl.find("#END_FRAGMENT_SHADER");
- if ( loc_VERTEX_SHADER == string::npos
- || loc_END_VERTEX_SHADER == string::npos
- || loc_FRAGMENT_SHADER == string::npos
- || loc_END_FRAGMENT_SHADER == string::npos
- )
- return false;
- // Load vertex and fragment shader source into buffers.
- {
- // Compile JSL vertex program.
- int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER");
- *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start);
- vertex_shader->assign(formatVertexShader(*vertex_shader));
- }
- {
- // Compile JSL fragment program.
- int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER");
- *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start);
- fragment_shader->assign(formatFragmentShader(*fragment_shader));
- }
- return true;
- }
+ bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader)
+ {
+ // parse shader source, need some optimizations
+ int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER");
+ int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER");
+ int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER");
+ int loc_END_FRAGMENT_SHADER = jsl.find("#END_FRAGMENT_SHADER");
+ if ( loc_VERTEX_SHADER == string::npos
+ || loc_END_VERTEX_SHADER == string::npos
+ || loc_FRAGMENT_SHADER == string::npos
+ || loc_END_FRAGMENT_SHADER == string::npos
+ )
+ return false;
+ // Load vertex and fragment shader source into buffers.
+ {
+ // Compile JSL vertex program.
+ int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER");
+ *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start);
+ vertex_shader->assign(formatVertexShader(*vertex_shader));
+ }
+ {
+ // Compile JSL fragment program.
+ int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER");
+ *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start);
+ fragment_shader->assign(formatFragmentShader(*fragment_shader));
+ }
+ return true;
+ }
- } // namespace Shaders
- } // namespace Graphics
+ } // namespace Shaders
+ } // namespace Graphics
} // namespace JinEngine
#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) \ No newline at end of file
diff --git a/src/libjin/graphics/shaders/jsl_compiler.h b/src/libjin/graphics/shaders/jsl_compiler.h
index ad3bdbb..f7aa48a 100644
--- a/src/libjin/graphics/shaders/jsl_compiler.h
+++ b/src/libjin/graphics/shaders/jsl_compiler.h
@@ -11,45 +11,45 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Shaders
- {
-
- extern JinEngine::String SHADER_PROJECTION_MATRIX;
- extern JinEngine::String SHADER_MODELVIEW_MATRIX;
- extern JinEngine::String SHADER_MAIN_TEXTURE;
- extern JinEngine::String SHADER_VERTEX_COORDS;
- extern JinEngine::String SHADER_TEXTURE_COORDS;
- extern JinEngine::String SHADER_VERTEX_COLOR;
- extern JinEngine::String SHADER_TIME;
- extern JinEngine::String SHADER_RENDERTARGET_SIZE;
-
- ///
- /// Compile JSL into GLSL.
- ///
- class JSLCompiler : public Singleton<JSLCompiler>
- {
- public:
- ///
- /// Compile JSL shader source into GLSL.
- ///
- /// @param jsl JSL shader source.
- /// @param glsl_vertex Output of vertex glsl shader source.
- /// @param glsl_fragment Output of fragment glsl shader source.
- /// @return True if compile successful, otherwise return false.
- ///
- bool compile(const std::string& jsl, std::string* glsl_vertex, std::string* glsl_fragment);
-
- private:
- JinEngine::String formatVertexShader(const JinEngine::String& vert);
-
- JinEngine::String formatFragmentShader(const JinEngine::String& frag);
-
- };
-
- } // namespace Shaders
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Shaders
+ {
+
+ extern JinEngine::String SHADER_PROJECTION_MATRIX;
+ extern JinEngine::String SHADER_MODELVIEW_MATRIX;
+ extern JinEngine::String SHADER_MAIN_TEXTURE;
+ extern JinEngine::String SHADER_VERTEX_COORDS;
+ extern JinEngine::String SHADER_TEXTURE_COORDS;
+ extern JinEngine::String SHADER_VERTEX_COLOR;
+ extern JinEngine::String SHADER_TIME;
+ extern JinEngine::String SHADER_RENDERTARGET_SIZE;
+
+ ///
+ /// Compile JSL into GLSL.
+ ///
+ class JSLCompiler : public Singleton<JSLCompiler>
+ {
+ public:
+ ///
+ /// Compile JSL shader source into GLSL.
+ ///
+ /// @param jsl JSL shader source.
+ /// @param glsl_vertex Output of vertex glsl shader source.
+ /// @param glsl_fragment Output of fragment glsl shader source.
+ /// @return True if compile successful, otherwise return false.
+ ///
+ bool compile(const std::string& jsl, std::string* glsl_vertex, std::string* glsl_fragment);
+
+ private:
+ JinEngine::String formatVertexShader(const JinEngine::String& vert);
+
+ JinEngine::String formatFragmentShader(const JinEngine::String& frag);
+
+ };
+
+ } // namespace Shaders
+ } // namespace Graphics
} // namespace JinEngine
#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
diff --git a/src/libjin/graphics/shaders/shader.cpp b/src/libjin/graphics/shaders/shader.cpp
index 36f6603..44b2cb0 100644
--- a/src/libjin/graphics/shaders/shader.cpp
+++ b/src/libjin/graphics/shaders/shader.cpp
@@ -20,302 +20,302 @@ using namespace JinEngine::Time;
namespace JinEngine
{
- namespace Graphics
- {
- namespace Shaders
- {
-
- //
- // default_texture
- // base_shader
- // SHADER_FORMAT_SIZE
- // formatShader
- //
- #include "built-in/default.shader.h"
-
- //
- // https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value
- // The default value of a sampler variable is 0. From the GLSL 3.30 spec,
- // section "4.3.5 Uniforms":
- //
- // The link time initial value is either the value of the variable's
- // initializer, if present, or 0 if no initializer is present.Sampler
- // types cannot have initializers.
- //
- // Since a value of 0 means that it's sampling from texture unit 0, it will
- // work without ever setting the value as long as you bind your textures to
- // unit 0. This is well defined behavior.
- //
- // Since texture unit 0 is also the default until you call glActiveTexture()
- // with a value other than GL_TEXTURE0, it's very common to always use unit
- // 0 as long as shaders do not need more than one texture.Which means that
- // often times, setting the sampler uniforms is redundant for simple
- // applications.
- //
- // I would still prefer to always set the values.If nothing else, it makes
- // it clear to anybody reading your code that you really mean to sample from
- // texture unit 0, and did not just forget to set the value.
- //
- const int MAIN_TEXTURE_UNIT = 0;
-
- static GLint textureUnit = 0;
-
- GLint Shader::mAttributeIndex = 0;
-
- Shader::Shader(const string& program)
- {
- if (!compile(program))
- {
- jin_log_error("Compile jsl shader failed.");
- throw Exception("Compile jsl shader failed");
- }
- }
-
- Shader::~Shader()
- {
- if (gl.getShader() == this)
- gl.unuseShader();
- // Delete shader program.
- glDeleteShader(mPID);
- }
-
- Shader& Shader::begin()
- {
-
- textureUnit = MAIN_TEXTURE_UNIT;
-
- // Send uniforms.
- sendInt(SHADER_MAIN_TEXTURE, MAIN_TEXTURE_UNIT);
- sendVec2(SHADER_TIME, Time::getSecond(), Time::getDeltaTime());
- Canvas* rt = gl.getCanvas();
- if (rt == OpenGL::SCREEN)
- {
- sendVec2(SHADER_RENDERTARGET_SIZE, Window::get()->getW(), Window::get()->getH());
- }
- else if(rt != nullptr)
- {
- sendVec2(SHADER_RENDERTARGET_SIZE, rt->getWidth(), rt->getHeight());
- }
-
- gl.activeTextureUnit(MAIN_TEXTURE_UNIT);
-
- return *this;
- }
-
- void Shader::end()
- {
- // Reset attribute index.
- for (; mAttributeIndex > 0; --mAttributeIndex)
- glDisableVertexAttribArray(mAttributeIndex);
- }
-
- bool Shader::compile(const string& program)
- {
- string vertex_shader, fragment_shader;
- // Compile JSL shader source into GLSL shader source.
- JSLCompiler* compiler = JSLCompiler::get();
- if (!compiler->compile(program, &vertex_shader, &fragment_shader))
- {
- return false;
- }
-
- #define glsl(SHADER_MODE, SHADER, SRC) \
- do{ \
- const GLchar* src = SRC.c_str(); \
- glShaderSource(SHADER, 1, &src, NULL); \
- glCompileShader(SHADER); \
- GLint success; \
- glGetShaderiv(SHADER, GL_COMPILE_STATUS, &success); \
- if (success == GL_FALSE) \
- return false; \
- }while(0)
-
- // Compile vertex shader.
- GLuint vid = glCreateShader(GL_VERTEX_SHADER);
- glsl(GL_VERTEX_SHADER, vid, vertex_shader);
- // Compile fragment shader.
- GLuint fid = glCreateShader(GL_FRAGMENT_SHADER);
- glsl(GL_FRAGMENT_SHADER, fid, fragment_shader);
-
- #undef glsl
- // Create OpenGL shader program.
- mPID = glCreateProgram();
- glAttachShader(mPID, vid);
- glAttachShader(mPID, fid);
- glLinkProgram(mPID);
- GLint success;
- glGetProgramiv(mPID, GL_LINK_STATUS, &success);
- if (success == GL_FALSE)
- return false;
- }
-
- static inline GLint getMaxTextureUnits()
- {
- GLint maxTextureUnits = 0;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
- return maxTextureUnits;
- }
-
- GLint Shader::claimTextureUnit(/*const std::string& name*/)
- {
- return textureUnit++;
- }
-
- GLint Shader::getUniformLocation(const char* uniform)
- {
- map<std::string, GLint>::iterator it = mUniformsLocation.find(uniform);
- if (it != mUniformsLocation.end())
- return it->second;
- GLint loc = glGetUniformLocation(mPID, uniform);
- mUniformsLocation.insert(pair<std::string, GLint>(uniform, loc));
- return loc;
- }
-
- #define check_jsl() \
- if (gl.getShader() != this) \
- return *this
-
- Shader & Shader::sendInt(const char* name, int value)
- {
- check_jsl();
- int loc = getUniformLocation(name);
- glUniform1i(loc, value);
- return *this;
- }
-
- Shader& Shader::sendFloat(const char* variable, float number)
- {
- check_jsl();
- int loc = getUniformLocation(variable);
- glUniform1f(loc, number);
- return *this;
- }
-
- //
- // https://www.douban.com/note/627332677/
- // struct TextureUnit
- // {
- // GLuint targetTexture1D;
- // GLuint targetTexture2D;
- // GLuint targetTexture3D;
- // GLuint targetTextureCube;
- // ...
- // };
- //
- // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
- // GLuint mCurrentTextureUnit = 0;
- //
- Shader& Shader::sendTexture(const char* variable, const Texture* tex)
- {
- check_jsl();
- GLint location = getUniformLocation(variable);
- if (location == -1)
- return *this;
- GLint unit = claimTextureUnit(/*variable*/);
- if (unit == 0)
- {
- // TODO: 쳣󶨵
- return *this;
- }
- gl.activeTextureUnit(unit);
- gl.bindTexture2D(tex->getGLTexture());
- glUniform1i(location, unit);
- gl.activeTextureUnit(MAIN_TEXTURE_UNIT);
- return *this;
- }
-
- Shader& Shader::sendCanvas(const char* variable, const Canvas* canvas)
- {
- check_jsl();
- GLint location = getUniformLocation(variable);
- if (location == -1)
- return *this;
- GLint unit = claimTextureUnit(/*variable*/);
- if (unit == 0)
- {
- // TODO: 쳣󶨵
- return *this;
- }
- glActiveTexture(GL_TEXTURE0 + unit);
- gl.bindTexture2D(canvas->getGLTexture());
- glUniform1i(location, unit);
-
- glActiveTexture(GL_TEXTURE0);
- return *this;
- }
-
- Shader& Shader::sendVec2(const char* name, float x, float y)
- {
- check_jsl();
- int loc = getUniformLocation(name);
- glUniform2f(loc, x, y);
- return *this;
- }
-
- Shader& Shader::sendVec3(const char* name, float x, float y, float z)
- {
- check_jsl();
- int loc = getUniformLocation(name);
- glUniform3f(loc, x, y, z);
- return *this;
- }
-
- Shader& Shader::sendVec4(const char* name, float x, float y, float z, float w)
- {
- check_jsl();
- int loc = getUniformLocation(name);
- glUniform4f(loc, x, y, z, w);
- return *this;
- }
-
- Shader& Shader::sendColor(const char* name, const Color* col)
- {
- check_jsl();
- int loc = getUniformLocation(name);
- glUniform4f(loc,
- col->r / 255.f,
- col->g / 255.f,
- col->b / 255.f,
- col->a / 255.f
- );
- return *this;
- }
-
- Shader& Shader::sendMatrix4(const char* name, const Math::Matrix* mat4)
- {
- int loc = getUniformLocation(name);
- glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements());
- return *this;
- }
-
- Shader& Shader::uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
- {
- uploadAttribute(SHADER_VERTEX_COORDS, n, type, stride, pointers, normalized);
- return *this;
- }
-
- Shader& Shader::uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
- {
- uploadAttribute(SHADER_TEXTURE_COORDS, n, type, stride, pointers, normalized);
- return *this;
- }
-
- Shader& Shader::uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
- {
- uploadAttribute(SHADER_VERTEX_COLOR, n, type, stride, pointers, normalized);
- return *this;
- }
-
- Shader& Shader::uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
- {
- GLint loc = glGetAttribLocation(mPID, name);
- glEnableVertexAttribArray(mAttributeIndex++);
- glVertexAttribPointer(loc, n, type, normalized, stride, pointers);
- return *this;
- }
-
- } // namespace Shaders
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Shaders
+ {
+
+ //
+ // default_texture
+ // base_shader
+ // SHADER_FORMAT_SIZE
+ // formatShader
+ //
+ #include "built-in/default.shader.h"
+
+ //
+ // https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value
+ // The default value of a sampler variable is 0. From the GLSL 3.30 spec,
+ // section "4.3.5 Uniforms":
+ //
+ // The link time initial value is either the value of the variable's
+ // initializer, if present, or 0 if no initializer is present.Sampler
+ // types cannot have initializers.
+ //
+ // Since a value of 0 means that it's sampling from texture unit 0, it will
+ // work without ever setting the value as long as you bind your textures to
+ // unit 0. This is well defined behavior.
+ //
+ // Since texture unit 0 is also the default until you call glActiveTexture()
+ // with a value other than GL_TEXTURE0, it's very common to always use unit
+ // 0 as long as shaders do not need more than one texture.Which means that
+ // often times, setting the sampler uniforms is redundant for simple
+ // applications.
+ //
+ // I would still prefer to always set the values.If nothing else, it makes
+ // it clear to anybody reading your code that you really mean to sample from
+ // texture unit 0, and did not just forget to set the value.
+ //
+ const int MAIN_TEXTURE_UNIT = 0;
+
+ static GLint textureUnit = 0;
+
+ GLint Shader::mAttributeIndex = 0;
+
+ Shader::Shader(const string& program)
+ {
+ if (!compile(program))
+ {
+ jin_log_error("Compile jsl shader failed.");
+ throw Exception("Compile jsl shader failed");
+ }
+ }
+
+ Shader::~Shader()
+ {
+ if (gl.getShader() == this)
+ gl.unuseShader();
+ // Delete shader program.
+ glDeleteShader(mPID);
+ }
+
+ Shader& Shader::begin()
+ {
+
+ textureUnit = MAIN_TEXTURE_UNIT;
+
+ // Send uniforms.
+ sendInt(SHADER_MAIN_TEXTURE, MAIN_TEXTURE_UNIT);
+ sendVec2(SHADER_TIME, Time::getSecond(), Time::getDeltaTime());
+ Canvas* rt = gl.getCanvas();
+ if (rt == OpenGL::SCREEN)
+ {
+ sendVec2(SHADER_RENDERTARGET_SIZE, Window::get()->getW(), Window::get()->getH());
+ }
+ else if(rt != nullptr)
+ {
+ sendVec2(SHADER_RENDERTARGET_SIZE, rt->getWidth(), rt->getHeight());
+ }
+
+ gl.activeTextureUnit(MAIN_TEXTURE_UNIT);
+
+ return *this;
+ }
+
+ void Shader::end()
+ {
+ // Reset attribute index.
+ for (; mAttributeIndex > 0; --mAttributeIndex)
+ glDisableVertexAttribArray(mAttributeIndex);
+ }
+
+ bool Shader::compile(const string& program)
+ {
+ string vertex_shader, fragment_shader;
+ // Compile JSL shader source into GLSL shader source.
+ JSLCompiler* compiler = JSLCompiler::get();
+ if (!compiler->compile(program, &vertex_shader, &fragment_shader))
+ {
+ return false;
+ }
+
+ #define glsl(SHADER_MODE, SHADER, SRC) \
+ do{ \
+ const GLchar* src = SRC.c_str(); \
+ glShaderSource(SHADER, 1, &src, NULL); \
+ glCompileShader(SHADER); \
+ GLint success; \
+ glGetShaderiv(SHADER, GL_COMPILE_STATUS, &success); \
+ if (success == GL_FALSE) \
+ return false; \
+ }while(0)
+
+ // Compile vertex shader.
+ GLuint vid = glCreateShader(GL_VERTEX_SHADER);
+ glsl(GL_VERTEX_SHADER, vid, vertex_shader);
+ // Compile fragment shader.
+ GLuint fid = glCreateShader(GL_FRAGMENT_SHADER);
+ glsl(GL_FRAGMENT_SHADER, fid, fragment_shader);
+
+ #undef glsl
+ // Create OpenGL shader program.
+ mPID = glCreateProgram();
+ glAttachShader(mPID, vid);
+ glAttachShader(mPID, fid);
+ glLinkProgram(mPID);
+ GLint success;
+ glGetProgramiv(mPID, GL_LINK_STATUS, &success);
+ if (success == GL_FALSE)
+ return false;
+ }
+
+ static inline GLint getMaxTextureUnits()
+ {
+ GLint maxTextureUnits = 0;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
+ return maxTextureUnits;
+ }
+
+ GLint Shader::claimTextureUnit(/*const std::string& name*/)
+ {
+ return textureUnit++;
+ }
+
+ GLint Shader::getUniformLocation(const char* uniform)
+ {
+ map<std::string, GLint>::iterator it = mUniformsLocation.find(uniform);
+ if (it != mUniformsLocation.end())
+ return it->second;
+ GLint loc = glGetUniformLocation(mPID, uniform);
+ mUniformsLocation.insert(pair<std::string, GLint>(uniform, loc));
+ return loc;
+ }
+
+ #define check_jsl() \
+ if (gl.getShader() != this) \
+ return *this
+
+ Shader & Shader::sendInt(const char* name, int value)
+ {
+ check_jsl();
+ int loc = getUniformLocation(name);
+ glUniform1i(loc, value);
+ return *this;
+ }
+
+ Shader& Shader::sendFloat(const char* variable, float number)
+ {
+ check_jsl();
+ int loc = getUniformLocation(variable);
+ glUniform1f(loc, number);
+ return *this;
+ }
+
+ //
+ // https://www.douban.com/note/627332677/
+ // struct TextureUnit
+ // {
+ // GLuint targetTexture1D;
+ // GLuint targetTexture2D;
+ // GLuint targetTexture3D;
+ // GLuint targetTextureCube;
+ // ...
+ // };
+ //
+ // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
+ // GLuint mCurrentTextureUnit = 0;
+ //
+ Shader& Shader::sendTexture(const char* variable, const Texture* tex)
+ {
+ check_jsl();
+ GLint location = getUniformLocation(variable);
+ if (location == -1)
+ return *this;
+ GLint unit = claimTextureUnit(/*variable*/);
+ if (unit == 0)
+ {
+ // TODO: 쳣󶨵
+ return *this;
+ }
+ gl.activeTextureUnit(unit);
+ gl.bindTexture2D(tex->getGLTexture());
+ glUniform1i(location, unit);
+ gl.activeTextureUnit(MAIN_TEXTURE_UNIT);
+ return *this;
+ }
+
+ Shader& Shader::sendCanvas(const char* variable, const Canvas* canvas)
+ {
+ check_jsl();
+ GLint location = getUniformLocation(variable);
+ if (location == -1)
+ return *this;
+ GLint unit = claimTextureUnit(/*variable*/);
+ if (unit == 0)
+ {
+ // TODO: 쳣󶨵
+ return *this;
+ }
+ glActiveTexture(GL_TEXTURE0 + unit);
+ gl.bindTexture2D(canvas->getGLTexture());
+ glUniform1i(location, unit);
+
+ glActiveTexture(GL_TEXTURE0);
+ return *this;
+ }
+
+ Shader& Shader::sendVec2(const char* name, float x, float y)
+ {
+ check_jsl();
+ int loc = getUniformLocation(name);
+ glUniform2f(loc, x, y);
+ return *this;
+ }
+
+ Shader& Shader::sendVec3(const char* name, float x, float y, float z)
+ {
+ check_jsl();
+ int loc = getUniformLocation(name);
+ glUniform3f(loc, x, y, z);
+ return *this;
+ }
+
+ Shader& Shader::sendVec4(const char* name, float x, float y, float z, float w)
+ {
+ check_jsl();
+ int loc = getUniformLocation(name);
+ glUniform4f(loc, x, y, z, w);
+ return *this;
+ }
+
+ Shader& Shader::sendColor(const char* name, const Color* col)
+ {
+ check_jsl();
+ int loc = getUniformLocation(name);
+ glUniform4f(loc,
+ col->r / 255.f,
+ col->g / 255.f,
+ col->b / 255.f,
+ col->a / 255.f
+ );
+ return *this;
+ }
+
+ Shader& Shader::sendMatrix4(const char* name, const Math::Matrix* mat4)
+ {
+ int loc = getUniformLocation(name);
+ glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements());
+ return *this;
+ }
+
+ Shader& Shader::uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
+ {
+ uploadAttribute(SHADER_VERTEX_COORDS, n, type, stride, pointers, normalized);
+ return *this;
+ }
+
+ Shader& Shader::uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
+ {
+ uploadAttribute(SHADER_TEXTURE_COORDS, n, type, stride, pointers, normalized);
+ return *this;
+ }
+
+ Shader& Shader::uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
+ {
+ uploadAttribute(SHADER_VERTEX_COLOR, n, type, stride, pointers, normalized);
+ return *this;
+ }
+
+ Shader& Shader::uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized)
+ {
+ GLint loc = glGetAttribLocation(mPID, name);
+ glEnableVertexAttribArray(mAttributeIndex++);
+ glVertexAttribPointer(loc, n, type, normalized, stride, pointers);
+ return *this;
+ }
+
+ } // namespace Shaders
+ } // namespace Graphics
} // namespace JinEngine
#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) \ No newline at end of file
diff --git a/src/libjin/graphics/shaders/shader.h b/src/libjin/graphics/shaders/shader.h
index e8756ac..c0e9086 100644
--- a/src/libjin/graphics/shaders/shader.h
+++ b/src/libjin/graphics/shaders/shader.h
@@ -17,186 +17,186 @@
namespace JinEngine
{
- namespace Graphics
- {
- namespace Shaders
- {
-
- ///
- /// Built in shader program.
- ///
- /// Built in shader program written with custom shading language called JSL (jin shading language). A
- /// JSL program is compiled into glsl, so most glsl built in functions and structs are available in
- /// JSL.
- ///
- class Shader : public Object
- {
- public:
- ///
- /// Shader constructor.
- ///
- Shader(const std::string& program);
-
- ///
- /// Destructor of shader.
- ///
- virtual ~Shader();
-
- ///
- /// Prepare shader and set default uniforms.
- ///
- Shader& begin();
-
- ///
- /// End use shader.
- ///
- void end();
-
- ///
- /// Send float value to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param number Value of uniform variable to be sent.
- ///
- Shader& sendFloat(const char* name, float number);
-
- ///
- /// Send texture to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param texture Texture to be sent.
- ///
- Shader& sendTexture(const char* name, const Texture* texture);
-
- ///
- /// Send integer value to shader
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param value Value to be sent.
- ///
- Shader& sendInt(const char* name, int value);
-
- ///
- /// Send 2D vector to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param x X value of the vector to be sent.
- /// @param y Y value of the vector to be sent.
- ///
- Shader& sendVec2(const char* name, float x, float y);
-
- ///
- /// Send 3D vector to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param x X value of the vector to be sent.
- /// @param y Y value of the vector to be sent.
- /// @param z Z value of the vector to be sent.
- ///
- Shader& sendVec3(const char* name, float x, float y, float z);
-
- ///
- /// Send 4D vector to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param x X value of the vector to be sent.
- /// @param y Y value of the vector to be sent.
- /// @param z Z value of the vector to be sent.
- /// @param w W value of the vector to be sent.
- ///
- Shader& sendVec4(const char* name, float x, float y, float z, float w);
-
- ///
- /// Send canvas to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param canvas Canvas to be sent.
- ///
- Shader& sendCanvas(const char* name, const Canvas* canvas);
-
- ///
- /// Send color to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param color Color to be sent.
- ///
- Shader& sendColor(const char* name, const Color* color);
-
- ///
- /// Send 4 by 4 matrix to shader.
- ///
- /// @param name Name of the uniform variable to be assigned.
- /// @param mat4 Matrix to be sent.
- ///
- Shader& sendMatrix4(const char* name, const Math::Matrix* mat4);
-
- ///
- /// Set vertices value.
- ///
- /// @param n Number of vertices.
- /// @param type Data type of each component in the array.
- /// @param stride Byte offset between consecutive generic vertex attributes.
- /// @param pointers Pointer to the first component of the first generic vertex attribute in the array.
- ///
- Shader& uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
-
- ///
- /// Set texture UV coordinates.
- ///
- /// @param n Number of vertices.
- /// @param type Data type of each component in the array.
- /// @param stride Byte offset between consecutive generic vertex attributes.
- /// @param pointers Pointer to the first component of the first generic vertex attribute in the array.
- ///
- Shader& uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
-
- ///
- /// Upload vertex color array.
- ///
- Shader& uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
-
- ///
- /// Set attribute.
- ///
- Shader& uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
-
- ///
- /// Program ID.
- ///
- inline GLuint getGLProgramID() { return mPID; };
-
- protected:
- ///
- /// Get texture unit of the uniform texture. If not, assign one.
- ///
- /// @param name Name of the texture uniform variable.
- /// @return Texture unit which texture variable be assigned.
- ///
- GLint claimTextureUnit(/*const std::string& name*/);
-
- GLint getUniformLocation(const char* uniforms);
-
- ///
- /// Compile JSL program into GLSL source.
- ///
- /// @param program JSL source code.
- /// @return Return true if compile successed, otherwise return false.
- ///
- bool compile(const std::string& program);
-
- //static GLint mTextureUnit;
- static GLint mAttributeIndex;
-
- GLuint mPID;
- //GLint mCurrentTextureUnit;
- //std::map<std::string, GLint> mTextureUnits;
-
- std::map<std::string, GLint> mUniformsLocation;
-
- };
-
- } // namespace Shaders
- } // namespace Graphics
+ namespace Graphics
+ {
+ namespace Shaders
+ {
+
+ ///
+ /// Built in shader program.
+ ///
+ /// Built in shader program written with custom shading language called JSL (jin shading language). A
+ /// JSL program is compiled into glsl, so most glsl built in functions and structs are available in
+ /// JSL.
+ ///
+ class Shader : public Object
+ {
+ public:
+ ///
+ /// Shader constructor.
+ ///
+ Shader(const std::string& program);
+
+ ///
+ /// Destructor of shader.
+ ///
+ virtual ~Shader();
+
+ ///
+ /// Prepare shader and set default uniforms.
+ ///
+ Shader& begin();
+
+ ///
+ /// End use shader.
+ ///
+ void end();
+
+ ///
+ /// Send float value to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param number Value of uniform variable to be sent.
+ ///
+ Shader& sendFloat(const char* name, float number);
+
+ ///
+ /// Send texture to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param texture Texture to be sent.
+ ///
+ Shader& sendTexture(const char* name, const Texture* texture);
+
+ ///
+ /// Send integer value to shader
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param value Value to be sent.
+ ///
+ Shader& sendInt(const char* name, int value);
+
+ ///
+ /// Send 2D vector to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param x X value of the vector to be sent.
+ /// @param y Y value of the vector to be sent.
+ ///
+ Shader& sendVec2(const char* name, float x, float y);
+
+ ///
+ /// Send 3D vector to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param x X value of the vector to be sent.
+ /// @param y Y value of the vector to be sent.
+ /// @param z Z value of the vector to be sent.
+ ///
+ Shader& sendVec3(const char* name, float x, float y, float z);
+
+ ///
+ /// Send 4D vector to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param x X value of the vector to be sent.
+ /// @param y Y value of the vector to be sent.
+ /// @param z Z value of the vector to be sent.
+ /// @param w W value of the vector to be sent.
+ ///
+ Shader& sendVec4(const char* name, float x, float y, float z, float w);
+
+ ///
+ /// Send canvas to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param canvas Canvas to be sent.
+ ///
+ Shader& sendCanvas(const char* name, const Canvas* canvas);
+
+ ///
+ /// Send color to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param color Color to be sent.
+ ///
+ Shader& sendColor(const char* name, const Color* color);
+
+ ///
+ /// Send 4 by 4 matrix to shader.
+ ///
+ /// @param name Name of the uniform variable to be assigned.
+ /// @param mat4 Matrix to be sent.
+ ///
+ Shader& sendMatrix4(const char* name, const Math::Matrix* mat4);
+
+ ///
+ /// Set vertices value.
+ ///
+ /// @param n Number of vertices.
+ /// @param type Data type of each component in the array.
+ /// @param stride Byte offset between consecutive generic vertex attributes.
+ /// @param pointers Pointer to the first component of the first generic vertex attribute in the array.
+ ///
+ Shader& uploadVertices(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
+
+ ///
+ /// Set texture UV coordinates.
+ ///
+ /// @param n Number of vertices.
+ /// @param type Data type of each component in the array.
+ /// @param stride Byte offset between consecutive generic vertex attributes.
+ /// @param pointers Pointer to the first component of the first generic vertex attribute in the array.
+ ///
+ Shader& uploadUV(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
+
+ ///
+ /// Upload vertex color array.
+ ///
+ Shader& uploadColor(int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
+
+ ///
+ /// Set attribute.
+ ///
+ Shader& uploadAttribute(const String& name, int n, GLenum type, GLsizei stride, const GLvoid * pointers, GLboolean normalized = GL_FALSE);
+
+ ///
+ /// Program ID.
+ ///
+ inline GLuint getGLProgramID() { return mPID; };
+
+ protected:
+ ///
+ /// Get texture unit of the uniform texture. If not, assign one.
+ ///
+ /// @param name Name of the texture uniform variable.
+ /// @return Texture unit which texture variable be assigned.
+ ///
+ GLint claimTextureUnit(/*const std::string& name*/);
+
+ GLint getUniformLocation(const char* uniforms);
+
+ ///
+ /// Compile JSL program into GLSL source.
+ ///
+ /// @param program JSL source code.
+ /// @return Return true if compile successed, otherwise return false.
+ ///
+ bool compile(const std::string& program);
+
+ //static GLint mTextureUnit;
+ static GLint mAttributeIndex;
+
+ GLuint mPID;
+ //GLint mCurrentTextureUnit;
+ //std::map<std::string, GLint> mTextureUnits;
+
+ std::map<std::string, GLint> mUniformsLocation;
+
+ };
+
+ } // namespace Shaders
+ } // namespace Graphics
} // namespace JinEngine
#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
diff --git a/src/libjin/graphics/shapes.cpp b/src/libjin/graphics/shapes.cpp
index 23fc888..228f4c8 100644
--- a/src/libjin/graphics/shapes.cpp
+++ b/src/libjin/graphics/shapes.cpp
@@ -13,136 +13,136 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
-
- using namespace Math;
-
- void point(int x, int y)
- {
- float verts[] = { x + 0.5f , y + 0.5f };
-
- Matrix modelMatrix = gl.getModelViewMatrix();
-
- Shader* shader = gl.getShader();
- shader->begin()
- .uploadVertices(2, GL_FLOAT, 0, verts)
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
-
- gl.drawArrays(GL_POINTS, 0, 1);
-
- shader->end();
- }
-
- void points(int n, GLshort* p)
- {
- Matrix modelMatrix = gl.getModelViewMatrix();
-
- Shader* shader = gl.getShader();
- shader->begin()
- .uploadVertices(2, GL_SHORT, 0, p)
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
-
- gl.drawArrays(GL_POINTS, 0, n);
-
- shader->end();
- }
-
- void line(int x1, int y1, int x2, int y2)
- {
- float verts[] = {
- x1 + 0.5f, y1 + 0.5f,
- x2 + 0.5f, y2 + 0.5f
- };
-
- Matrix modelMatrix = gl.getModelViewMatrix();
-
- Shader* shader = gl.getShader();
- shader->begin()
- .uploadVertices(2, GL_FLOAT, 0, verts)
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
-
- gl.drawArrays(GL_LINES, 0, 2);
-
- shader->end();
- }
-
- void circle(RenderMode mode, int x, int y, int r)
- {
- r = r < 0 ? 0 : r;
-
- int points = 40;
- float two_pi = static_cast<float>(PI * 2);
- if (points <= 0) points = 1;
- float angle_shift = (two_pi / points);
- float phi = .0f;
-
- float *coords = new float[2 * (points + 1)];
- for (int i = 0; i < points; ++i, phi += angle_shift)
- {
- coords[2 * i] = x + r * cos(phi);
- coords[2 * i + 1] = y + r * sin(phi);
- }
-
- coords[2 * points] = coords[0];
- coords[2 * points + 1] = coords[1];
-
- polygon(mode, coords, points);
-
- delete[] coords;
- }
-
- void rect(RenderMode mode, int x, int y, int w, int h)
- {
- float coords[] = { x + 0.5f, y + 0.5f, x + w + 0.5f, y + 0.5f, x + w + 0.5f, y + h + 0.5f, x + 0.5f, y + h + 0.5f };
- polygon(mode, coords, 4);
- }
-
- void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3)
- {
- float coords[] = { x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f, x3 + 0.5f, y3 + 0.5f };
- polygon(mode, coords, 3);
- }
-
- void polygon_line(float* p, int count)
- {
- Shader* shader = gl.getShader();
- Matrix modelMatrix = gl.getModelViewMatrix();
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
- .uploadVertices(2, GL_FLOAT, 0, p);
-
- gl.drawArrays(GL_LINE_LOOP, 0, count);
-
- shader->end();
- }
-
- void polygon(RenderMode mode, float* p, int count)
- {
- if (mode == LINE)
- {
- polygon_line(p, count);
- }
- else if (mode == FILL)
- {
- Shader* shader = gl.getShader();
- Matrix modelMatrix = gl.getModelViewMatrix();
- shader->begin()
- .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
- .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
- .uploadVertices(2, GL_FLOAT, 0, p);
-
- gl.drawArrays(GL_POLYGON, 0, count);
-
- shader->end();
- }
- }
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ using namespace Math;
+
+ void point(int x, int y)
+ {
+ float verts[] = { x + 0.5f , y + 0.5f };
+
+ Matrix modelMatrix = gl.getModelViewMatrix();
+
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .uploadVertices(2, GL_FLOAT, 0, verts)
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
+
+ gl.drawArrays(GL_POINTS, 0, 1);
+
+ shader->end();
+ }
+
+ void points(int n, GLshort* p)
+ {
+ Matrix modelMatrix = gl.getModelViewMatrix();
+
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .uploadVertices(2, GL_SHORT, 0, p)
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
+
+ gl.drawArrays(GL_POINTS, 0, n);
+
+ shader->end();
+ }
+
+ void line(int x1, int y1, int x2, int y2)
+ {
+ float verts[] = {
+ x1 + 0.5f, y1 + 0.5f,
+ x2 + 0.5f, y2 + 0.5f
+ };
+
+ Matrix modelMatrix = gl.getModelViewMatrix();
+
+ Shader* shader = gl.getShader();
+ shader->begin()
+ .uploadVertices(2, GL_FLOAT, 0, verts)
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix());
+
+ gl.drawArrays(GL_LINES, 0, 2);
+
+ shader->end();
+ }
+
+ void circle(RenderMode mode, int x, int y, int r)
+ {
+ r = r < 0 ? 0 : r;
+
+ int points = 40;
+ float two_pi = static_cast<float>(PI * 2);
+ if (points <= 0) points = 1;
+ float angle_shift = (two_pi / points);
+ float phi = .0f;
+
+ float *coords = new float[2 * (points + 1)];
+ for (int i = 0; i < points; ++i, phi += angle_shift)
+ {
+ coords[2 * i] = x + r * cos(phi);
+ coords[2 * i + 1] = y + r * sin(phi);
+ }
+
+ coords[2 * points] = coords[0];
+ coords[2 * points + 1] = coords[1];
+
+ polygon(mode, coords, points);
+
+ delete[] coords;
+ }
+
+ void rect(RenderMode mode, int x, int y, int w, int h)
+ {
+ float coords[] = { x + 0.5f, y + 0.5f, x + w + 0.5f, y + 0.5f, x + w + 0.5f, y + h + 0.5f, x + 0.5f, y + h + 0.5f };
+ polygon(mode, coords, 4);
+ }
+
+ void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3)
+ {
+ float coords[] = { x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f, x3 + 0.5f, y3 + 0.5f };
+ polygon(mode, coords, 3);
+ }
+
+ void polygon_line(float* p, int count)
+ {
+ Shader* shader = gl.getShader();
+ Matrix modelMatrix = gl.getModelViewMatrix();
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
+ .uploadVertices(2, GL_FLOAT, 0, p);
+
+ gl.drawArrays(GL_LINE_LOOP, 0, count);
+
+ shader->end();
+ }
+
+ void polygon(RenderMode mode, float* p, int count)
+ {
+ if (mode == LINE)
+ {
+ polygon_line(p, count);
+ }
+ else if (mode == FILL)
+ {
+ Shader* shader = gl.getShader();
+ Matrix modelMatrix = gl.getModelViewMatrix();
+ shader->begin()
+ .sendMatrix4(SHADER_MODELVIEW_MATRIX, &modelMatrix)
+ .sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.getProjectionMatrix())
+ .uploadVertices(2, GL_FLOAT, 0, p);
+
+ gl.drawArrays(GL_POLYGON, 0, count);
+
+ shader->end();
+ }
+ }
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/shapes.h b/src/libjin/graphics/shapes.h
index 6c25eeb..99979d8 100644
--- a/src/libjin/graphics/shapes.h
+++ b/src/libjin/graphics/shapes.h
@@ -9,24 +9,24 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- enum RenderMode {
- NONE = 0,
- FILL ,
- LINE
- };
+ enum RenderMode {
+ NONE = 0,
+ FILL ,
+ LINE
+ };
- extern void line(int x1, int y1, int x2, int y2);
- extern void rect(RenderMode mode, int x, int y, int w, int h);
- extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3);
- extern void circle(RenderMode mode, int x, int y, int r);
- extern void point(int x, int y);
- extern void points(int n, GLshort* p, GLubyte* c);
- extern void polygon(RenderMode mode, float* p, int count);
+ extern void line(int x1, int y1, int x2, int y2);
+ extern void rect(RenderMode mode, int x, int y, int w, int h);
+ extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3);
+ extern void circle(RenderMode mode, int x, int y, int r);
+ extern void point(int x, int y);
+ extern void points(int n, GLshort* p, GLubyte* c);
+ extern void polygon(RenderMode mode, float* p, int count);
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine
#endif // jin_graphics
diff --git a/src/libjin/graphics/sprite.cpp b/src/libjin/graphics/sprite.cpp
index d74c1ef..a09a315 100644
--- a/src/libjin/graphics/sprite.cpp
+++ b/src/libjin/graphics/sprite.cpp
@@ -6,90 +6,90 @@ using namespace JinEngine::Graphics;
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin)
- : mGraphic(graphic)
- , mQuad(quad)
- {
- setOrigin(origin);
- }
+ Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin)
+ : mGraphic(graphic)
+ , mQuad(quad)
+ {
+ setOrigin(origin);
+ }
- Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy)
- : mGraphic(graphic)
- , mQuad(quad)
- , mOrigin(ox, oy)
- {
- }
+ Sprite::Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy)
+ : mGraphic(graphic)
+ , mQuad(quad)
+ , mOrigin(ox, oy)
+ {
+ }
- Sprite::Sprite(const Graphic* graphic, Origin origin)
- : mGraphic(graphic)
- , mQuad(0, 0, graphic->getWidth(), graphic->getHeight())
- {
- setOrigin(origin);
- }
+ Sprite::Sprite(const Graphic* graphic, Origin origin)
+ : mGraphic(graphic)
+ , mQuad(0, 0, graphic->getWidth(), graphic->getHeight())
+ {
+ setOrigin(origin);
+ }
- Sprite::Sprite(const Graphic* graphic, float ox, float oy)
- : mGraphic(graphic)
- , mQuad(0, 0, graphic->getWidth(), graphic->getHeight())
- , mOrigin(ox, oy)
- {
- }
+ Sprite::Sprite(const Graphic* graphic, float ox, float oy)
+ : mGraphic(graphic)
+ , mQuad(0, 0, graphic->getWidth(), graphic->getHeight())
+ , mOrigin(ox, oy)
+ {
+ }
- Sprite::~Sprite()
- {
- }
+ Sprite::~Sprite()
+ {
+ }
- Math::Vector2<int> Sprite::getSize()
- {
- return Math::Vector2<int>(mQuad.w, mQuad.h);
- }
+ Math::Vector2<int> Sprite::getSize()
+ {
+ return Math::Vector2<int>(mQuad.w, mQuad.h);
+ }
- void Sprite::render(float x, float y, float sx, float sy, float r) const
- {
- if (mGraphic != nullptr)
- mGraphic->render(mQuad, x, y, sx, sy, r, mOrigin.x(), mOrigin.y());
- }
+ void Sprite::render(float x, float y, float sx, float sy, float r) const
+ {
+ if (mGraphic != nullptr)
+ mGraphic->render(mQuad, x, y, sx, sy, r, mOrigin.x(), mOrigin.y());
+ }
- void Sprite::setOrigin(Origin origin)
- {
- int l = 0, r = 0, t = 0, b = 0;
- Vector2<int> size = getSize();
- r = size.w();
- b = size.h();
- Vector2<float>* org = const_cast<Vector2<float>*>(&mOrigin);
- switch (origin)
- {
- case Origin::TOPLEFT:
- org->set(l, t);
- break;
- case Origin::TOPCENTER:
- org->set(r / 2.f, t);
- break;
- case Origin::TOPRIGHT:
- org->set(r, t);
- break;
- case Origin::MIDDLELEFT:
- org->set(l, b / 2.f);
- break;
- case Origin::MIDDLECENTER:
- org->set(r / 2.f, b / 2.f);
- break;
- case Origin::MIDDLERIGHT:
- org->set(r, b / 2.f);
- break;
- case Origin::BOTTOMLEFT:
- org->set(l, b);
- break;
- case Origin::BOTTOMCENTER:
- org->set(r / 2.f, b);
- break;
- case Origin::BOTTOMRIGHT:
- org->set(r, b);
- break;
- }
- }
+ void Sprite::setOrigin(Origin origin)
+ {
+ int l = 0, r = 0, t = 0, b = 0;
+ Vector2<int> size = getSize();
+ r = size.w();
+ b = size.h();
+ Vector2<float>* org = const_cast<Vector2<float>*>(&mOrigin);
+ switch (origin)
+ {
+ case Origin::TOPLEFT:
+ org->set(l, t);
+ break;
+ case Origin::TOPCENTER:
+ org->set(r / 2.f, t);
+ break;
+ case Origin::TOPRIGHT:
+ org->set(r, t);
+ break;
+ case Origin::MIDDLELEFT:
+ org->set(l, b / 2.f);
+ break;
+ case Origin::MIDDLECENTER:
+ org->set(r / 2.f, b / 2.f);
+ break;
+ case Origin::MIDDLERIGHT:
+ org->set(r, b / 2.f);
+ break;
+ case Origin::BOTTOMLEFT:
+ org->set(l, b);
+ break;
+ case Origin::BOTTOMCENTER:
+ org->set(r / 2.f, b);
+ break;
+ case Origin::BOTTOMRIGHT:
+ org->set(r, b);
+ break;
+ }
+ }
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin/graphics/sprite.h b/src/libjin/graphics/sprite.h
index 2acebe0..a143c17 100644
--- a/src/libjin/graphics/sprite.h
+++ b/src/libjin/graphics/sprite.h
@@ -10,46 +10,46 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- ///
- /// A sprite is unit of rendering. Animation is based on sprite, but not texture or other graphic stuff.
- ///
- class Sprite : public Object, public Renderable
- {
- public:
+ ///
+ /// A sprite is unit of rendering. Animation is based on sprite, but not texture or other graphic stuff.
+ ///
+ class Sprite : public Object, public Renderable
+ {
+ public:
- Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin);
+ Sprite(const Graphic* graphic, const Math::Quad& quad, Origin origin);
- Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy);
+ Sprite(const Graphic* graphic, const Math::Quad& quad, float ox, float oy);
- Sprite(const Graphic* graphic, Origin origin);
+ Sprite(const Graphic* graphic, Origin origin);
- Sprite(const Graphic* graphic, float ox, float oy);
+ Sprite(const Graphic* graphic, float ox, float oy);
- virtual ~Sprite();
+ virtual ~Sprite();
- Math::Vector2<int> getSize();
+ Math::Vector2<int> getSize();
- void render(float x, float y, float sx, float sy, float r) const override;
+ void render(float x, float y, float sx, float sy, float r) const override;
- private:
+ private:
- void setOrigin(Origin origin);
+ void setOrigin(Origin origin);
- const Math::Vector2<float> mOrigin;
+ const Math::Vector2<float> mOrigin;
- ///
- /// Quad of graphic.
- ///
- const Math::Quad mQuad;
+ ///
+ /// Quad of graphic.
+ ///
+ const Math::Quad mQuad;
- const Graphic* mGraphic;
+ const Graphic* mGraphic;
- };
+ };
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/sprite_batch.cpp b/src/libjin/graphics/sprite_batch.cpp
index 82e480f..7cab9be 100644
--- a/src/libjin/graphics/sprite_batch.cpp
+++ b/src/libjin/graphics/sprite_batch.cpp
@@ -2,10 +2,10 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/sprite_batch.h b/src/libjin/graphics/sprite_batch.h
index 0aad172..a224ded 100644
--- a/src/libjin/graphics/sprite_batch.h
+++ b/src/libjin/graphics/sprite_batch.h
@@ -8,22 +8,22 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- class SpriteBatch : public Object, public Renderable
- {
- public:
+ class SpriteBatch : public Object, public Renderable
+ {
+ public:
- private:
- static void createDefaultShader();
+ private:
+ static void createDefaultShader();
- //Shaders::Shader
+ //Shaders::Shader
- };
+ };
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/sprite_sheet.cpp b/src/libjin/graphics/sprite_sheet.cpp
index 24ec4fd..36fde61 100644
--- a/src/libjin/graphics/sprite_sheet.cpp
+++ b/src/libjin/graphics/sprite_sheet.cpp
@@ -10,71 +10,71 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- SpriteSheet::SpriteSheet(const Graphic* graphic)
- : mGraphic(graphic)
- {
- }
+ SpriteSheet::SpriteSheet(const Graphic* graphic)
+ : mGraphic(graphic)
+ {
+ }
- Sprite* SpriteSheet::createSprite(const Math::Quad& quad, Origin origin)
- {
- Sprite* spr = new Sprite(mGraphic, quad, origin);
- return spr;
- }
+ Sprite* SpriteSheet::createSprite(const Math::Quad& quad, Origin origin)
+ {
+ Sprite* spr = new Sprite(mGraphic, quad, origin);
+ return spr;
+ }
- Sprite* SpriteSheet::createSprite(const Math::Quad& quad, float ox, float oy)
- {
- Sprite* spr = new Sprite(mGraphic, quad, ox, oy);
- return spr;
- }
+ Sprite* SpriteSheet::createSprite(const Math::Quad& quad, float ox, float oy)
+ {
+ Sprite* spr = new Sprite(mGraphic, quad, ox, oy);
+ return spr;
+ }
- std::vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin, uint offx, uint offy)
- {
- vector<Sprite*> sprites;
- int i = 0;
- for (int r = 0; r < row; ++r)
- {
- for (int c = 0; c < colum; ++c)
- {
- Quad quad;
- quad.x = (r * colum + c) * w + offx;
- quad.y = r * h + offy;
- quad.w = w;
- quad.h = h;
- Sprite* spr = new Sprite(mGraphic, quad, origin);
- sprites.push_back(spr);
- if ((++i) == count)
- goto done;
- }
- }
- done:
- return sprites;
- }
+ std::vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin, uint offx, uint offy)
+ {
+ vector<Sprite*> sprites;
+ int i = 0;
+ for (int r = 0; r < row; ++r)
+ {
+ for (int c = 0; c < colum; ++c)
+ {
+ Quad quad;
+ quad.x = (r * colum + c) * w + offx;
+ quad.y = r * h + offy;
+ quad.w = w;
+ quad.h = h;
+ Sprite* spr = new Sprite(mGraphic, quad, origin);
+ sprites.push_back(spr);
+ if ((++i) == count)
+ goto done;
+ }
+ }
+ done:
+ return sprites;
+ }
- vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, float ox, float oy, uint offx, uint offy)
- {
- vector<Sprite*> sprites;
- int i = 0;
- for (int r = 0; r < row; ++r)
- {
- for (int c = 0; c < colum; ++c)
- {
- Quad quad;
- quad.x = (r * colum + c) * w + offx;
- quad.y = r * h + offy;
- quad.w = w;
- quad.h = h;
- Sprite* spr = new Sprite(mGraphic, quad, ox, oy);
- sprites.push_back(spr);
- if ((++i) == count)
- goto done;
- }
- }
- done:
- return sprites;
- }
+ vector<Sprite*> SpriteSheet::createSprites(uint count, uint row, uint colum, uint w, uint h, float ox, float oy, uint offx, uint offy)
+ {
+ vector<Sprite*> sprites;
+ int i = 0;
+ for (int r = 0; r < row; ++r)
+ {
+ for (int c = 0; c < colum; ++c)
+ {
+ Quad quad;
+ quad.x = (r * colum + c) * w + offx;
+ quad.y = r * h + offy;
+ quad.w = w;
+ quad.h = h;
+ Sprite* spr = new Sprite(mGraphic, quad, ox, oy);
+ sprites.push_back(spr);
+ if ((++i) == count)
+ goto done;
+ }
+ }
+ done:
+ return sprites;
+ }
- }
+ }
} \ No newline at end of file
diff --git a/src/libjin/graphics/sprite_sheet.h b/src/libjin/graphics/sprite_sheet.h
index eb50b2c..1ca72a5 100644
--- a/src/libjin/graphics/sprite_sheet.h
+++ b/src/libjin/graphics/sprite_sheet.h
@@ -9,37 +9,37 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- class SpriteSheet : public Object
- {
- public:
- SpriteSheet(const Graphic* graphic);
+ class SpriteSheet : public Object
+ {
+ public:
+ SpriteSheet(const Graphic* graphic);
- ///
- /// Create a new sprite in sheet.
- ///
- Sprite* createSprite(const Math::Quad& quad, Origin origin);
+ ///
+ /// Create a new sprite in sheet.
+ ///
+ Sprite* createSprite(const Math::Quad& quad, Origin origin);
- ///
- /// Create a new sprite in sheet.
- ///
- Sprite* createSprite(const Math::Quad& quad, float ox, float oy);
+ ///
+ /// Create a new sprite in sheet.
+ ///
+ Sprite* createSprite(const Math::Quad& quad, float ox, float oy);
- ///
- ///
- ///
- std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin = Origin::TOPLEFT, uint offx = 0, uint offy = 0);
+ ///
+ ///
+ ///
+ std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, Origin origin = Origin::TOPLEFT, uint offx = 0, uint offy = 0);
- std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, float ox = 0, float oy = 0, uint offx = 0, uint offy = 0);
+ std::vector<Sprite*> createSprites(uint count, uint row, uint colum, uint w, uint h, float ox = 0, float oy = 0, uint offx = 0, uint offy = 0);
- private:
- const Graphic* const mGraphic;
+ private:
+ const Graphic* const mGraphic;
- };
+ };
- } // namespace Graphics
+ } // namespace Graphics
} // namespace JinEngine
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/texture.cpp b/src/libjin/graphics/texture.cpp
index ba8a33a..45432d1 100644
--- a/src/libjin/graphics/texture.cpp
+++ b/src/libjin/graphics/texture.cpp
@@ -12,34 +12,34 @@ using namespace JinEngine::Math;
namespace JinEngine
{
- namespace Graphics
- {
-
- Texture::Texture()
- : Graphic()
- {
- ++gl.getStats().textures;
- }
-
- Texture::Texture(const char* path)
- {
- Bitmap* bitmap = new Bitmap(path);
- new (this) Texture(bitmap);
- delete bitmap;
- }
-
- Texture::Texture(const Bitmap* bitmap)
- : Graphic(bitmap)
- {
- ++gl.getStats().textures;
- }
-
- Texture::~Texture()
- {
- --gl.getStats().textures;
- }
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ Texture::Texture()
+ : Graphic()
+ {
+ ++gl.getStats().textures;
+ }
+
+ Texture::Texture(const char* path)
+ {
+ Bitmap* bitmap = new Bitmap(path);
+ new (this) Texture(bitmap);
+ delete bitmap;
+ }
+
+ Texture::Texture(const Bitmap* bitmap)
+ : Graphic(bitmap)
+ {
+ ++gl.getStats().textures;
+ }
+
+ Texture::~Texture()
+ {
+ --gl.getStats().textures;
+ }
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/texture.h b/src/libjin/graphics/texture.h
index 7bba557..6d5e5be 100644
--- a/src/libjin/graphics/texture.h
+++ b/src/libjin/graphics/texture.h
@@ -9,38 +9,38 @@
namespace JinEngine
{
- namespace Graphics
- {
-
- ///
- ///
- ///
- class Texture : public Graphic
- {
- public:
- ///
- ///
- ///
- Texture();
-
- ///
- ///
- ///
- Texture(const char* path);
-
- ///
- ///
- ///
- Texture(const Bitmap* bitmap);
-
- ///
- ///
- ///
- ~Texture();
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ ///
+ ///
+ ///
+ class Texture : public Graphic
+ {
+ public:
+ ///
+ ///
+ ///
+ Texture();
+
+ ///
+ ///
+ ///
+ Texture(const char* path);
+
+ ///
+ ///
+ ///
+ Texture(const Bitmap* bitmap);
+
+ ///
+ ///
+ ///
+ ~Texture();
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // jin_graphics
diff --git a/src/libjin/graphics/vertex.h b/src/libjin/graphics/vertex.h
index 192117e..2fac1cc 100644
--- a/src/libjin/graphics/vertex.h
+++ b/src/libjin/graphics/vertex.h
@@ -7,17 +7,17 @@
namespace JinEngine
{
- namespace Graphics
- {
+ namespace Graphics
+ {
- struct Vertex
- {
- Math::Vector2<float> xy;
- Math::Vector2<float> uv;
- Color color;
- };
+ struct Vertex
+ {
+ Math::Vector2<float> xy;
+ Math::Vector2<float> uv;
+ Color color;
+ };
- }
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/graphics/window.cpp b/src/libjin/graphics/window.cpp
index 479961b..0f43a28 100644
--- a/src/libjin/graphics/window.cpp
+++ b/src/libjin/graphics/window.cpp
@@ -17,106 +17,106 @@ using namespace JinEngine::Graphics::Shaders;
namespace JinEngine
{
- namespace Graphics
- {
-
- bool Window::startSystem(const SettingBase* s)
- {
- jin_log_info("Initialize window system.");
-
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- return false;
-
- const Setting* setting = (Setting*)s;
- mSize.w() = setting->width;
- mSize.h() = setting->height;
- mFps = setting->fps;
- bool vsync = setting->vsync;
- const char* title = setting->title;
- const char* icon = setting->icon;
-
- if (mWnd)
- {
- SDL_DestroyWindow(mWnd);
- SDL_FlushEvent(SDL_WINDOWEVENT);
- }
-
- SDL_GLContext ctx = NULL;
-
- if (ctx)
- {
- SDL_GL_DeleteContext(ctx);
- }
-
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
-
- int wx = SDL_WINDOWPOS_UNDEFINED,
- wy = SDL_WINDOWPOS_UNDEFINED;
-
- int flag = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL;
- if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN;
- if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE;
-
- mWnd = SDL_CreateWindow(title, wx, wy, mSize.w(), mSize.h(), flag);
- if (mWnd == NULL)
- return false;
-
- // Set window icon.
- //try
- //{
- // Bitmap* bitmap = new Bitmap(icon);
- // SDL_Surface *surface;
- // Color* pixels = const_cast<Color*>(bitmap->getPixels());
- // uint w = bitmap->getWidth(), h = bitmap->getHeight();
- // surface = SDL_CreateRGBSurfaceFrom(
- // pixels, w, h, 32, w * 4, Color::RMASK, Color::GMASK, Color::BMASK, Color::AMASK);
- // SDL_SetWindowIcon(mWnd, surface);
- // SDL_FreeSurface(surface);
- //} catch (...) {}
-
- ctx = SDL_GL_CreateContext(mWnd);
- if (ctx == NULL)
- return false;
-
- gl.loadGL();
-
- SDL_GL_SetSwapInterval(vsync ? 1 : 0);
- SDL_GL_MakeCurrent(mWnd, ctx);
-
- // Default configuration.
- gl.init();
-
- return true;
- }
-
- void Window::quitSystem()
- {
- jin_log_info("Quit window system.");
-
- SDL_DestroyWindow(mWnd);
- }
-
- void Window::present()
- {
- if (mWnd)
- SDL_GL_SwapWindow(mWnd);
- gl.resetStats();
- }
-
- void Window::setTitle(const char* title)
- {
- SDL_SetWindowTitle(mWnd, title);
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+
+ bool Window::startSystem(const SettingBase* s)
+ {
+ jin_log_info("Initialize window system.");
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ return false;
+
+ const Setting* setting = (Setting*)s;
+ mSize.w() = setting->width;
+ mSize.h() = setting->height;
+ mFps = setting->fps;
+ bool vsync = setting->vsync;
+ const char* title = setting->title;
+ const char* icon = setting->icon;
+
+ if (mWnd)
+ {
+ SDL_DestroyWindow(mWnd);
+ SDL_FlushEvent(SDL_WINDOWEVENT);
+ }
+
+ SDL_GLContext ctx = NULL;
+
+ if (ctx)
+ {
+ SDL_GL_DeleteContext(ctx);
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
+
+ int wx = SDL_WINDOWPOS_UNDEFINED,
+ wy = SDL_WINDOWPOS_UNDEFINED;
+
+ int flag = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL;
+ if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN;
+ if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE;
+
+ mWnd = SDL_CreateWindow(title, wx, wy, mSize.w(), mSize.h(), flag);
+ if (mWnd == NULL)
+ return false;
+
+ // Set window icon.
+ //try
+ //{
+ // Bitmap* bitmap = new Bitmap(icon);
+ // SDL_Surface *surface;
+ // Color* pixels = const_cast<Color*>(bitmap->getPixels());
+ // uint w = bitmap->getWidth(), h = bitmap->getHeight();
+ // surface = SDL_CreateRGBSurfaceFrom(
+ // pixels, w, h, 32, w * 4, Color::RMASK, Color::GMASK, Color::BMASK, Color::AMASK);
+ // SDL_SetWindowIcon(mWnd, surface);
+ // SDL_FreeSurface(surface);
+ //} catch (...) {}
+
+ ctx = SDL_GL_CreateContext(mWnd);
+ if (ctx == NULL)
+ return false;
+
+ gl.loadGL();
+
+ SDL_GL_SetSwapInterval(vsync ? 1 : 0);
+ SDL_GL_MakeCurrent(mWnd, ctx);
+
+ // Default configuration.
+ gl.init();
+
+ return true;
+ }
+
+ void Window::quitSystem()
+ {
+ jin_log_info("Quit window system.");
+
+ SDL_DestroyWindow(mWnd);
+ }
+
+ void Window::present()
+ {
+ if (mWnd)
+ SDL_GL_SwapWindow(mWnd);
+ gl.resetStats();
+ }
+
+ void Window::setTitle(const char* title)
+ {
+ SDL_SetWindowTitle(mWnd, title);
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // defined(jin_graphics) \ No newline at end of file
diff --git a/src/libjin/graphics/window.h b/src/libjin/graphics/window.h
index c279e9b..605cebe 100644
--- a/src/libjin/graphics/window.h
+++ b/src/libjin/graphics/window.h
@@ -11,94 +11,94 @@
namespace JinEngine
{
- namespace Graphics
- {
- ///
- ///
- ///
- class Window
- : public Subsystem<Window>
- {
- public:
- ///
- ///
- ///
- struct Setting : SettingBase
- {
- public:
- const char* title; ///< window title
- const char* icon; ///< window icon
- bool fullscreen; ///< full screen
- int width, height; ///< window size
- bool vsync; ///< vsync
- int fps; ///< frame per second
- bool resizable; ///< resizable
- };
-
- ///
- ///
- ///
- Window() {};
-
- ///
- ///
- ///
- virtual ~Window() {};
-
- ///
- ///
- ///
- void setTitle(const char* title);
-
- ///
- ///
- ///
- inline int getW(){ return mSize.w(); }
-
- ///
- ///
- ///
- inline int getH(){ return mSize.h(); }
-
- ///
- ///
- ///
- inline int getFPS(){ return mFps; }
-
- ///
- ///
- ///
- void present();
-
- ///
- ///
- ///
- inline void hide() { SDL_HideWindow(mWnd); };
-
- ///
- ///
- ///
- void show() { SDL_ShowWindow(mWnd); };
-
- private:
-
- ///
- ///
- ///
- bool startSystem(const SettingBase* setting) override;
-
- ///
- ///
- ///
- void quitSystem() override;
-
- SDL_Window* mWnd;
- JinEngine::Math::Vector2<unsigned int> mSize;
- int mFps;
-
- };
-
- } // namespace Graphics
+ namespace Graphics
+ {
+ ///
+ ///
+ ///
+ class Window
+ : public Subsystem<Window>
+ {
+ public:
+ ///
+ ///
+ ///
+ struct Setting : SettingBase
+ {
+ public:
+ const char* title; ///< window title
+ const char* icon; ///< window icon
+ bool fullscreen; ///< full screen
+ int width, height; ///< window size
+ bool vsync; ///< vsync
+ int fps; ///< frame per second
+ bool resizable; ///< resizable
+ };
+
+ ///
+ ///
+ ///
+ Window() {};
+
+ ///
+ ///
+ ///
+ virtual ~Window() {};
+
+ ///
+ ///
+ ///
+ void setTitle(const char* title);
+
+ ///
+ ///
+ ///
+ inline int getW(){ return mSize.w(); }
+
+ ///
+ ///
+ ///
+ inline int getH(){ return mSize.h(); }
+
+ ///
+ ///
+ ///
+ inline int getFPS(){ return mFps; }
+
+ ///
+ ///
+ ///
+ void present();
+
+ ///
+ ///
+ ///
+ inline void hide() { SDL_HideWindow(mWnd); };
+
+ ///
+ ///
+ ///
+ void show() { SDL_ShowWindow(mWnd); };
+
+ private:
+
+ ///
+ ///
+ ///
+ bool startSystem(const SettingBase* setting) override;
+
+ ///
+ ///
+ ///
+ void quitSystem() override;
+
+ SDL_Window* mWnd;
+ JinEngine::Math::Vector2<unsigned int> mSize;
+ int mFps;
+
+ };
+
+ } // namespace Graphics
} // namespace JinEngine
#endif // jin_graphics