diff options
Diffstat (limited to 'src/libjin/Graphics')
28 files changed, 2057 insertions, 2057 deletions
diff --git a/src/libjin/Graphics/Bitmap.cpp b/src/libjin/Graphics/Bitmap.cpp index 160fda2..8769e8f 100644 --- a/src/libjin/Graphics/Bitmap.cpp +++ b/src/libjin/Graphics/Bitmap.cpp @@ -7,144 +7,144 @@ using namespace jin::math; namespace jin { -namespace graphics -{ - - /* pixelbitmap */ - Bitmap* Bitmap::createBitmap(const void* pixel, unsigned width, unsigned height) - { - Bitmap* bitmap = new Bitmap(width, height); - memcpy(bitmap->pixels, pixel, width*height * sizeof(Color)); - return bitmap; - } - - /*static*/ Bitmap* Bitmap::createBitmap(const void* imgData, size_t size) - { - if (imgData == nullptr) - return nullptr; - int w, h; - void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha); - if (data == nullptr) - return nullptr; - Bitmap* bitmap = new Bitmap(); - bitmap->pixels = (Color*)data; - bitmap->width = w; - bitmap->height = h; - return bitmap; - } - - /*static*/ Bitmap* Bitmap::createBitmap(int w, int h, Color color) - { - Bitmap* bitmap = new Bitmap(w, h); - if (color != Color::BLACK) - bitmap->setPixels(color); - return bitmap; - } - - /*static */ Bitmap* Bitmap::clone(const Bitmap* bitmap) - { - Bitmap* b = new Bitmap(); - int w = bitmap->getWidth(); - int h = bitmap->getHeight(); - b->resetPixels(bitmap->getPixels(), w, h); - 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]; - } - - 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]; - 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) - return; - if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) - return; - 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]; - size_t s = w * h * sizeof(Color); - 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) - { - 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]; - } + namespace graphics + { + + /* pixelbitmap */ + Bitmap* Bitmap::createBitmap(const void* pixel, unsigned width, unsigned height) + { + Bitmap* bitmap = new Bitmap(width, height); + memcpy(bitmap->pixels, pixel, width*height * sizeof(Color)); + return bitmap; + } + + /*static*/ Bitmap* Bitmap::createBitmap(const void* imgData, size_t size) + { + if (imgData == nullptr) + return nullptr; + int w, h; + void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha); + if (data == nullptr) + return nullptr; + Bitmap* bitmap = new Bitmap(); + bitmap->pixels = (Color*)data; + bitmap->width = w; + bitmap->height = h; + return bitmap; + } + + /*static*/ Bitmap* Bitmap::createBitmap(int w, int h, Color color) + { + Bitmap* bitmap = new Bitmap(w, h); + if (color != Color::BLACK) + bitmap->setPixels(color); + return bitmap; + } + + /*static */ Bitmap* Bitmap::clone(const Bitmap* bitmap) + { + Bitmap* b = new Bitmap(); + int w = bitmap->getWidth(); + int h = bitmap->getHeight(); + b->resetPixels(bitmap->getPixels(), w, h); + 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]; + } + + 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]; + 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) + return; + if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) + return; + 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]; + size_t s = w * h * sizeof(Color); + 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) + { + 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; - } + const Color* Bitmap::getPixels() const + { + return pixels; + } -} + } }
\ No newline at end of file diff --git a/src/libjin/Graphics/Bitmap.h b/src/libjin/Graphics/Bitmap.h index 6264c37..5599521 100644 --- a/src/libjin/Graphics/Bitmap.h +++ b/src/libjin/Graphics/Bitmap.h @@ -9,43 +9,43 @@ namespace jin { -namespace graphics -{ - - class Bitmap - { - public: - static Bitmap* createBitmap(const void* pixel, unsigned width, unsigned height); - static Bitmap* createBitmap(const void* imgData, size_t size); - static Bitmap* createBitmap(int w, int h, Color color = Color::BLACK); - static Bitmap* clone(const Bitmap* bitmap); - - virtual ~Bitmap(); - /* init pixels */ - 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); - /* modify pixels */ - void setPixel(const Color& pixel, int x, int y); - void setPixels(Color pixels); - void setPixels(Color* pixels); - Color getPixel(int x, int y); - const Color* getPixels() const; - /* get width and height */ - inline int getWidth() const { return width; } - inline int getHeight() const { return height; } - inline math::Vector2<int> getSize() const { return math::Vector2<int>(width, height); } - - protected: - Bitmap(); - Bitmap(unsigned w, unsigned h); - - Color * pixels; - unsigned width, height; - - }; - -} // graphics + namespace graphics + { + + class Bitmap + { + public: + static Bitmap* createBitmap(const void* pixel, unsigned width, unsigned height); + static Bitmap* createBitmap(const void* imgData, size_t size); + static Bitmap* createBitmap(int w, int h, Color color = Color::BLACK); + static Bitmap* clone(const Bitmap* bitmap); + + virtual ~Bitmap(); + /* init pixels */ + 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); + /* modify pixels */ + void setPixel(const Color& pixel, int x, int y); + void setPixels(Color pixels); + void setPixels(Color* pixels); + Color getPixel(int x, int y); + const Color* getPixels() const; + /* get width and height */ + inline int getWidth() const { return width; } + inline int getHeight() const { return height; } + inline math::Vector2<int> getSize() const { return math::Vector2<int>(width, height); } + + protected: + Bitmap(); + Bitmap(unsigned w, unsigned h); + + Color * pixels; + unsigned width, height; + + }; + + } // graphics } // jin #endif diff --git a/src/libjin/Graphics/Canvas.cpp b/src/libjin/Graphics/Canvas.cpp index d34731a..6db06c6 100644 --- a/src/libjin/Graphics/Canvas.cpp +++ b/src/libjin/Graphics/Canvas.cpp @@ -7,96 +7,96 @@ namespace jin { -namespace graphics -{ - - /*class member*/ const Canvas* Canvas::current = nullptr; - /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0); - - /*class member*/ Canvas* Canvas::createCanvas(int w, int h) - { - return new Canvas(w, h); - } - - Canvas::Canvas(GLuint n) - : fbo(n) - { - } - - Canvas::Canvas(int w, int h) - : Drawable(w, h) - { - GLint current_fbo; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - - /* generate a new render buffer object */ - fbo = gl.genFrameBuffer(); - gl.bindFrameBuffer(fbo); - - /* generate texture save target */ - texture = gl.genTexture(); - gl.bindTexture(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); - gl.bindTexture(0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - /* unbind framebuffer */ - gl.bindFrameBuffer(current_fbo); - } - - Canvas::~Canvas() - { - } - - /*class member*/ bool Canvas::isBinded(const Canvas* cvs) - { - return current == cvs; - } - - /** - * bind to canvas - */ - /*class member*/ void Canvas::bind(Canvas* canvas) - { - if (isBinded(canvas)) return; - current = canvas; - gl.bindFrameBuffer(canvas->fbo); - int w = canvas->size.w; - int h = canvas->size.h; - /* set view port to canvas */ - glViewport(0, 0, w, h); - gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1); - } - - /** - * 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 - */ - /*class member*/ void Canvas::unbind() - { - if (isBinded(DEFAULT_CANVAS)) return; - current = DEFAULT_CANVAS; - /* get window size as viewport */ - Window* wnd = Window::get(); - int w = wnd->getW(); - int h = wnd->getH(); - - glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo); - - /* set viewport on screen */ - glViewport(0, 0, w, h); - - gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1); - - } - -} // render + namespace graphics + { + + /*class member*/ const Canvas* Canvas::current = nullptr; + /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0); + + /*class member*/ Canvas* Canvas::createCanvas(int w, int h) + { + return new Canvas(w, h); + } + + Canvas::Canvas(GLuint n) + : fbo(n) + { + } + + Canvas::Canvas(int w, int h) + : Drawable(w, h) + { + GLint current_fbo; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + + /* generate a new render buffer object */ + fbo = gl.genFrameBuffer(); + gl.bindFrameBuffer(fbo); + + /* generate texture save target */ + texture = gl.genTexture(); + gl.bindTexture(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); + gl.bindTexture(0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + /* unbind framebuffer */ + gl.bindFrameBuffer(current_fbo); + } + + Canvas::~Canvas() + { + } + + /*class member*/ bool Canvas::isBinded(const Canvas* cvs) + { + return current == cvs; + } + + /** + * bind to canvas + */ + /*class member*/ void Canvas::bind(Canvas* canvas) + { + if (isBinded(canvas)) return; + current = canvas; + gl.bindFrameBuffer(canvas->fbo); + int w = canvas->size.w; + int h = canvas->size.h; + /* set view port to canvas */ + glViewport(0, 0, w, h); + gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1); + } + + /** + * 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 + */ + /*class member*/ void Canvas::unbind() + { + if (isBinded(DEFAULT_CANVAS)) return; + current = DEFAULT_CANVAS; + /* get window size as viewport */ + Window* wnd = Window::get(); + int w = wnd->getW(); + int h = wnd->getH(); + + glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo); + + /* set viewport on screen */ + glViewport(0, 0, w, h); + + gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1); + + } + + } // render } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Canvas.h b/src/libjin/Graphics/Canvas.h index 09ae7aa..4851c83 100644 --- a/src/libjin/Graphics/Canvas.h +++ b/src/libjin/Graphics/Canvas.h @@ -6,33 +6,33 @@ #include "drawable.h" namespace jin { -namespace graphics -{ + namespace graphics + { - class Canvas: public Drawable - { - public: - static Canvas* createCanvas(int w, int h); + class Canvas: public Drawable + { + public: + static Canvas* createCanvas(int w, int h); - static void bind(Canvas*); - static void unbind(); - static bool isBinded(const Canvas*); + static void bind(Canvas*); + static void unbind(); + static bool isBinded(const Canvas*); - ~Canvas(); + ~Canvas(); - protected: - static const Canvas* const DEFAULT_CANVAS; - static const Canvas* current; + protected: + static const Canvas* const DEFAULT_CANVAS; + static const Canvas* current; - Canvas(int w, int h); - Canvas(GLuint n); + Canvas(int w, int h); + Canvas(GLuint n); - GLuint fbo; + GLuint fbo; - }; + }; -} // render + } // render } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Color.cpp b/src/libjin/Graphics/Color.cpp index 414b248..517af50 100644 --- a/src/libjin/Graphics/Color.cpp +++ b/src/libjin/Graphics/Color.cpp @@ -2,16 +2,16 @@ namespace jin { -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); -} + } }
\ No newline at end of file diff --git a/src/libjin/Graphics/Color.h b/src/libjin/Graphics/Color.h index 3de49dc..b235a66 100644 --- a/src/libjin/Graphics/Color.h +++ b/src/libjin/Graphics/Color.h @@ -10,75 +10,75 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - typedef unsigned char Channel; + typedef unsigned char 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; + 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; - Color() { r = g = b = a = 0; }; + 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(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; - } + 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 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; - } + 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; + } - 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; + Channel r, g, b, a; - }; + }; -} // render + } // render } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Font/Decoder.cpp b/src/libjin/Graphics/Font/Decoder.cpp index 10927f0..856627b 100644 --- a/src/libjin/Graphics/Font/Decoder.cpp +++ b/src/libjin/Graphics/Font/Decoder.cpp @@ -4,90 +4,90 @@ namespace jin { -namespace graphics -{ - - /* utf8 byte string to unicode codepoint */ - static const char *utf8toCodepoint(const char *p, unsigned *res) { - return nullptr; + namespace graphics + { - } + /* utf8 byte string to unicode codepoint */ + static const char *utf8toCodepoint(const char *p, unsigned *res) { + return nullptr; - ///////////////////////////////////////////////////////////////////////////// - // 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; - } + ///////////////////////////////////////////////////////////////////////////// + // decoders + ///////////////////////////////////////////////////////////////////////////// - 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: + 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; } - x = (*p & mask) << shift; - do { - if (*(++p) == '\0') { - return p; + + 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; } - shift -= 6; - x |= (*p & 0x3f) << shift; - } while (shift); - return p + 1; - } -/* - const void* Utf16::decode(const void* data, Codepoint* res) const - { - return nullptr; - } + 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; + } -} // graphics + } // graphics } // jin
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/Decoder.h b/src/libjin/Graphics/Font/Decoder.h index 4568d65..e5940a2 100644 --- a/src/libjin/Graphics/Font/Decoder.h +++ b/src/libjin/Graphics/Font/Decoder.h @@ -7,38 +7,38 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - class Decoder - { - public: - virtual const void* decode(const void* data, Codepoint* c) const = 0 ; - virtual const void* next(const void* data) const = 0; - }; + class Decoder + { + public: + virtual const void* decode(const void* data, Codepoint* c) const = 0 ; + virtual const void* next(const void* data) const = 0; + }; - class Utf8 : public Decoder - { - public: - const void* decode(const void* data, Codepoint* c) const override; - const void* next(const void* data) const override; - }; -/* - class Utf16 : public Decoder - { - public: - const void* decode(const void* data, Codepoint* c) const override; - const void* next(const void* data) const override; - }; -*/ - class Ascii : public Decoder - { - public: - const void* decode(const void* data, Codepoint* c) const override; - const void* next(const void* data) const override; - }; + class Utf8 : public Decoder + { + public: + const void* decode(const void* data, Codepoint* c) const override; + const void* next(const void* data) const override; + }; + /* + class Utf16 : public Decoder + { + public: + const void* decode(const void* data, Codepoint* c) const override; + const void* next(const void* data) const override; + }; + */ + class Ascii : public Decoder + { + public: + const void* decode(const void* data, Codepoint* c) const override; + const void* next(const void* data) const override; + }; -} // graphics + } // graphics } // jin #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/Font.h b/src/libjin/Graphics/Font/Font.h index fcc559c..9ccef54 100644 --- a/src/libjin/Graphics/Font/Font.h +++ b/src/libjin/Graphics/Font/Font.h @@ -5,35 +5,35 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - struct Page; + struct Page; - class Font - { - public: - Font(unsigned fontsize) - : fontSize(fontsize) - { - } - virtual ~Font() {}; + class Font + { + public: + Font(unsigned fontsize) + : fontSize(fontsize) + { + } + virtual ~Font() {}; - virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; - virtual Page* typeset(const Content& text, int lineheight, int spacing = 0) = 0; + virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; + virtual Page* typeset(const Content& text, int lineheight, int spacing = 0) = 0; - virtual void print(const Page* page, int x, int y) = 0; - virtual void print(const Content& text, int x, int y, int lineheight, int spacing = 0) = 0; - virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; + virtual void print(const Page* page, int x, int y) = 0; + virtual void print(const Content& text, int x, int y, int lineheight, int spacing = 0) = 0; + virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; - inline unsigned getFontSize() { return fontSize; }; + inline unsigned getFontSize() { return fontSize; }; - protected: - unsigned fontSize; + protected: + unsigned fontSize; - }; + }; -} // graphics + } // graphics } // jin #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/Page.h b/src/libjin/Graphics/Font/Page.h index 6e7cbdf..e1430e1 100644 --- a/src/libjin/Graphics/Font/Page.h +++ b/src/libjin/Graphics/Font/Page.h @@ -5,34 +5,34 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - class Font; + class Font; - struct GlyphVertex - { - int x, y; // screen coordinates - float u, v; // texture uv - }; + struct GlyphVertex + { + int x, y; // screen coordinates + float u, v; // texture uv + }; - struct GlyphArrayDrawInfo - { - GLuint texture; // atlas - unsigned int start; // glyph vertex indecies - unsigned int count; // glyph vertex count - }; + struct GlyphArrayDrawInfo + { + GLuint texture; // atlas + unsigned int start; // glyph vertex indecies + unsigned int count; // glyph vertex count + }; - /* for reduce draw call */ - struct Page - { - Font* font; - std::vector<GlyphArrayDrawInfo> glyphinfolist; - std::vector<GlyphVertex> glyphvertices; - math::Vector2<int> size; - }; + /* for reduce draw call */ + struct Page + { + Font* font; + std::vector<GlyphArrayDrawInfo> glyphinfolist; + std::vector<GlyphVertex> glyphvertices; + math::Vector2<int> size; + }; -} + } } #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/TTF.cpp b/src/libjin/Graphics/Font/TTF.cpp index 105bcfb..7e62485 100644 --- a/src/libjin/Graphics/Font/TTF.cpp +++ b/src/libjin/Graphics/Font/TTF.cpp @@ -15,440 +15,440 @@ namespace jin { -namespace graphics -{ - - ///////////////////////////////////////////////////////////////////////////// - // TTFData - ///////////////////////////////////////////////////////////////////////////// - - TTFData* TTFData::createTTFData(const unsigned char* data, unsigned int size) - { - TTFData* ttf = nullptr; - try - { - ttf = new TTFData(data, size); - return ttf; - } - catch (...) - { - return nullptr; - } - } - - 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) + namespace graphics { - TTF* ttf; - try + + ///////////////////////////////////////////////////////////////////////////// + // TTFData + ///////////////////////////////////////////////////////////////////////////// + + TTFData* TTFData::createTTFData(const unsigned char* data, unsigned int size) + { + TTFData* ttf = nullptr; + try + { + ttf = new TTFData(data, size); + return ttf; + } + catch (...) + { + return nullptr; + } + } + + 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/font.shader.h" + + using namespace std; + using namespace jin::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) + { + } + + ///*static*/ 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() { - ttf = new TTF(this, fontSize); } - catch (...) + + GLuint TTF::createAtlas() { - return nullptr; + GLuint t; + gl.flushError(); + t = gl.genTexture(); + gl.bindTexture(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); + gl.bindTexture(0); + return 0; + } + atlases.push_back(t); + gl.bindTexture(0); + return t; } - 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/font.shader.h" - - using namespace std; - using namespace jin::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) - { - } - - ///*static*/ 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.bindTexture(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); - gl.bindTexture(0); - return 0; - } - atlases.push_back(t); - gl.bindTexture(0); - return t; - } - void TTF::print(const Content& t, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(t, lineheight, spacing); - print(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; - } - 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::print(const Page* page, int x, int y) - { - Shader* shader = Shader::getCurrentShader(); - const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - for (int i = 0; i < glyphinfolist.size(); ++i) - { - const GlyphArrayDrawInfo& info = glyphinfolist[i]; - shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); - shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); - gl.bindTexture(info.texture); - gl.drawArrays(GL_QUADS, 0, info.count); - gl.bindTexture(0); - } - } - - void TTF::print(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */) - { - print(*text, x, y, lineheight, spacing); - } - - int TTF::getCharWidth(int c) - { - int adw, lsb; - ttf->pushTTFsize(fontSize); - 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(fontSize); - 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(fontSize); - 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(fontSize); - *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(fontSize); - 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.bindTexture(atlas); - gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); - gl.bindTexture(); - 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); - } - -} // graphics + void TTF::print(const Content& t, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(t, lineheight, spacing); + print(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; + } + 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::print(const Page* page, int x, int y) + { + Shader* shader = Shader::getCurrentShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + for (int i = 0; i < glyphinfolist.size(); ++i) + { + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); + shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + gl.bindTexture(0); + } + } + + void TTF::print(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */) + { + print(*text, x, y, lineheight, spacing); + } + + int TTF::getCharWidth(int c) + { + int adw, lsb; + ttf->pushTTFsize(fontSize); + 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(fontSize); + 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(fontSize); + 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(fontSize); + *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(fontSize); + 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.bindTexture(atlas); + gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); + gl.bindTexture(); + 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); + } + + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/TTF.h b/src/libjin/Graphics/Font/TTF.h index 804cd9d..fc2eca3 100644 --- a/src/libjin/Graphics/Font/TTF.h +++ b/src/libjin/Graphics/Font/TTF.h @@ -17,115 +17,115 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - class TTF; + class TTF; - /** - * TTFData - * |- TTF(14px) - * |- TTF(15px) - * . - * . - * . - */ - class TTFData - { - public: - static TTFData* createTTFData(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; - - TTFData(const unsigned char* data, unsigned int size); - - stbtt_fontinfo info; - struct - { - unsigned char* data; - unsigned int size; - } raw; - std::vector<float> scales; - - }; - - class TTF : public Font - { - 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 print(const Text& text, int x, int y, int lineheight, int spacing = 0) override; - void print(const Content& text, int x, int y, int lineheight, int spacing = 0) override; - void print(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; - - /* cursor helped render to texture */ - math::Vector2<float> cursor; - - }; - -} // graphics + /** + * TTFData + * |- TTF(14px) + * |- TTF(15px) + * . + * . + * . + */ + class TTFData + { + public: + static TTFData* createTTFData(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; + + TTFData(const unsigned char* data, unsigned int size); + + stbtt_fontinfo info; + struct + { + unsigned char* data; + unsigned int size; + } raw; + std::vector<float> scales; + + }; + + class TTF : public Font + { + 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 print(const Text& text, int x, int y, int lineheight, int spacing = 0) override; + void print(const Content& text, int x, int y, int lineheight, int spacing = 0) override; + void print(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; + + /* cursor helped render to texture */ + math::Vector2<float> cursor; + + }; + + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Font/Text.cpp b/src/libjin/Graphics/Font/Text.cpp index f202267..ac0242e 100644 --- a/src/libjin/Graphics/Font/Text.cpp +++ b/src/libjin/Graphics/Font/Text.cpp @@ -5,152 +5,152 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - ///////////////////////////////////////////////////////////////////////////// - // iterator - ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + // iterator + ///////////////////////////////////////////////////////////////////////////// - Text::Iterator::Iterator(const Iterator& itor) - : data(itor.data) - , p(itor.p) - , encode(itor.encode) - , length(itor.length) - { - switch (encode) + Text::Iterator::Iterator(const Iterator& itor) + : data(itor.data) + , p(itor.p) + , encode(itor.encode) + , length(itor.length) { - case Encode::UTF8: decoder = new Utf8(); break; - //case Encode::UTF16: decoder = new Utf16(); break; - case Encode::ASCII: decoder = new Ascii(); break; + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + //case Encode::UTF16: decoder = new Utf16(); 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) + Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length) + : data(_data) + , p(_data) + , encode(_encode) + , length(_length) { - case Encode::UTF8: decoder = new Utf8(); break; - //case Encode::UTF16: decoder = new Utf16(); break; - case Encode::ASCII: decoder = new Ascii(); break; + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + //case Encode::UTF16: decoder = new Utf16(); break; + case Encode::ASCII: decoder = new Ascii(); break; + } } - } - Text::Iterator::~Iterator() - { - delete decoder; - } + Text::Iterator::~Iterator() + { + delete decoder; + } - Codepoint Text::Iterator::get() - { - Codepoint codepoint; - decoder->decode(p, &codepoint); - return codepoint; - } + 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; - } + 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; - } + 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; - } + 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 ++() + { + 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; - } + 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); + } - 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::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) + Text::Text(Encode encode, const void* data) { - content.push_back(*it); + 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) + Text::Text(Encode encode, const void* data, unsigned length) { - content.push_back(*it); + Iterator end = Iterator(encode, data, length); + end.toEnd(); + Iterator it = Iterator(encode, data, length); + for (; it != end; ++it) + { + content.push_back(*it); + } } - } - Text::~Text() - { - } + Text::~Text() + { + } - const Content& Text::getContent() const - { - return content; - } + const Content& Text::getContent() const + { + return content; + } - const Content& Text::operator*() const - { - return content; - } + const Content& Text::operator*() const + { + return content; + } -} // graphics + } // graphics } // jin
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/Text.h b/src/libjin/Graphics/Font/Text.h index 9fe152d..a4cbcbf 100644 --- a/src/libjin/Graphics/Font/Text.h +++ b/src/libjin/Graphics/Font/Text.h @@ -5,70 +5,70 @@ namespace jin { -namespace graphics -{ - - typedef unsigned int Codepoint; - - typedef std::vector<Codepoint> Content; + namespace graphics + { - class Text; - class Decoder; + typedef unsigned int Codepoint; - enum Encode - { - UTF8, // utf-8 - //UTF16, // utf-16 - ASCII, // ASCII - }; + typedef std::vector<Codepoint> Content; - /* raw encoded text */ - class Text - { - public: - Text(Encode encode, const void* data); - Text(Encode encode, const void* data, unsigned int length); - ~Text(); + class Text; + class Decoder; - const Content& getContent() const; - const Content& operator*() const; + enum Encode + { + UTF8, // utf-8 + //UTF16, // utf-16 + ASCII, // ASCII + }; - private: - class Iterator + /* raw encoded text */ + class Text { 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 *(); - /* prefix ++ */ - Iterator& operator ++(); - /* postfix ++ */ - Iterator operator ++(int); - bool operator !=(const Iterator& itor); - bool operator ==(const Iterator& itor); + 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: - void operator = (const Iterator&); + 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 *(); + /* prefix ++ */ + Iterator& operator ++(); + /* postfix ++ */ + 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; - const Encode encode; - const Decoder* decoder; - const void* p; - const void* const data; - unsigned int length; }; - Content content; - - }; - -} // graphics + } // graphics } // jin #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/TextureFont.cpp b/src/libjin/Graphics/Font/TextureFont.cpp index a1f2b27..8c9c4ac 100644 --- a/src/libjin/Graphics/Font/TextureFont.cpp +++ b/src/libjin/Graphics/Font/TextureFont.cpp @@ -6,295 +6,295 @@ namespace jin { -namespace graphics -{ - - using namespace std; - using namespace math; - - TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) - { - TextureFont* tf = new TextureFont(bitmap, codepoints, cellw, cellh); - return tf; - } - - TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, int cellw, int cellh) + namespace graphics { - TextureFont* tf = new TextureFont(bitmap, *codepoints, cellw, cellh); - return tf; - } - TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) - { - TextureFont* tf = new TextureFont(bitmap, codepoints, mask, cellh); - return tf; - } + using namespace std; + using namespace math; - TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, Color mask, int cellh) - { - TextureFont* tf = new TextureFont(bitmap, *codepoints, mask, cellh); - return tf; - } + TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, codepoints, cellw, cellh); + return tf; + } - TextureFont::~TextureFont() - { - } + TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, int cellw, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, *codepoints, cellw, cellh); + return tf; + } - const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const - { - auto it = glyphs.find(codepoint); - if (it != glyphs.end()) + TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) { - return &it->second; + TextureFont* tf = new TextureFont(bitmap, codepoints, mask, cellh); + return tf; } - 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; + TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, Color mask, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, *codepoints, mask, cellh); + return tf; + } -#define glyphvertices_push(_x, _y, _u, _v) \ - vertex.x = _x; vertex.y = _y;\ - vertex.u = _u; vertex.v = _v;\ - glyphvertices.push_back(vertex);\ + TextureFont::~TextureFont() + { + } - for (Codepoint c : text) + const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const { - if (c == 0x0D) continue; - if (c == 0x0A) + auto it = glyphs.find(codepoint); + if (it != glyphs.end()) { - /* new line */ - p.y += lineheight; - p.x = 0; - continue; + return &it->second; } - glyph = findGlyph(c); - if (glyph == nullptr) continue; - if (texture != this->texture) - { - texture = this->texture; - GlyphArrayDrawInfo info; - info.start = i; - info.count = 0; - info.texture = texture; - glyphinfolist.push_back(info); - } - glyphinfolist[glyphinfolist.size() - 1].count += 4; - // normalized - float nx = glyph->x / (float)size.w, ny = glyph->y / (float)size.h; - float nw = glyph->w / (float)size.w, nh = glyph->h / (float)size.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; + else + return nullptr; } - 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()) + Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) { - return it->second.w; + 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);\ + + for (Codepoint c : text) + { + if (c == 0x0D) continue; + if (c == 0x0A) + { + /* new line */ + p.y += lineheight; + p.x = 0; + continue; + } + glyph = findGlyph(c); + if (glyph == nullptr) continue; + if (texture != this->texture) + { + texture = this->texture; + GlyphArrayDrawInfo info; + info.start = i; + info.count = 0; + info.texture = texture; + glyphinfolist.push_back(info); + } + glyphinfolist[glyphinfolist.size() - 1].count += 4; + // normalized + float nx = glyph->x / (float)size.w, ny = glyph->y / (float)size.h; + float nw = glyph->w / (float)size.w, nh = glyph->h / (float)size.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; } - return 0; - } - int TextureFont::getCharHeight(int c) - { - auto it = glyphs.find(c); - if (it != glyphs.end()) + int TextureFont::getCharWidth(int c) { - return it->second.h; + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.w; + } + return 0; } - return 0; - } - int TextureFont::getTextWidth(const Content& t, int spacing) - { - int res = 0; - int tmp = 0; - for (Codepoint c : t) + int TextureFont::getCharHeight(int c) { - if (c == 0x0D) - continue; - if (c == 0x0A) + auto it = glyphs.find(c); + if (it != glyphs.end()) { - tmp = 0; - continue; + return it->second.h; } - tmp += getCharWidth(c) + spacing; - if (tmp > res) - res = tmp; + return 0; } - return res; - } - int TextureFont::getTextHeight(const Content& t, int lineheight) - { - int res = 0; - bool newline = true; - for (Codepoint c : t) + int TextureFont::getTextWidth(const Content& t, int spacing) { - if (c == 0x0A) - newline = true; - else if (c == 0x0D); - else if (newline) + int res = 0; + int tmp = 0; + for (Codepoint c : t) { - newline = false; - res += lineheight; + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + continue; + } + tmp += getCharWidth(c) + spacing; + if (tmp > res) + res = tmp; } + return res; } - 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) + int TextureFont::getTextHeight(const Content& t, int lineheight) { - if (c == 0x0D) - continue; - if (c == 0x0A) + int res = 0; + bool newline = true; + for (Codepoint c : t) { - tmp = 0; - newline = true; - continue; + if (c == 0x0A) + newline = true; + else if (c == 0x0D); + else if (newline) + { + newline = false; + res += lineheight; + } } - else if (newline) + 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) { - newline = false; - *h += lineheight; + 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; } - tmp += getCharWidth(c) + spacing; - if (tmp > *w) - *w = tmp; } - } - - Page* TextureFont::typeset(const Text& text, int lineheight, int spacing) - { - return typeset(*text, lineheight, spacing); - } - void TextureFont::print(const Page* page, int x, int y) - { - Shader* shader = Shader::getCurrentShader(); - const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - for (int i = 0; i < glyphinfolist.size(); ++i) + Page* TextureFont::typeset(const Text& text, int lineheight, int spacing) { - const GlyphArrayDrawInfo& info = glyphinfolist[i]; - shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); - shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); - gl.bindTexture(info.texture); - gl.drawArrays(GL_QUADS, 0, info.count); - gl.bindTexture(0); + return typeset(*text, lineheight, spacing); } - } - - void TextureFont::print(const Content& text, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(text, lineheight, spacing); - print(page, x, y); - delete page; - } - - void TextureFont::print(const Text& text, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(text, lineheight, spacing); - print(page, x, y); - delete page; - } - TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) - : Drawable(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) + void TextureFont::print(const Page* page, int x, int y) { - glyph.y = y * cellh; - for (int x = 0; x < count.colum; ++x) + Shader* shader = Shader::getCurrentShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + for (int i = 0; i < glyphinfolist.size(); ++i) { - glyph.x = x * cellw; - if (x + y * count.colum >= codepoints.size()) - return; - glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum], glyph)); + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); + shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + gl.bindTexture(0); } } - } - TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) - : Drawable(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) + void TextureFont::print(const Content& text, int x, int y, int lineheight, int spacing) { - glyph.y = y; - bool newc = false; - for (int x = 0; x <= w; ++x) + Page* page = typeset(text, lineheight, spacing); + print(page, x, y); + delete page; + } + + void TextureFont::print(const Text& text, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(text, lineheight, spacing); + print(page, x, y); + delete page; + } + + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) + : Drawable(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) { - if (x == w && newc) + glyph.y = y * cellh; + for (int x = 0; x < count.colum; ++x) { - glyph.w = x - glyph.x; - if (i >= codepoints.size()) + glyph.x = x * cellw; + if (x + y * count.colum >= 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; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum], glyph)); } - else if (newc && c == mask) + } + } + + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) + : Drawable(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) { - glyph.w = x - glyph.x; - if (i >= codepoints.size()) - return; - glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); - if (codepoints[i] == 't') + if (x == w && newc) { - int a = 10; + 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; } - ++i; - newc = false; } } } - } -} + } }
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/TextureFont.h b/src/libjin/Graphics/Font/TextureFont.h index 0d0d091..a1d1a37 100644 --- a/src/libjin/Graphics/Font/TextureFont.h +++ b/src/libjin/Graphics/Font/TextureFont.h @@ -14,49 +14,49 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - /* Texture font */ - class TextureFont : public Font - , public Drawable - { - public: - static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); - static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh); - static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); - static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh); + /* Texture font */ + class TextureFont : public Font + , public Drawable + { + public: + static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); + static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh); + static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); + static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh); - ~TextureFont(); + ~TextureFont(); - Page* typeset(const Text& text, int lineheight, int spacing = 0) override; - Page* typeset(const Content& text, int lineheight, int spacing = 0) override ; + Page* typeset(const Text& text, int lineheight, int spacing = 0) override; + Page* typeset(const Content& text, int lineheight, int spacing = 0) override ; - void print(const Page* page, int x, int y) override; - void print(const Content& text, int x, int y, int linehgiht, int spacing = 0) override; - void print(const Text& text, int x, int y, int lineheight, int spacing = 0)override; + void print(const Page* page, int x, int y) override; + void print(const Content& text, int x, int y, int linehgiht, int spacing = 0) override; + void print(const Text& text, int x, int y, int lineheight, int spacing = 0)override; - private: - struct TextureGlyph - { - float x, y, w, h; - }; + private: + struct TextureGlyph + { + float x, y, w, h; + }; - 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 Content& codepoints, int cellw, int cellh); + TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); - 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; + 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; + std::map<Codepoint, TextureGlyph> glyphs; - }; + }; -} + } } #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Mesh.cpp b/src/libjin/Graphics/Mesh.cpp index 503a189..3142894 100644 --- a/src/libjin/Graphics/Mesh.cpp +++ b/src/libjin/Graphics/Mesh.cpp @@ -2,10 +2,10 @@ namespace jin { -namespace graphics -{ + namespace graphics + { -} + } }
\ No newline at end of file diff --git a/src/libjin/Graphics/Mesh.h b/src/libjin/Graphics/Mesh.h index c14af89..66727e4 100644 --- a/src/libjin/Graphics/Mesh.h +++ b/src/libjin/Graphics/Mesh.h @@ -3,19 +3,19 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - class Mesh - { - public: + class Mesh + { + public: - private: + private: - }; + }; -} + } } #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/OpenGL.cpp b/src/libjin/Graphics/OpenGL.cpp index f7bed9f..6bc176e 100644 --- a/src/libjin/Graphics/OpenGL.cpp +++ b/src/libjin/Graphics/OpenGL.cpp @@ -3,10 +3,10 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - OpenGL gl; + OpenGL gl; -} + } } diff --git a/src/libjin/Graphics/OpenGL.h b/src/libjin/Graphics/OpenGL.h index 51395ba..47011a2 100644 --- a/src/libjin/Graphics/OpenGL.h +++ b/src/libjin/Graphics/OpenGL.h @@ -6,24 +6,24 @@ namespace jin { -namespace graphics -{ - - class OpenGL : public ogl2d::OpenGL + namespace graphics { - public: - math::Matrix ProjectionMatrix; - math::Matrix ModelMatrix; - OpenGL() : ogl2d::OpenGL() + class OpenGL : public ogl2d::OpenGL { - } + public: + math::Matrix ProjectionMatrix; + math::Matrix ModelMatrix; - }; + OpenGL() : ogl2d::OpenGL() + { + } - extern OpenGL gl; + }; -} + extern OpenGL gl; + + } } #endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader.cpp b/src/libjin/Graphics/Shader.cpp index 688fa51..8788900 100644 --- a/src/libjin/Graphics/Shader.cpp +++ b/src/libjin/Graphics/Shader.cpp @@ -9,274 +9,274 @@ #include "../Filesystem/Buffer.h" namespace jin { -namespace graphics -{ + namespace graphics + { - using namespace jin::filesystem; - using namespace std; + using namespace jin::filesystem; + using namespace std; - /** - * default_texture - * base_shader - * SHADER_FORMAT_SIZE - * formatShader - */ - #include "Shaders/default.shader.h" + /** + * default_texture + * base_shader + * SHADER_FORMAT_SIZE + * formatShader + */ + #include "Shaders/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 DEFAULT_TEXTURE_UNIT = 0; + /** + * 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 DEFAULT_TEXTURE_UNIT = 0; - /*static*/ Shader* Shader::currentShader = nullptr; + /*static*/ Shader* Shader::currentShader = nullptr; - Shader* Shader::createShader(const string& program) - { - Shader* shader = nullptr; - try - { - shader = new Shader(program); - } - catch(...) - { - return nullptr; - } - return shader; - } + Shader* Shader::createShader(const string& program) + { + Shader* shader = nullptr; + try + { + shader = new Shader(program); + } + catch(...) + { + return nullptr; + } + return shader; + } - Shader::Shader(const string& program) - : currentTextureUnit(DEFAULT_TEXTURE_UNIT) - { - if (!compile(program)) - throw 0; - } + Shader::Shader(const string& program) + : currentTextureUnit(DEFAULT_TEXTURE_UNIT) + { + if (!compile(program)) + throw 0; + } - Shader::~Shader() - { - if (currentShader == this) - unuse(); - } + Shader::~Shader() + { + if (currentShader == this) + unuse(); + } - bool Shader::compile(const string& program) - { - /* parse shader source, need some optimizations */ - int loc_VERTEX_SHADER = program.find("#VERTEX_SHADER"); - int loc_END_VERTEX_SHADER = program.find("#END_VERTEX_SHADER"); - int loc_FRAGMENT_SHADER = program.find("#FRAGMENT_SHADER"); - int loc_END_FRAGMENT_SHADER = program.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 */ - int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); - string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start); - Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE); - formatVertexShader((char*)vbuffer.data, vertex_shader.c_str()); - start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); - string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start); - Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE); - formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str()); - /* compile */ - GLint success; - GLuint vshader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); - glCompileShader(vshader); - glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) - return false; - GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL); - glCompileShader(fshader); - glGetShaderiv(fshader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) - return false; - pid = glCreateProgram(); - glAttachShader(pid, vshader); - glAttachShader(pid, fshader); - glLinkProgram(pid); - glGetProgramiv(pid, GL_LINK_STATUS, &success); - if (success == GL_FALSE) - throw false; - } + bool Shader::compile(const string& program) + { + /* parse shader source, need some optimizations */ + int loc_VERTEX_SHADER = program.find("#VERTEX_SHADER"); + int loc_END_VERTEX_SHADER = program.find("#END_VERTEX_SHADER"); + int loc_FRAGMENT_SHADER = program.find("#FRAGMENT_SHADER"); + int loc_END_FRAGMENT_SHADER = program.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 */ + int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start); + Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE); + formatVertexShader((char*)vbuffer.data, vertex_shader.c_str()); + start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start); + Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE); + formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str()); + /* compile */ + GLint success; + GLuint vshader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); + glCompileShader(vshader); + glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + return false; + GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL); + glCompileShader(fshader); + glGetShaderiv(fshader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + return false; + pid = glCreateProgram(); + glAttachShader(pid, vshader); + glAttachShader(pid, fshader); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &success); + if (success == GL_FALSE) + throw false; + } - static inline GLint getMaxTextureUnits() - { - GLint maxTextureUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - return maxTextureUnits; - } + static inline GLint getMaxTextureUnits() + { + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + return maxTextureUnits; + } - void Shader::use() - { - glUseProgram(pid); - currentShader = this; - sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); - } + void Shader::use() + { + glUseProgram(pid); + currentShader = this; + sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); + } - /*static*/ void Shader::unuse() - { - glUseProgram(0); - currentShader = nullptr; - } + /*static*/ void Shader::unuse() + { + glUseProgram(0); + currentShader = nullptr; + } - GLint Shader::claimTextureUnit(const std::string& name) - { - std::map<std::string, GLint>::iterator unit = textureUnits.find(name); - if (unit != textureUnits.end()) - return unit->second; - static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); - if (++currentTextureUnit >= MAX_TEXTURE_UNITS) - return 0; - textureUnits[name] = currentTextureUnit; - return currentTextureUnit; - } + GLint Shader::claimTextureUnit(const std::string& name) + { + std::map<std::string, GLint>::iterator unit = textureUnits.find(name); + if (unit != textureUnits.end()) + return unit->second; + static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); + if (++currentTextureUnit >= MAX_TEXTURE_UNITS) + return 0; + textureUnits[name] = currentTextureUnit; + return currentTextureUnit; + } -#define checkJSL() \ - if (currentShader != this) \ - return + #define checkJSL() \ + if (currentShader != this) \ + return - void Shader::sendInt(const char* name, int value) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform1i(loc, value); - } + void Shader::sendInt(const char* name, int value) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform1i(loc, value); + } - void Shader::sendFloat(const char* variable, float number) - { - checkJSL(); - int loc = glGetUniformLocation(pid, variable); - glUniform1f(loc, number); - } + void Shader::sendFloat(const char* variable, float number) + { + checkJSL(); + int loc = glGetUniformLocation(pid, variable); + glUniform1f(loc, number); + } - /** - * https://www.douban.com/note/627332677/ - * struct TextureUnit - * { - * GLuint targetTexture1D; - * GLuint targetTexture2D; - * GLuint targetTexture3D; - * GLuint targetTextureCube; - * ... - * }; - * - * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] - * GLuint currentTextureUnit = 0; - */ - void Shader::sendTexture(const char* variable, const Texture* tex) - { - checkJSL(); - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint unit = claimTextureUnit(variable); - if (unit == 0) - { - // TODO: 쳣 - return; - } - gl.activeTexUnit(unit); - glUniform1i(location, unit); - gl.bindTexture(tex->getTexture()); - gl.activeTexUnit(0); - } + /** + * https://www.douban.com/note/627332677/ + * struct TextureUnit + * { + * GLuint targetTexture1D; + * GLuint targetTexture2D; + * GLuint targetTexture3D; + * GLuint targetTextureCube; + * ... + * }; + * + * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] + * GLuint currentTextureUnit = 0; + */ + void Shader::sendTexture(const char* variable, const Texture* tex) + { + checkJSL(); + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + gl.activeTexUnit(unit); + glUniform1i(location, unit); + gl.bindTexture(tex->getTexture()); + gl.activeTexUnit(0); + } - void Shader::sendCanvas(const char* variable, const Canvas* canvas) - { - checkJSL(); - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint unit = claimTextureUnit(variable); - if (unit == 0) - { - // TODO: 쳣 - return; - } - glUniform1i(location, unit); - glActiveTexture(GL_TEXTURE0 + unit); - gl.bindTexture(canvas->getTexture()); + void Shader::sendCanvas(const char* variable, const Canvas* canvas) + { + checkJSL(); + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + glUniform1i(location, unit); + glActiveTexture(GL_TEXTURE0 + unit); + gl.bindTexture(canvas->getTexture()); - glActiveTexture(GL_TEXTURE0); - } + glActiveTexture(GL_TEXTURE0); + } - void Shader::sendVec2(const char* name, float x, float y) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform2f(loc, x, y); - } + void Shader::sendVec2(const char* name, float x, float y) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform2f(loc, x, y); + } - void Shader::sendVec3(const char* name, float x, float y, float z) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform3f(loc, x, y, z); - } + void Shader::sendVec3(const char* name, float x, float y, float z) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform3f(loc, x, y, z); + } - void Shader::sendVec4(const char* name, float x, float y, float z, float w) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform4f(loc, x, y, z, w); - } + void Shader::sendVec4(const char* name, float x, float y, float z, float w) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform4f(loc, x, y, z, w); + } - void Shader::sendColor(const char* name, const Color* col) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform4f(loc, - col->r / 255.f, - col->g / 255.f, - col->b / 255.f, - col->a / 255.f - ); - } + void Shader::sendColor(const char* name, const Color* col) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform4f(loc, + col->r / 255.f, + col->g / 255.f, + col->b / 255.f, + col->a / 255.f + ); + } - void Shader::sendMatrix4(const char* name, const math::Matrix* mat4) - { - int loc = glGetUniformLocation(pid, name); - glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); - } + void Shader::sendMatrix4(const char* name, const math::Matrix* mat4) + { + int loc = glGetUniformLocation(pid, name); + glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); + } - void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) - { - GLint loc = glGetAttribLocation(pid, SHADER_VERTEX_COORDS); - glEnableVertexAttribArray(0); - glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); - } + void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, SHADER_VERTEX_COORDS); + glEnableVertexAttribArray(0); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } - void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) - { - GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS); - glEnableVertexAttribArray(1); - glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); - } + void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS); + glEnableVertexAttribArray(1); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } -} // graphics + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader.h b/src/libjin/Graphics/Shader.h index dcd0b62..6339883 100644 --- a/src/libjin/Graphics/Shader.h +++ b/src/libjin/Graphics/Shader.h @@ -13,46 +13,46 @@ namespace jin { -namespace graphics -{ - - class Shader - { - public: - static Shader* createShader(const std::string& program); - static inline Shader* getCurrentShader() { return currentShader; } - static void unuse(); - - virtual ~Shader(); - - void use(); - void sendFloat(const char* name, float number); - void sendTexture(const char* name, const Texture* image); - void sendInt(const char* name, int value); - void sendVec2(const char* name, float x, float y); - void sendVec3(const char* name, float x, float y, float z); - void sendVec4(const char* name, float x, float y, float z, float w); - void sendCanvas(const char* name, const Canvas* canvas); - void sendColor(const char* name, const Color* col); - void sendMatrix4(const char* name, const math::Matrix* mat4); - - void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); - void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); - - protected: - static Shader* currentShader; - - GLint claimTextureUnit(const std::string& name); - Shader(const std::string& program); - bool compile(const std::string& program); - - GLuint pid; - GLint currentTextureUnit; - std::map<std::string, GLint> textureUnits; - - }; - -} // graphics + namespace graphics + { + + class Shader + { + public: + static Shader* createShader(const std::string& program); + static inline Shader* getCurrentShader() { return currentShader; } + static void unuse(); + + virtual ~Shader(); + + void use(); + void sendFloat(const char* name, float number); + void sendTexture(const char* name, const Texture* image); + void sendInt(const char* name, int value); + void sendVec2(const char* name, float x, float y); + void sendVec3(const char* name, float x, float y, float z); + void sendVec4(const char* name, float x, float y, float z, float w); + void sendCanvas(const char* name, const Canvas* canvas); + void sendColor(const char* name, const Color* col); + void sendMatrix4(const char* name, const math::Matrix* mat4); + + void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + + protected: + static Shader* currentShader; + + GLint claimTextureUnit(const std::string& name); + Shader(const std::string& program); + bool compile(const std::string& program); + + GLuint pid; + GLint currentTextureUnit; + std::map<std::string, GLint> textureUnits; + + }; + + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Shapes.cpp b/src/libjin/Graphics/Shapes.cpp index f5aedd4..5e87473 100644 --- a/src/libjin/Graphics/Shapes.cpp +++ b/src/libjin/Graphics/Shapes.cpp @@ -9,118 +9,118 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - using namespace math; + using namespace math; - void point(int x, int y) - { - float verts[] = { x + 0.5f , y + 0.5f }; + void point(int x, int y) + { + float verts[] = { x + 0.5f , y + 0.5f }; - Shader* shader = Shader::getCurrentShader(); - shader->bindVertexPointer(2, GL_FLOAT, 0, verts); - gl.ModelMatrix.setIdentity(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_FLOAT, 0, verts); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - glDrawArrays(GL_POINTS, 0, 1); - } + glDrawArrays(GL_POINTS, 0, 1); + } - void points(int n, GLshort* p) - { - Shader* shader = Shader::getCurrentShader(); - shader->bindVertexPointer(2, GL_SHORT, 0, p); - gl.ModelMatrix.setIdentity(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + void points(int n, GLshort* p) + { + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_SHORT, 0, p); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - glDrawArrays(GL_POINTS, 0, n); - } - - void line(int x1, int y1, int x2, int y2) - { - float verts[] = { - x1, y1, - x2, y2 - }; + glDrawArrays(GL_POINTS, 0, n); + } + + void line(int x1, int y1, int x2, int y2) + { + float verts[] = { + x1, y1, + x2, y2 + }; - Shader* shader = Shader::getCurrentShader(); - shader->bindVertexPointer(2, GL_FLOAT, 0, verts); - gl.ModelMatrix.setIdentity(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_FLOAT, 0, verts); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - glDrawArrays(GL_LINES, 0, 2); - } - - 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, y, x + w, y, x + w, y + h, x, y + h }; - polygon(mode, coords, 4); - } - - void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3) - { - float coords[] = { x1, y1, x2, y2, x3, y3 }; - polygon(mode, coords, 3); - } - - void polygon_line(float* p, int count) - { - Shader* shader = Shader::getCurrentShader(); - gl.ModelMatrix.setIdentity(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - shader->bindVertexPointer(2, GL_FLOAT, 0, p); - - glDrawArrays(GL_LINE_LOOP, 0, count); - } - - void polygon(RenderMode mode, float* p, int count) - { - if (mode == LINE) - { - polygon_line(p, count); - } - else if (mode == FILL) - { + glDrawArrays(GL_LINES, 0, 2); + } + + 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, y, x + w, y, x + w, y + h, x, y + h }; + polygon(mode, coords, 4); + } + + void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3) + { + float coords[] = { x1, y1, x2, y2, x3, y3 }; + polygon(mode, coords, 3); + } + + void polygon_line(float* p, int count) + { Shader* shader = Shader::getCurrentShader(); - gl.ModelMatrix.setIdentity(); + gl.ModelMatrix.setIdentity(); shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); shader->bindVertexPointer(2, GL_FLOAT, 0, p); - glDrawArrays(GL_POLYGON, 0, count); - } - } - -} // graphics + glDrawArrays(GL_LINE_LOOP, 0, count); + } + + void polygon(RenderMode mode, float* p, int count) + { + if (mode == LINE) + { + polygon_line(p, count); + } + else if (mode == FILL) + { + Shader* shader = Shader::getCurrentShader(); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, p); + + glDrawArrays(GL_POLYGON, 0, count); + } + } + + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Shapes.h b/src/libjin/Graphics/Shapes.h index b248cca..93cde6d 100644 --- a/src/libjin/Graphics/Shapes.h +++ b/src/libjin/Graphics/Shapes.h @@ -9,28 +9,28 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - typedef enum { - NONE = 0, - FILL , - LINE - }RenderMode; + typedef enum { + NONE = 0, + FILL , + LINE + }RenderMode; - /** - * TODO: - * drawPixels(int n, points) - */ - 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); + /** + * TODO: + * drawPixels(int n, points) + */ + 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); -} // graphics + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Texture.cpp b/src/libjin/Graphics/Texture.cpp index a42e796..915fe54 100644 --- a/src/libjin/Graphics/Texture.cpp +++ b/src/libjin/Graphics/Texture.cpp @@ -8,27 +8,27 @@ namespace jin { -namespace graphics -{ + namespace graphics + { - using namespace jin::math; + using namespace jin::math; - /*static*/ Texture* Texture::createTexture(Bitmap* bitmap) - { - Texture* tex = new Texture(bitmap); - return tex; - } + /*static*/ Texture* Texture::createTexture(Bitmap* bitmap) + { + Texture* tex = new Texture(bitmap); + return tex; + } - Texture::Texture(const Bitmap* bitmap) - : Drawable(bitmap) - { - } + Texture::Texture(const Bitmap* bitmap) + : Drawable(bitmap) + { + } - Texture::~Texture() - { - } + Texture::~Texture() + { + } -} // graphics + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Texture.h b/src/libjin/Graphics/Texture.h index 1704ee7..eb16519 100644 --- a/src/libjin/Graphics/Texture.h +++ b/src/libjin/Graphics/Texture.h @@ -9,22 +9,22 @@ #include "Bitmap.h" namespace jin { -namespace graphics -{ + namespace graphics + { - class Texture: public Drawable - { - public: - static Texture* createTexture(Bitmap* bitmap); + class Texture: public Drawable + { + public: + static Texture* createTexture(Bitmap* bitmap); - ~Texture(); + ~Texture(); - private: - Texture(const Bitmap* bitmap); + private: + Texture(const Bitmap* bitmap); - }; + }; -} // graphics + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER diff --git a/src/libjin/Graphics/Window.cpp b/src/libjin/Graphics/Window.cpp index 6ebc9f9..140ef36 100644 --- a/src/libjin/Graphics/Window.cpp +++ b/src/libjin/Graphics/Window.cpp @@ -12,98 +12,98 @@ namespace jin { -namespace graphics -{ - - bool Window::initSystem(const SettingBase* s) - { -#if LIBJIN_DEBUG - Loghelper::log(Loglevel::LV_INFO, "Init window system"); -#endif - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - return false; - - const Setting* setting = (Setting*)s; - size.w = setting->width; - size.h = setting->height; - fps = setting->fps; - bool vsync = setting->vsync; - const char* title = setting->title; - - if (wnd) - { - SDL_DestroyWindow(wnd); - 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); - - int wx = SDL_WINDOWPOS_UNDEFINED, - wy = SDL_WINDOWPOS_UNDEFINED; + namespace graphics + { + + bool Window::initSystem(const SettingBase* s) + { + #if LIBJIN_DEBUG + Loghelper::log(Loglevel::LV_INFO, "Init window system"); + #endif + + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return false; + + const Setting* setting = (Setting*)s; + size.w = setting->width; + size.h = setting->height; + fps = setting->fps; + bool vsync = setting->vsync; + const char* title = setting->title; + + if (wnd) + { + SDL_DestroyWindow(wnd); + 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); + + int wx = SDL_WINDOWPOS_UNDEFINED, + wy = SDL_WINDOWPOS_UNDEFINED; - int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; - if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; - if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; - - wnd = SDL_CreateWindow(title, wx, wy, size.w, size.h, flag); - if (wnd == NULL) - return false; - ctx = SDL_GL_CreateContext(wnd); - if (ctx == NULL) - return false; - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - SDL_GL_MakeCurrent(wnd, ctx); - /* default configuration */ - gl.setClearColor(0, 0, 0, 0xff); - gl.pushColor(0xff, 0xff, 0xff, 0xff); - gl.enable(GL_BLEND); - gl.enable(GL_TEXTURE_2D); - gl.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - /* avoid white screen blink on windows */ - swapBuffers(); - /* bind to default canvas */ - Canvas::unbind(); - Shader::unuse(); - return true; - } - - void Window::quitSystem() - { - /* disable opengl */ - gl.disable(GL_BLEND); - gl.disable(GL_TEXTURE_2D); - /* close window */ - SDL_DestroyWindow(wnd); - SDL_Quit(); - } - - void Window::swapBuffers() - { - if (wnd) - SDL_GL_SwapWindow(wnd); - } - - void Window::setTitle(const char* title) - { - SDL_SetWindowTitle(wnd, title); - }; - -} // graphics + int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; + if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; + if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; + + wnd = SDL_CreateWindow(title, wx, wy, size.w, size.h, flag); + if (wnd == NULL) + return false; + ctx = SDL_GL_CreateContext(wnd); + if (ctx == NULL) + return false; + SDL_GL_SetSwapInterval(vsync ? 1 : 0); + SDL_GL_MakeCurrent(wnd, ctx); + /* default configuration */ + gl.setClearColor(0, 0, 0, 0xff); + gl.pushColor(0xff, 0xff, 0xff, 0xff); + gl.enable(GL_BLEND); + gl.enable(GL_TEXTURE_2D); + gl.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* avoid white screen blink on windows */ + swapBuffers(); + /* bind to default canvas */ + Canvas::unbind(); + Shader::unuse(); + return true; + } + + void Window::quitSystem() + { + /* disable opengl */ + gl.disable(GL_BLEND); + gl.disable(GL_TEXTURE_2D); + /* close window */ + SDL_DestroyWindow(wnd); + SDL_Quit(); + } + + void Window::swapBuffers() + { + if (wnd) + SDL_GL_SwapWindow(wnd); + } + + void Window::setTitle(const char* title) + { + SDL_SetWindowTitle(wnd, title); + }; + + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Window.h b/src/libjin/Graphics/Window.h index 301b0b5..3734ee3 100644 --- a/src/libjin/Graphics/Window.h +++ b/src/libjin/Graphics/Window.h @@ -10,45 +10,45 @@ namespace jin { -namespace graphics -{ - - class Window : public Subsystem<Window> - { - public: - struct Setting : SettingBase - { - public: - const char* title; // - bool fullscreen; // ȫ - int width, height; // ڴС - bool vsync; // ֱͬ - int fps; // FPS - bool resizable; // resize - }; - - void setTitle(const char* title); - inline int getW(){ return size.w; } - inline int getH(){ return size.h; } - inline int getFPS(){ return fps; } - void swapBuffers(); - - private: - SINGLETON(Window); - - Window() {}; - - virtual ~Window() {}; - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - SDL_Window* wnd; - jin::math::Vector2<unsigned int> size; - int fps; - - }; - -} // render + namespace graphics + { + + class Window : public Subsystem<Window> + { + public: + struct Setting : SettingBase + { + public: + const char* title; // + bool fullscreen; // ȫ + int width, height; // ڴС + bool vsync; // ֱͬ + int fps; // FPS + bool resizable; // resize + }; + + void setTitle(const char* title); + inline int getW(){ return size.w; } + inline int getH(){ return size.h; } + inline int getFPS(){ return fps; } + void swapBuffers(); + + private: + SINGLETON(Window); + + Window() {}; + + virtual ~Window() {}; + bool initSystem(const SettingBase* setting) override; + void quitSystem() override; + + SDL_Window* wnd; + jin::math::Vector2<unsigned int> size; + int fps; + + }; + + } // render } // jin #endif // LIBJIN_MODULES_RENDER |