diff options
author | chai <chaifix@163.com> | 2018-10-10 13:10:23 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-10-10 13:10:23 +0800 |
commit | 498664ceba42e3b609e4464c246de164c61775c7 (patch) | |
tree | c1741b8ba567d5d0aafef7831298bdddb348b7d7 | |
parent | 95c088f3e48321c155eabc00fc4710692405855d (diff) |
*update
30 files changed, 971 insertions, 759 deletions
diff --git a/build/Debug/05Font.exe b/build/Debug/05Font.exe Binary files differindex cf80b7f..7b9484a 100644 --- a/build/Debug/05Font.exe +++ b/build/Debug/05Font.exe diff --git a/build/libjin.sln b/build/libjin.sln index 05a6517..59694f9 100644 --- a/build/libjin.sln +++ b/build/libjin.sln @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D4 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05Font", "05Font\05Font.vcxproj", "{D1953718-E728-4A86-9CCF-8BEC1F5C5F97}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06TextureFont", "06TextureFont\06TextureFont.vcxproj", "{A81B426C-A6C7-4861-92A9-A087872D2C53}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -73,6 +75,14 @@ Global {D1953718-E728-4A86-9CCF-8BEC1F5C5F97}.Release|x64.Build.0 = Release|x64 {D1953718-E728-4A86-9CCF-8BEC1F5C5F97}.Release|x86.ActiveCfg = Release|Win32 {D1953718-E728-4A86-9CCF-8BEC1F5C5F97}.Release|x86.Build.0 = Release|Win32 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Debug|x64.ActiveCfg = Debug|x64 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Debug|x64.Build.0 = Debug|x64 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Debug|x86.ActiveCfg = Debug|Win32 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Debug|x86.Build.0 = Debug|Win32 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Release|x64.ActiveCfg = Release|x64 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Release|x64.Build.0 = Release|x64 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Release|x86.ActiveCfg = Release|Win32 + {A81B426C-A6C7-4861-92A9-A087872D2C53}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,6 +93,7 @@ Global {0E49D105-2032-4825-9FA1-54B1B94E3655} = {D401F737-EEF5-4EA3-8CEA-A15523AE68AD} {85071432-24B6-46D4-98D8-DAA63183093C} = {D401F737-EEF5-4EA3-8CEA-A15523AE68AD} {D1953718-E728-4A86-9CCF-8BEC1F5C5F97} = {D401F737-EEF5-4EA3-8CEA-A15523AE68AD} + {A81B426C-A6C7-4861-92A9-A087872D2C53} = {D401F737-EEF5-4EA3-8CEA-A15523AE68AD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {310E7948-2690-4896-9579-19E6AC4D405B} diff --git a/build/libjin/libjin.vcxproj b/build/libjin/libjin.vcxproj index ebd95dc..f186a79 100644 --- a/build/libjin/libjin.vcxproj +++ b/build/libjin/libjin.vcxproj @@ -36,8 +36,8 @@ <ClCompile Include="..\..\libjin\Graphics\Canvas.cpp" /> <ClCompile Include="..\..\libjin\Graphics\Color.cpp" /> <ClCompile Include="..\..\libjin\Graphics\Drawable.cpp" /> - <ClCompile Include="..\..\libjin\Graphics\Font.cpp" /> - <ClCompile Include="..\..\libjin\Graphics\FontData.cpp" /> + <ClCompile Include="..\..\libjin\Graphics\TexFont.cpp" /> + <ClCompile Include="..\..\libjin\Graphics\TTF.cpp" /> <ClCompile Include="..\..\libjin\Graphics\Mesh.cpp" /> <ClCompile Include="..\..\libjin\Graphics\OpenGL.cpp" /> <ClCompile Include="..\..\libjin\Graphics\Shader.cpp" /> @@ -87,11 +87,12 @@ <ClInclude Include="..\..\libjin\Graphics\Canvas.h" /> <ClInclude Include="..\..\libjin\Graphics\Color.h" /> <ClInclude Include="..\..\libjin\Graphics\Drawable.h" /> + <ClInclude Include="..\..\libjin\Graphics\TTF.h" /> <ClInclude Include="..\..\libjin\Graphics\Font.h" /> - <ClInclude Include="..\..\libjin\Graphics\FontData.h" /> <ClInclude Include="..\..\libjin\Graphics\Graphics.h" /> <ClInclude Include="..\..\libjin\Graphics\Mesh.h" /> <ClInclude Include="..\..\libjin\Graphics\OpenGL.h" /> + <ClInclude Include="..\..\libjin\Graphics\Page.h" /> <ClInclude Include="..\..\libjin\Graphics\Shader.h" /> <ClInclude Include="..\..\libjin\Graphics\Shaders\base.shader.h" /> <ClInclude Include="..\..\libjin\Graphics\Shaders\default.shader.h" /> @@ -99,6 +100,7 @@ <ClInclude Include="..\..\libjin\Graphics\Shaders\texture.shader.h" /> <ClInclude Include="..\..\libjin\Graphics\Shapes.h" /> <ClInclude Include="..\..\libjin\Graphics\Texture.h" /> + <ClInclude Include="..\..\libjin\Graphics\TexFont.h" /> <ClInclude Include="..\..\libjin\Graphics\Utf8.h" /> <ClInclude Include="..\..\libjin\Graphics\Window.h" /> <ClInclude Include="..\..\libjin\Input\Event.h" /> diff --git a/build/libjin/libjin.vcxproj.filters b/build/libjin/libjin.vcxproj.filters index f79e814..cd91c37 100644 --- a/build/libjin/libjin.vcxproj.filters +++ b/build/libjin/libjin.vcxproj.filters @@ -99,9 +99,6 @@ <ClCompile Include="..\..\libjin\Graphics\Drawable.cpp"> <Filter>Graphics</Filter> </ClCompile> - <ClCompile Include="..\..\libjin\Graphics\Font.cpp"> - <Filter>Graphics</Filter> - </ClCompile> <ClCompile Include="..\..\libjin\Graphics\Texture.cpp"> <Filter>Graphics</Filter> </ClCompile> @@ -162,9 +159,6 @@ <ClCompile Include="..\..\libjin\Game\Game.cpp"> <Filter>Game</Filter> </ClCompile> - <ClCompile Include="..\..\libjin\Graphics\FontData.cpp"> - <Filter>Graphics</Filter> - </ClCompile> <ClCompile Include="..\..\libjin\Graphics\Mesh.cpp"> <Filter>Graphics</Filter> </ClCompile> @@ -174,6 +168,12 @@ <ClCompile Include="..\..\libjin\Graphics\Utf8.cpp"> <Filter>Graphics</Filter> </ClCompile> + <ClCompile Include="..\..\libjin\Graphics\TTF.cpp"> + <Filter>Graphics</Filter> + </ClCompile> + <ClCompile Include="..\..\libjin\Graphics\TexFont.cpp"> + <Filter>Graphics</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libjin\3rdparty\GLee\GLee.h"> @@ -230,9 +230,6 @@ <ClInclude Include="..\..\libjin\Graphics\Drawable.h"> <Filter>Graphics</Filter> </ClInclude> - <ClInclude Include="..\..\libjin\Graphics\Font.h"> - <Filter>Graphics</Filter> - </ClInclude> <ClInclude Include="..\..\libjin\Graphics\Graphics.h"> <Filter>Graphics</Filter> </ClInclude> @@ -340,9 +337,6 @@ <ClInclude Include="..\..\libjin\Math\Vector4.hpp"> <Filter>Math</Filter> </ClInclude> - <ClInclude Include="..\..\libjin\Graphics\FontData.h"> - <Filter>Graphics</Filter> - </ClInclude> <ClInclude Include="..\..\libjin\Graphics\OpenGL.h"> <Filter>Graphics</Filter> </ClInclude> @@ -367,6 +361,18 @@ <ClInclude Include="..\..\libjin\Graphics\Shaders\texture.shader.h"> <Filter>Graphics\Shaders</Filter> </ClInclude> + <ClInclude Include="..\..\libjin\Graphics\Page.h"> + <Filter>Graphics</Filter> + </ClInclude> + <ClInclude Include="..\..\libjin\Graphics\TTF.h"> + <Filter>Graphics</Filter> + </ClInclude> + <ClInclude Include="..\..\libjin\Graphics\Font.h"> + <Filter>Graphics</Filter> + </ClInclude> + <ClInclude Include="..\..\libjin\Graphics\TexFont.h"> + <Filter>Graphics</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="..\..\libjin\README.md" /> diff --git a/libjin/3rdparty/ogl/OpenGL.h b/libjin/3rdparty/ogl/OpenGL.h index 33b14d2..3984b49 100644 --- a/libjin/3rdparty/ogl/OpenGL.h +++ b/libjin/3rdparty/ogl/OpenGL.h @@ -45,15 +45,6 @@ namespace ogl2d void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void activeTexUnit(unsigned int unit = 0); - inline void vertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) - { - glVertexPointer(size, type, stride, pointer); - } - - inline void texCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) - { - glTexCoordPointer(size, type, stride, pointer); - } inline void drawArrays(GLenum mode, GLint first, GLsizei count) { diff --git a/libjin/Audio/SDL/SDLSource.cpp b/libjin/Audio/SDL/SDLSource.cpp index 251ef27..9f4f2fb 100644 --- a/libjin/Audio/SDL/SDLSource.cpp +++ b/libjin/Audio/SDL/SDLSource.cpp @@ -290,21 +290,21 @@ Manager::get()->pushCommand(cmd); \ for (int i = 0; i < samples; ++i) { char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels; - short left = 0; - short right = 0; + short l = 0; + short r = 0; if (raw.bitdepth == 16) { - left = ((short*)source)[L] * status.volume; - right = ((short*)source)[L + raw.channels - 1] * status.volume; + l = ((short*)source)[L] * status.volume; + r = ((short*)source)[L + raw.channels - 1] * status.volume; } else if (raw.bitdepth == 8) { - left = source[L] << 8; // << 8 Ŵ16bits - right = source[L + raw.channels - 1] << 8; + l = source[L] << 8; // << 8 Ŵ16bits + r = source[L + raw.channels - 1] << 8; } short* sample = buffer + (i << 1); - sample[L] = clamp(sample[L] + left, SHRT_MIN, SHRT_MAX); // - sample[R] = clamp(sample[R] + right, SHRT_MIN, SHRT_MAX); // + sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); // + sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); // ++status.pos; if (status.pos > raw.samples && status.loop) status.pos = 0; // rewind diff --git a/libjin/Game/Game.cpp b/libjin/Game/Game.cpp index 3f905f2..6dc75ce 100644 --- a/libjin/Game/Game.cpp +++ b/libjin/Game/Game.cpp @@ -26,30 +26,26 @@ namespace core const int MS_PER_UPDATE = 1000.0f / FPS; _running = true; Event e; - int previous = getMilliSecond(); - int dt = MS_PER_UPDATE; + int current = getMilliSecond(); + int previous = current; + int dt = 0; while (_running) { while (jin::input::pollEvent(&e)) { - if (_onEvent != nullptr) - _onEvent(&e); - if (!_running) goto quitloop; + if (_onEvent != nullptr) + _onEvent(&e); + if (!_running) + goto quitloop; } - if (_onUpdate != nullptr) _onUpdate(dt); - if (_onDraw != nullptr) _onDraw(); - wnd->swapBuffers(); - const int current = getMilliSecond(); + previous = current; + current = getMilliSecond(); dt = current - previous; - const int wait = MS_PER_UPDATE - (current - previous); - previous += MS_PER_UPDATE; - if (wait > 0) - { - sleep(wait); - dt = MS_PER_UPDATE; - } - else - previous = current; + if (_onUpdate != nullptr) + _onUpdate(dt); + if (_onDraw != nullptr) + _onDraw(); + wnd->swapBuffers(); } quitloop:; } diff --git a/libjin/Graphics/Bitmap.h b/libjin/Graphics/Bitmap.h index af7f376..5510569 100644 --- a/libjin/Graphics/Bitmap.h +++ b/libjin/Graphics/Bitmap.h @@ -16,7 +16,6 @@ namespace graphics public: static Bitmap* createBitmap(const void* imgData, size_t size); static Bitmap* createBitmap(int w, int h, Color color = Color::BLACK); - static void destroyBitmap(Bitmap* bitmap); static Bitmap* clone(const Bitmap* bitmap); ~Bitmap(); diff --git a/libjin/Graphics/Drawable.cpp b/libjin/Graphics/Drawable.cpp index 9f52f0a..ee3e5f2 100644 --- a/libjin/Graphics/Drawable.cpp +++ b/libjin/Graphics/Drawable.cpp @@ -10,7 +10,7 @@ namespace jin { namespace graphics { - + Drawable::Drawable(int w, int h) : texture(0) , size(w, h) @@ -27,6 +27,35 @@ namespace graphics texture_coords[6] = 1; texture_coords[7] = 0; } + Drawable::Drawable(const Bitmap* bitmap) + : texture(0) + , anchor(0, 0) + { + unsigned int w = size.w = bitmap->getWidth(); + unsigned int h = size.h = bitmap->getHeight(); + + vertex_coords[0] = 0; vertex_coords[1] = 0; + vertex_coords[2] = 0; vertex_coords[3] = h; + vertex_coords[4] = w; vertex_coords[5] = h; + vertex_coords[6] = w; vertex_coords[7] = 0; + + texture_coords[0] = 0; texture_coords[1] = 0; + texture_coords[2] = 0; texture_coords[3] = 1; + texture_coords[4] = 1; texture_coords[5] = 1; + texture_coords[6] = 1; texture_coords[7] = 0; + + unsigned int w = size.w; + unsigned int h = size.h; + const Color* pixels = bitmap->getPixels(); + + texture = gl.genTexture(); + gl.bindTexture(texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + gl.bindTexture(0); + } + Drawable::~Drawable() { glDeleteTextures(1, &texture); @@ -42,9 +71,9 @@ namespace graphics { gl.ModelMatrix.setTransformation(x, y, r, sx, sy, anchor.x, anchor.y); - Shader* shader = Shader::getCurrentJSL(); - shader->sendMatrix4(Shader::MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); shader->bindVertexPointer(2, GL_FLOAT, 0, vertex_coords); shader->bindUVPointer(2, GL_FLOAT, 0, texture_coords); @@ -53,6 +82,38 @@ namespace graphics gl.bindTexture(0); } + void Drawable::draw(const math::Quad& slice, int x, int y, float sx, float sy, float r, float ax, float ay) + { + float vertCoords[8] = { + 0, 0, + 0, slice.h, + slice.w, slice.h, + slice.w, 0 + }; + float slx = slice.x / size.w; + float sly = slice.y / size.h; + float slw = slice.w / size.w; + float slh = slice.h / size.h; + float texCoords[8] = { + slx, sly, + slx, sly + slh, + slx + slw, sly + slh, + slx + slw, sly + }; + + gl.ModelMatrix.setTransformation(x, y, r, sx, sy, ax, ay); + + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(Shader::SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(Shader::SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, vertCoords); + shader->bindUVPointer(2, GL_FLOAT, 0, texCoords); + + gl.bindTexture(texture); + gl.drawArrays(GL_QUADS, 0, 4); + gl.bindTexture(0); + } + } // render } // jin diff --git a/libjin/Graphics/Drawable.h b/libjin/Graphics/Drawable.h index c77068c..0c4c3ef 100644 --- a/libjin/Graphics/Drawable.h +++ b/libjin/Graphics/Drawable.h @@ -3,8 +3,10 @@ #include "../jin_configuration.h" #if LIBJIN_MODULES_RENDER +#include "../math/Quad.h" #include "../math/Vector2.hpp" #include "OpenGL.h" +#include "Bitmap.h" namespace jin { @@ -15,10 +17,12 @@ namespace graphics { public: Drawable(int w = 0, int h = 0); + Drawable(const Bitmap* bitmap); virtual ~Drawable(); void setAnchor(int x, int y); - void draw(int x, int y, float sx, float sy, float r); + void draw(int x, int y, float sx = 1, float sy = 1, float r = 0); + void draw(const math::Quad& slice, int x, int y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); inline int getWidth() const { return size.w; } inline int getHeight() const { return size.h; } inline GLuint getTexture() const { return texture; } diff --git a/libjin/Graphics/Font.cpp b/libjin/Graphics/Font.cpp deleted file mode 100644 index dc7fb33..0000000 --- a/libjin/Graphics/Font.cpp +++ /dev/null @@ -1,354 +0,0 @@ -#include "../jin_configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "OpenGL.h" -#include "font.h" -#include <stdio.h> -#include "color.h" -#include "Shader.h" -#include "../Common/Array.hpp" - -namespace jin -{ -namespace graphics -{ - - #include "Shaders/font.shader.h" - - using namespace std; - using namespace jin::math; - - const int Font::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 }; - const int Font::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 }; - - /* utf8 byte string to unicode codepoint */ - static const char *utf8toCodepoint(const char *p, unsigned *res) { - 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; - } - - /*static*/ Font* Font::createFont(FontData* fontData, unsigned int fontSzie) - { - Font* font; - try - { - font = new Font(fontData, fontSzie); - } - catch (...) - { - return nullptr; - } - return font; - } - - void Font::destroyFont(Font* font) - { - if (font != nullptr) - delete font; - } - - Font::Font(FontData* f, unsigned int fontSize) - : cursor(0, 0) - , font(f) - , fontsize(fontSize) - { - font->pushFontsize(fontsize); - font->getVMetrics(&baseline, &descent); - estimateSize(); - font->popFontsize(); - /* create a default texture */ - createAtlas(); - } - - /* estimate the size of atlas texture */ - void Font::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; - } - } - } - - Font::~Font() - { - map<unsigned int, Glyph*>::iterator it = glyphs.begin(); - for (; it != glyphs.end(); ++it) - { - delete it->second; - } - } - - GLuint Font::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 Font::print(const char* t, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(t, lineheight, spacing); - print(page, x, y); - delete page; - } - - Page* Font::typeset(const char* text, int lineheight, int spacing) - { - // typesetting, for reducing draw call - const char* t = text; - Page* page = new Page(); - vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Vector2<int> p(0, 0); - Codepoint c; - int texture = -1; - Glyph* glyph = nullptr; - GlyphVertex vertex; - for (int i = 0; *t != NULL; i += 4) - { - t = utf8toCodepoint(t, &c); - if (c == 0x0D) - { - i -= 4; - continue; - } - /* new line */ - if (c == 0x0A) - { - p.y += lineheight; - p.x = 0; - i -= 4; - continue; - } - 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; - Glyph::Bbox& bbox = glyph->bbox; - // 1 - vertex.x = p.x; vertex.y = p.y; - vertex.u = bbox.x; vertex.v = bbox.y; - glyphvertices.push_back(vertex); - // 2 - vertex.x = p.x; vertex.y = p.y + glyph->height; - vertex.u = bbox.x; vertex.v = bbox.y + bbox.height; - glyphvertices.push_back(vertex); - // 3 - vertex.x = p.x + glyph->width; vertex.y = p.y + glyph->height; - vertex.u = bbox.x + bbox.width; vertex.v = bbox.y + bbox.height; - glyphvertices.push_back(vertex); - // 4 - vertex.x = p.x + glyph->width; vertex.y = p.y; - vertex.u = bbox.x + bbox.width; vertex.v = bbox.y; - glyphvertices.push_back(vertex); - - p.x += glyph->width + spacing; - } - //getTextBox(text, &page->width, &page->height, lineheight, spacing); - return page; - } - - void Font::print(const Page* page, int x, int y) - { - Shader* shader = Shader::getCurrentJSL(); - 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); - } - } - - int Font::getCharWidth(int c) - { - int adw, lsb; - font->getHMetrics(c, &adw, &lsb); - return adw; - } - - int Font::getCharHeight(int c) - { - return descent; - } - - int Font::getTextWidth(const char* t, int spacing) - { - int res = 0; - int tmp = 0; - const char *p = t; - while (*p) { - unsigned c; - p = utf8toCodepoint(p, &c); - if (*p == 0x0D) - continue; - if (*p == 0x0A) - { - tmp = 0; - continue; - } - tmp += getCharWidth(c) + spacing; - if (tmp > res) res = tmp; - } - return res; - } - - int Font::getTextHeight(const char* t, int lineheight) - { - int res = 0; - bool newline = true; - while (*t) - { - unsigned c; - t = utf8toCodepoint(t, &c); - if (*t == 0x0A) - newline = true; - else if (*t == 0x0D); - else if (newline) - { - newline = false; - res += lineheight; - } - } - return res; - } - - void Font::getTextBox(const char* text, int* w, int* h, int lineheight, int spacing) - { - *w = 0; - *h = 0; - int tmp = 0; - const char *p = text; - bool nl = true; - while (*p) { - unsigned c; - p = utf8toCodepoint(p, &c); - if (*p == 0x0D) - continue; - if (*p == 0x0A) - { - tmp = 0; - nl = true; - continue; - } - else if(nl) - { - nl = false; - *h += lineheight; - } - tmp += getCharWidth(c) + spacing; - if (tmp > *w) *w = tmp; - } - } - - Glyph* Font::bakeGlyph(unsigned int character) - { - Glyph* glyph = (Glyph*)malloc(sizeof(Glyph)); - int w, h, xoff, yoff; - font->pushFontsize(fontsize); - GLuint atlas = atlases.back(); - const Color* bitmap = font->getCodepointBitmap(character, &w, &h, &xoff, &yoff); - int adw, lsb; - { - font->getHMetrics(character, &adw, &lsb); - font->popFontsize(); - 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; - } - glyph->atlas = atlas; - glyph->bbox.x = cursor.x / (float)textureWidth; - glyph->bbox.y = cursor.y / (float)textureHeight; - glyph->bbox.width = adw / (float)textureWidth; - glyph->bbox.height = descent / (float)textureHeight; - glyph->width = adw; - glyph->height = descent; - glyphs.insert(std::pair<unsigned int, Glyph*>(character, glyph)); - - cursor.x += adw; - return glyph; - } - - Glyph* Font::findGlyph(unsigned int character) - { - map<unsigned int, Glyph*>::iterator it = glyphs.find(character); - if (it != glyphs.end()) - { - return it->second; - } - else - { - Glyph* glyph = bakeGlyph(character); - return glyph; - } - } - -} // graphics -} // jin - -#endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/libjin/Graphics/Font.h b/libjin/Graphics/Font.h index 4525e8f..adb8c38 100644 --- a/libjin/Graphics/Font.h +++ b/libjin/Graphics/Font.h @@ -1,105 +1,28 @@ #ifndef __LIBJIN_FONT_H #define __LIBJIN_FONT_H -#include "../jin_configuration.h" -#if LIBJIN_MODULES_RENDER - -#include <vector> -#include <map> -#include "drawable.h" -#include "FontData.h" -#include "../math/quad.h" namespace jin { namespace graphics -{ - - 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 Glyph - { - GLuint atlas; - /* normalized coordinates */ - struct Bbox - { - float x, y; - float width, height; - } bbox; - /* glyph size in pixel */ - unsigned int width, height; - }; + typedef unsigned int Codepoint; - struct Page - { - std::vector<GlyphArrayDrawInfo> glyphinfolist; - std::vector<GlyphVertex> glyphvertices; - int width, height; - }; + struct Page; class Font { public: - typedef unsigned int Codepoint; - - static Font* createFont(FontData* fontData, unsigned int fontSzie); - static void destroyFont(Font* font); - - Page* typeset(const char* text, int lineheight, int spacing); - void print(const char* text, int x, int y, int lineheight, int spacing = 0); - void print(const Page* page, int x, int y); - //Bitmap* bake(const char* text); -#if defined(font_debug) - void drawAtlas(); -#endif - - private: - 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]; - - Font(FontData* font, Codepoint fontSize); - ~Font(); - - void estimateSize(); - GLuint createAtlas(); - Glyph* bakeGlyph(Codepoint character); - Glyph* findGlyph(Codepoint character); - - int getCharWidth(int c); - int getCharHeight(int c); - int getTextWidth(const char* text, int spacing = 0); - int getTextHeight(const char* text, int lineheight); - void getTextBox(const char* text, int* w, int* h, int lineheight, int spacing = 0); - - int textureWidth; - int textureHeight; - std::vector<GLuint> atlases; - /* map unicode codepoint to glyph */ - std::map<Codepoint, Glyph*> glyphs; - FontData* font; - const unsigned int fontsize; - int baseline; - int descent; + Font() {} + virtual ~Font() {}; - /* cursor helped render to texture */ - math::Vector2<float> cursor; + virtual void print(const Page* page, int x, int y) = 0; + virtual void print(const std::vector<Codepoint>& text, int x, int y, int lineheight, int spacing = 0) = 0; + virtual Page* typeset(const std::vector<Codepoint>& text, int lineheight, int spacing = 0) = 0; }; -} // graphics -} // jin +} +} -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_FONT_H
\ No newline at end of file +#endif
\ No newline at end of file diff --git a/libjin/Graphics/FontData.cpp b/libjin/Graphics/FontData.cpp deleted file mode 100644 index 1b66b12..0000000 --- a/libjin/Graphics/FontData.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "FontData.h" -#define STB_TRUETYPE_IMPLEMENTATION -#include "../3rdparty/stb/stb_truetype.h" -#include <stdio.h> - -namespace jin -{ -namespace graphics -{ - - FontData* FontData::createFontData(const unsigned char* data, unsigned int size) - { - FontData* font = nullptr; - try - { - font = new FontData(data, size); - return font; - } - catch (...) - { - return nullptr; - } - } - - FontData::FontData(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 */ - pushFontsize(FONT_SIZE); - } - - FontData::~FontData() - { - free(raw.data); - } - - /* - * (0, 0) - * +--------------+ ascent - * | +--------+ | - * | | | | - * | | bitmap | | - * +--|--------|--+ baseline - * | +--------+ | - * +--|-----------+ decent - * | | - * leftSideBearing | - * | - * advanceWidth - */ - void FontData::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 FontData::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 FontData::pushFontsize(unsigned int fs) - { - float sc = stbtt_ScaleForPixelHeight(&info, fs); - scales.push_back(sc); - } - - void FontData::popFontsize() - { - /* always keep default font size on the bottom of stack */ - if(scales.size() > 1) - scales.pop_back(); - } - - Channel* FontData::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* FontData::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; - } - -} -}
\ No newline at end of file diff --git a/libjin/Graphics/FontData.h b/libjin/Graphics/FontData.h deleted file mode 100644 index c75b9a1..0000000 --- a/libjin/Graphics/FontData.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __LIBJIN_FONTDATA_H -#define __LIBJIN_FONTDATA_H -#include "../3rdparty/stb/stb_truetype.h" -#include "Color.h" -#include <vector> - -namespace jin -{ -namespace graphics -{ - - class FontData - { - public: - static FontData* createFontData(const unsigned char* data, unsigned int size); - - ~FontData(); - - void pushFontsize(unsigned int fontsize); - void popFontsize(); - - 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; - - FontData(const unsigned char* data, unsigned int size); - - stbtt_fontinfo info; - struct - { - unsigned char* data; - unsigned int size; - } raw; - std::vector<float> scales; - - }; - -} -} - -#endif
\ No newline at end of file diff --git a/libjin/Graphics/Graphics.h b/libjin/Graphics/Graphics.h index 961f9b1..a4bf98b 100644 --- a/libjin/Graphics/Graphics.h +++ b/libjin/Graphics/Graphics.h @@ -5,7 +5,8 @@ #include "canvas.h" #include "color.h" -#include "font.h" +#include "FontData.h" +#include "Font.h" #include "Shapes.h" #include "texture.h" #include "Shader.h" diff --git a/libjin/Graphics/Mesh.h b/libjin/Graphics/Mesh.h index d0bb93e..c14af89 100644 --- a/libjin/Graphics/Mesh.h +++ b/libjin/Graphics/Mesh.h @@ -8,6 +8,10 @@ namespace graphics class Mesh { + public: + + private: + }; diff --git a/libjin/Graphics/Page.h b/libjin/Graphics/Page.h new file mode 100644 index 0000000..b878a74 --- /dev/null +++ b/libjin/Graphics/Page.h @@ -0,0 +1,38 @@ +#ifndef __LIBJIN_PAGE_H +#define __LIBJIN_PAGE_H +#include "../math/Vector2.hpp" +#include "Font.h" + +namespace jin +{ +namespace graphics +{ + + class Font; + + 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 + }; + + /* 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/libjin/Graphics/Shader.cpp b/libjin/Graphics/Shader.cpp index d484662..688fa51 100644 --- a/libjin/Graphics/Shader.cpp +++ b/libjin/Graphics/Shader.cpp @@ -21,13 +21,7 @@ namespace graphics * SHADER_FORMAT_SIZE * formatShader */ - #include "Shaders/base.shader.h" - - const char* Shader::PROJECTION_MATRIX = "_projectionMatrix_"; - const char* Shader::MODEL_MATRIX = "_modelMatrix_"; - const char* Shader::MAIN_TEXTURE = "_main_texture_"; - const char* Shader::VERTEX_COORDS = "_vert_coord_"; - const char* Shader::TEXTURE_COORDS = "_tex_coord_"; + #include "Shaders/default.shader.h" /** * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value @@ -85,6 +79,7 @@ namespace graphics 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"); @@ -95,12 +90,13 @@ namespace graphics || loc_END_FRAGMENT_SHADER == string::npos ) return false; - int p = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); - string vertex_shader = program.substr(p, loc_END_VERTEX_SHADER - p); + /* 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()); - p = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); - string fragment_shader = program.substr(p, loc_END_FRAGMENT_SHADER - p); + 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 */ @@ -109,18 +105,12 @@ namespace graphics glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); glCompileShader(vshader); glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); - std::cout << (char*)vbuffer.data << std::endl; - Buffer log = Buffer(1024); - int len; - glGetShaderInfoLog(vshader, sizeof(log), &len, (GLchar*)log.data); - std::cout << (char*)log.data << std::endl; 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); - std::cout << (char*)fbuffer.data << std::endl; if (success == GL_FALSE) return false; pid = glCreateProgram(); @@ -128,8 +118,6 @@ namespace graphics glAttachShader(pid, fshader); glLinkProgram(pid); glGetProgramiv(pid, GL_LINK_STATUS, &success); - glGetProgramInfoLog(pid, 1024, &len, (GLchar*)log.data); - std::cout << (char*)log.data << std::endl; if (success == GL_FALSE) throw false; } @@ -140,12 +128,12 @@ namespace graphics glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); return maxTextureUnits; } - + void Shader::use() { glUseProgram(pid); currentShader = this; - sendInt(Shader::MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); + sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); } /*static*/ void Shader::unuse() @@ -276,14 +264,14 @@ namespace graphics void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) { - GLint loc = glGetAttribLocation(pid, VERTEX_COORDS); + 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, TEXTURE_COORDS); + GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS); glEnableVertexAttribArray(1); glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); } diff --git a/libjin/Graphics/Shader.h b/libjin/Graphics/Shader.h index 2ea9e04..dcd0b62 100644 --- a/libjin/Graphics/Shader.h +++ b/libjin/Graphics/Shader.h @@ -9,26 +9,20 @@ #include "texture.h" #include "canvas.h" #include "../3rdparty/GLee/GLee.h" +#include "Shaders/base.shader.h" namespace jin { namespace graphics { - /* Jin Shading Language Program*/ class Shader { public: static Shader* createShader(const std::string& program); - static inline Shader* getCurrentJSL() { return currentShader; } + static inline Shader* getCurrentShader() { return currentShader; } static void unuse(); - static const char* PROJECTION_MATRIX; - static const char* MODEL_MATRIX; - static const char* MAIN_TEXTURE; - static const char* VERTEX_COORDS; - static const char* TEXTURE_COORDS; - virtual ~Shader(); void use(); diff --git a/libjin/Graphics/Shaders/base.shader.h b/libjin/Graphics/Shaders/base.shader.h index 4efbab7..bf41c4f 100644 --- a/libjin/Graphics/Shaders/base.shader.h +++ b/libjin/Graphics/Shaders/base.shader.h @@ -1,3 +1,5 @@ +#ifndef LIBJIN_BASE_SHADER_H +#define LIBJIN_BASE_SHADER_H /* * https://stackoverflow.com/questions/10868958/what-does-sampler2d-store * The sampler2D is bound to a texture unit. The glUniform call binds it to texture @@ -51,26 +53,26 @@ static const char* base_vertex = R"( %s -uniform mat4 _projectionMatrix_; -uniform mat4 _modelMatrix_; +uniform mat4 jin_ProjectionMatrix; +uniform mat4 jin_ModelMatrix; -in vec2 _vert_coord_; -in vec2 _tex_coord_; +in vec2 jin_VertexCoords; +in vec2 jin_TextureCoords; -out vec4 _color; -out vec2 _xy; -out vec2 _uv; +out vec4 jin_Color; +out vec2 jin_XY; +out vec2 jin_UV; %s void main() { - vec4 v = _modelMatrix_ * vec4(_vert_coord_, 0, 1.0); - Vertex _v = vert(Vertex(v.xy, _tex_coord_)); - gl_Position = _projectionMatrix_ * v; - _color = gl_Color; - _xy = _v.xy; - _uv = _v.uv; + vec4 v = jin_ModelMatrix * vec4(jin_VertexCoords, 0, 1.0); + Vertex _v = vert(Vertex(v.xy, jin_TextureCoords)); + gl_Position = jin_ProjectionMatrix * vec4(_v.xy, 0, 1.0f); + jin_Color = gl_Color; + jin_XY = _v.xy; + jin_UV = _v.uv; } )"; @@ -83,22 +85,30 @@ static const char* base_fragment = R"( %s -uniform Texture _main_texture_; +uniform Texture jin_MainTexture; -in vec4 _color; -in vec2 _xy; -in vec2 _uv; +in vec4 jin_Color; +in vec2 jin_XY; +in vec2 jin_UV; -out vec4 _outColor_; +out vec4 jin_OutColor; %s void main() { - _outColor_ = frag(_color, _main_texture_, Vertex(_xy, _uv)); + jin_OutColor = frag(jin_Color, jin_MainTexture, Vertex(jin_XY, jin_UV)); } )"; static const int BASE_FRAGMENT_SHADER_SIZE = strlen(base_fragment) + BASE_SHARED_SIZE; #define formatFragmentShader(buf, program) sprintf(buf, base_fragment, base_shared, program) + +static const char* SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; +static const char* SHADER_MODEL_MATRIX = "jin_ModelMatrix"; +static const char* SHADER_MAIN_TEXTURE = "jin_MainTexture"; +static const char* SHADER_VERTEX_COORDS = "jin_VertexCoords"; +static const char* SHADER_TEXTURE_COORDS = "jin_TextureCoords"; + +#endif
\ No newline at end of file diff --git a/libjin/Graphics/Shapes.cpp b/libjin/Graphics/Shapes.cpp index f639695..f5aedd4 100644 --- a/libjin/Graphics/Shapes.cpp +++ b/libjin/Graphics/Shapes.cpp @@ -18,20 +18,22 @@ namespace graphics { float verts[] = { x + 0.5f , y + 0.5f }; - Shader* shader = Shader::getCurrentJSL(); + Shader* shader = Shader::getCurrentShader(); shader->bindVertexPointer(2, GL_FLOAT, 0, verts); - shader->sendMatrix4(Shader::MODEL_MATRIX, &Matrix::Identity); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); glDrawArrays(GL_POINTS, 0, 1); } void points(int n, GLshort* p) { - Shader* shader = Shader::getCurrentJSL(); + Shader* shader = Shader::getCurrentShader(); shader->bindVertexPointer(2, GL_SHORT, 0, p); - shader->sendMatrix4(Shader::MODEL_MATRIX, &Matrix::Identity); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); glDrawArrays(GL_POINTS, 0, n); } @@ -43,10 +45,11 @@ namespace graphics x2, y2 }; - Shader* shader = Shader::getCurrentJSL(); + Shader* shader = Shader::getCurrentShader(); shader->bindVertexPointer(2, GL_FLOAT, 0, verts); - shader->sendMatrix4(Shader::MODEL_MATRIX, &Matrix::Identity); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); glDrawArrays(GL_LINES, 0, 2); } @@ -90,9 +93,10 @@ namespace graphics void polygon_line(float* p, int count) { - Shader* shader = Shader::getCurrentJSL(); - shader->sendMatrix4(Shader::MODEL_MATRIX, &Matrix::Identity); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + 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); @@ -106,9 +110,10 @@ namespace graphics } else if (mode == FILL) { - Shader* shader = Shader::getCurrentJSL(); - shader->sendMatrix4(Shader::MODEL_MATRIX, &Matrix::Identity); - shader->sendMatrix4(Shader::PROJECTION_MATRIX, &gl.ProjectionMatrix); + 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); diff --git a/libjin/Graphics/TTF.cpp b/libjin/Graphics/TTF.cpp new file mode 100644 index 0000000..e5a3f3a --- /dev/null +++ b/libjin/Graphics/TTF.cpp @@ -0,0 +1,458 @@ +#include "../jin_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "OpenGL.h" +#include "ttf.h" +#include <stdio.h> +#include "color.h" +#include "Shader.h" +#include "Page.h" +#include "../Common/Array.hpp" + +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); + } + + /* + * (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 }; + + /* utf8 byte string to unicode codepoint */ + static const char* utf8toCodepoint(const char *p, Codepoint *res) { + 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; + } + + /* 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) + : cursor(0, 0) + , ttf(f) + , ttfsize(fontSize) + { + ttf->pushTTFsize(ttfsize); + 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() + { + map<unsigned int, TTFGlyph*>::iterator it = glyphs.begin(); + for (; it != glyphs.end(); ++it) + { + delete it->second; + } + } + + 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 std::vector<Codepoint>& 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 std::vector<Codepoint>& 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; +#define glyphvertices_push(_x, _y, _u, _v) \ +vertex.x = _x; vertex.y = _y;\ +vertex.u = _u; vertex.v = _v;\ +glyphvertices.push_back(vertex); + Vector2<int> p(0, 0); + int i = 0; + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + /* new line */ + if (c == 0x0A) + { + p.y += lineheight; + p.x = 0; + continue; + } + 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.height); + glyphvertices_push(p.x + glyph->width, p.y + glyph->height, bbox.x + bbox.width, bbox.y + bbox.height); + glyphvertices_push(p.x + glyph->width, p.y, bbox.x + bbox.width, bbox.y); + + p.x += glyph->width + spacing; + + i += 4; + } +#undef glyphvertices_push + getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing); + return page; + } + + 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); + } + } + + int TTF::getCharWidth(int c) + { + int adw, lsb; + ttf->pushTTFsize(ttfsize); + ttf->getHMetrics(c, &adw, &lsb); + ttf->popTTFsize(); + return adw; + } + + int TTF::getCharHeight(int c) + { + return descent; + } + + int TTF::getTextWidth(const std::vector<Codepoint>& t, int spacing) + { + ttf->pushTTFsize(ttfsize); + 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 std::vector<Codepoint>& t, int lineheight) + { + ttf->pushTTFsize(ttfsize); + 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 std::vector<Codepoint>& text, int* w, int* h, int lineheight, int spacing) + { + ttf->pushTTFsize(ttfsize); + *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) + { + TTFGlyph* glyph = (TTFGlyph*)malloc(sizeof(TTFGlyph)); + int w, h, xoff, yoff; + ttf->pushTTFsize(ttfsize); + GLuint atlas = atlases.back(); + const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff); + int adw, lsb; + { + 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; + } + glyph->atlas = atlas; + glyph->bbox.x = cursor.x / (float)textureWidth; + glyph->bbox.y = cursor.y / (float)textureHeight; + glyph->bbox.width = adw / (float)textureWidth; + glyph->bbox.height = descent / (float)textureHeight; + glyph->width = adw; + glyph->height = descent; + glyphs.insert(std::pair<unsigned int, TTFGlyph*>(character, glyph)); + + cursor.x += adw; + return glyph; + } + + TTF::TTFGlyph* TTF::findGlyph(unsigned int character) + { + map<unsigned int, TTFGlyph*>::iterator it = glyphs.find(character); + if (it != glyphs.end()) + { + return it->second; + } + else + { + TTFGlyph* glyph = bakeGlyph(character); + return glyph; + } + } + +} // graphics +} // jin + +#endif // LIBJIN_MODULES_RENDER
\ No newline at end of file diff --git a/libjin/Graphics/TTF.h b/libjin/Graphics/TTF.h new file mode 100644 index 0000000..d2459ba --- /dev/null +++ b/libjin/Graphics/TTF.h @@ -0,0 +1,114 @@ +#ifndef __LIBJIN_TTF_H +#define __LIBJIN_TTF_H +#include "../jin_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include <vector> +#include <map> +#include "drawable.h" +#include "../math/quad.h" +#include "Page.h" +#include "Font.h" +#include "Color.h" +#include "../3rdparty/stb/stb_truetype.h" + +namespace jin +{ +namespace graphics +{ + + class TTFData + { + public: + static TTFData* createTTFData(const unsigned char* data, unsigned int size); + + ~TTFData(); + + void pushTTFsize(unsigned int 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 int ttfSzie); + + Page* typeset(const std::vector<Codepoint>& text, int lineheight, int spacing) override; + void print(const std::vector<Codepoint>& text, int x, int y, int lineheight, int spacing = 0) override; + void print(const Page* page, int x, int y) override ; +#if defined(ttf_debug) + void drawAtlas(); +#endif + ~TTF(); + + private: + struct TTFGlyph + { + GLuint atlas; + /* normalized coordinates */ + struct Bbox + { + float x, y; + float width, height; + } 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 std::vector<Codepoint>& text, int spacing = 0); + int getTextHeight(const std::vector<Codepoint>& text, int lineheight); + void getTextBox(const std::vector<Codepoint>& text, int* w, int* h, int lineheight, int spacing = 0); + + int textureWidth; + int textureHeight; + std::vector<GLuint> atlases; + /* map unicode codepoint to glyph */ + std::map<Codepoint, TTFGlyph*> glyphs; + TTFData* ttf; + const unsigned int ttfsize; + int baseline; + int descent; + + /* cursor helped render to texture */ + math::Vector2<float> cursor; + + }; + +} // graphics +} // jin + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_FONT_H
\ No newline at end of file diff --git a/libjin/Graphics/TexFont.cpp b/libjin/Graphics/TexFont.cpp new file mode 100644 index 0000000..ffd8c72 --- /dev/null +++ b/libjin/Graphics/TexFont.cpp @@ -0,0 +1,56 @@ +#include "TexFont.h" + +namespace jin +{ +namespace graphics +{ + /* + * +--------------------+ + * | top | + * | l ************* r | + * | e ************* i | + * | f ****glyphs*** g | + * | t ************* h | + * | ************* t | + * | bottom | + * +--------------------+ + */ + + /* create texture font from tilemap */ + TexFont * TexFont::createTexFont(const Bitmap* bitmap, const std::vector<Codepoint>& codepoints, int cellw, int cellh, int l, int r, int t, int b) + { + } + + /* create texture font from seperated glyphs */ + TexFont* TexFont::createTexFont(const Bitmap* bitmap, const std::vector<Codepoint>& codepoints, Color mask, int cellh, int l, int r, int t, int b) + { + + } + + TexFont::~TexFont() + { + + } + + Page* TexFont::typeset(const std::vector<Codepoint>& text, int lineheight, int spacing = 0) + { + + } + + void TexFont::print(const Page* page, int x, int y) + { + + } + + void TexFont::print(const std::vector<Codepoint>& text, int x, int y, int linehgiht, int spacing = 0) + { + + } + + TexFont::TexFont(const Bitmap* bitmap) + : Drawable(bitmap) + { + } + +} +}
\ No newline at end of file diff --git a/libjin/Graphics/TexFont.h b/libjin/Graphics/TexFont.h new file mode 100644 index 0000000..334ff5c --- /dev/null +++ b/libjin/Graphics/TexFont.h @@ -0,0 +1,44 @@ +#ifndef __LIBJIN_TEXTURE_FONT_H +#define __LIBJIN_TEXTURE_FONT_H + +#include <map> +#include <vector> + +#include "Page.h" +#include "Bitmap.h" +#include "Font.h" +#include "Drawable.h" + +namespace jin +{ +namespace graphics +{ + + class TexFont : public Font + , public Drawable + { + public: + /* create texture font from tilemap */ + TexFont * createTexFont(const Bitmap* bitmap, const std::vector<Codepoint>& codepoints, int cellw, int cellh, int l = 0, int r = 0, int t = 0, int b = 0); + /* create texture font from seperated glyphs */ + TexFont* createTexFont(const Bitmap* bitmap, const std::vector<Codepoint>& codepoints, Color mask, int cellh, int l = 0, int r = 0, int t = 0, int b = 0); + + ~TexFont(); + + Page* typeset(const std::vector<Codepoint>& text, int lineheight, int spacing = 0) override ; + void print(const Page* page, int x, int y) override; + void print(const std::vector<Codepoint>& text, int x, int y, int linehgiht, int spacing = 0) override; + + private: + struct TexGlyph { unsigned short x, y, w, h;}; + + TexFont(const Bitmap* bitmap); + + std::map<Codepoint, TexGlyph> glyphs; + + }; + +} +} + +#endif
\ No newline at end of file diff --git a/libjin/Graphics/Texture.cpp b/libjin/Graphics/Texture.cpp index 5a39f77..a42e796 100644 --- a/libjin/Graphics/Texture.cpp +++ b/libjin/Graphics/Texture.cpp @@ -20,18 +20,8 @@ namespace graphics } Texture::Texture(const Bitmap* bitmap) - : Drawable(bitmap->getWidth(), bitmap->getHeight()) + : Drawable(bitmap) { - unsigned int w = size.w; - unsigned int h = size.h; - const Color* pixels = bitmap->getPixels(); - - texture = gl.genTexture(); - gl.bindTexture(texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - gl.bindTexture(0); } Texture::~Texture() diff --git a/libjin/Graphics/Window.cpp b/libjin/Graphics/Window.cpp index d04a1c7..6ebc9f9 100644 --- a/libjin/Graphics/Window.cpp +++ b/libjin/Graphics/Window.cpp @@ -5,6 +5,7 @@ #include "window.h" #include "OpenGL.h" #include "canvas.h" +#include "Shader.h" #include "../utils/utils.h" #include "../audio/sdl/SDLAudio.h" #include "../utils/log.h" @@ -77,6 +78,7 @@ namespace graphics swapBuffers(); /* bind to default canvas */ Canvas::unbind(); + Shader::unuse(); return true; } diff --git a/libjin/Math/Matrix.cpp b/libjin/Math/Matrix.cpp index a80f37a..a6e2491 100644 --- a/libjin/Math/Matrix.cpp +++ b/libjin/Math/Matrix.cpp @@ -26,10 +26,10 @@ namespace math void Matrix::setOrtho(float l, float r, float b, float t, float n, float f) { - float w = r - l; + setIdentity(); + float w = r - l; float h = t - b; float z = f - n; - setIdentity(); e[0] = 2 / w; e[5] = 2 / h; e[10] = -2 / z; diff --git a/test/05Font/main.cpp b/test/05Font/main.cpp index 3b58bae..3ce8183 100644 --- a/test/05Font/main.cpp +++ b/test/05Font/main.cpp @@ -10,13 +10,14 @@ Font* font = nullptr; Canvas* canvas; FontData* data = nullptr; Shader* shader = nullptr; +Shader* shader2 = nullptr; Page* page = nullptr; Texture* tex = nullptr; float dt; void onLoad() { - const char* program = R"( + const char* font_shader = R"( #VERTEX_SHADER Vertex vert(Vertex v) @@ -28,8 +29,6 @@ Vertex vert(Vertex v) #FRAGMENT_SHADER -vec2 stepSize = vec2(0.02f, 0.02f); - Color frag(Color col, Texture tex, Vertex v) { return vec4(col.rgb, texel(tex, v.uv).a); @@ -37,15 +36,37 @@ Color frag(Color col, Texture tex, Vertex v) #END_FRAGMENT_SHADER )"; - shader = Shader::createShader(program); + const char* canvas_shader = R"( +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + if(v.uv.x <= 0.002f || v.uv.x >= 0.998f || v.uv.y <= 0.005f || v.uv.y >= 0.995f) + return vec4(1, 1, 1, 1); + else + return texel(tex, v.uv); +} + +#END_FRAGMENT_SHADER +)"; + shader = Shader::createShader(font_shader); + shader2 = Shader::createShader(canvas_shader); Filesystem* fs = Filesystem::get(); fs->mount("../Debug"); Buffer buffer; fs->read("font.ttf", &buffer); data = FontData::createFontData((const unsigned char*)buffer.data, buffer.size); - font = Font::createFont(data, 18); - page = font->typeset(u8R"( -平安時代中期の物語。紫式部著。ただし,そのすべてが紫式部の筆に成るのでは + font = Font::createFont(data, 15); + page = font->typeset(u8R"(平安時代中期の物語。紫式部著。ただし,そのすべてが紫式部の筆に成るのでは ないとする説もある。 54帖。寛弘 (1004~12) 頃成立か。物語は3部に分けてみ ることができる。第1部は,容貌,才能などすべてにすぐれた主人公光源氏が,多 啊哈噶科膜卡して広く迎えられている。貴族社会の苦悩を摘出したところに磁瓷得 @@ -61,7 +82,7 @@ Color frag(Color col, Texture tex, Vertex v) 》开始在日本东京电视台播出。2004年,漫画进而改编成电影。2006年,漩涡鸣人入选 美国《新闻周刊》日文版于10月18日发行的特集中选出的“全世界最受尊敬的100位日本 人”。[2] -)", 20, 0); +)", 17, 0); delete data; //canvas = Canvas::createCanvas(100, 100); //page = font->typeset("こんにちは世界!", 120, 20); @@ -69,7 +90,22 @@ Color frag(Color col, Texture tex, Vertex v) fs->read("img.png", &buffer); Bitmap* bitmap = Bitmap::createBitmap(buffer.data, buffer.size); tex = Texture::createTexture(bitmap); - canvas = Canvas::createCanvas(100, 100); + canvas = Canvas::createCanvas(page->width, page->height); + + Canvas::bind(canvas); + glClear(GL_COLOR_BUFFER_BIT); + glColor4f(1, 1, 1, 1); + if (font != nullptr) + { + //font->print(u8"Hello,你好\n啊 world!", 10, 10); + //font->print(u8"Привет мир!", 10, 10 + 15 * 1); + shader->use(); + font->print(page, 0, 0); + shader->unuse(); + //font->print(u8"你好世界!", 10, 10 + 15*3); + //font->render(page); + } + Canvas::unbind(); } void onEvent(jin::input::Event* e) @@ -90,23 +126,13 @@ void onDraw() glColor4f(1, 1, 1, 1); //gl.pushColor(32, 32, 32, 255); //rect(FILL, 0, 0, 500, 500); - shader->use(); //circle(RenderMode::LINE, 50, 50, 30); //tex->draw(0, 0, 1, 1, 0); //tex->draw(20, 50, 1, 1, 0); //shader->sendFloat("dt", dt); - Canvas::bind(canvas); - if (font != nullptr) - { - //font->print(u8"Hello,你好\n啊 world!", 10, 10); - //font->print(u8"Привет мир!", 10, 10 + 15 * 1); - font->print(page, 12, 10 + 15 * 2); - //font->print(u8"你好世界!", 10, 10 + 15*3); - //font->render(page); - } - Canvas::unbind(); - canvas->draw(0, 0, 1, 1, 0); - shader->unuse(); + shader2->use(); + canvas->draw(20 * sin(dt), 10 * cos(dt), 1, 1, 0); + shader2->unuse(); } int main(int argc, char* argv[]) diff --git a/test/06TextureFont/main.cpp b/test/06TextureFont/main.cpp new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/test/06TextureFont/main.cpp @@ -0,0 +1,3 @@ + + + |