diff options
Diffstat (limited to 'src/libjin/graphics')
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, ¤t_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, ¤t_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 |