From: Clyne Sullivan Date: Tue, 17 Sep 2019 17:55:22 +0000 (-0400) Subject: update with master; using VBOs for fonts X-Git-Tag: v0.2-alpha~5^2~7 X-Git-Url: https://code.bitgloo.com/?a=commitdiff_plain;h=ceda39e4bd2e3a7794f0cb4f96df1de6ebee47d2;p=clyne%2Fgamedev2.git update with master; using VBOs for fonts --- ceda39e4bd2e3a7794f0cb4f96df1de6ebee47d2 diff --cc src/engine.cpp index 37f6e68,a2d0e9b..70b0b45 --- a/src/engine.cpp +++ b/src/engine.cpp @@@ -45,10 -44,10 +45,11 @@@ int Engine::init(void systems.add(); systems.add(); systems.add(entities); + systems.add(); systems.add(); - systems.add(entities); + systems.add(entities, *(systems.system().get())); systems.add(); + systems.add(); systems.configure(); // Load game script and entity data diff --cc src/script.cpp index 61aa136,cf5b2dd..ec8f5c7 --- a/src/script.cpp +++ b/src/script.cpp @@@ -121,8 -127,19 +127,18 @@@ void ScriptSystem::scriptExport(void sol::constructors(), "standing", &Physics::standing); + lua.new_usertype("World", + sol::constructors(), + "Generate", &World::generate, + "Seed", sol::property(&World::setSeed, &World::getSeed), + "setData", &World::setData, + "registerMaterial", &World::registerMaterial, + "setSize", &World::setSize, + "getSize", &World::getSize); + - - auto gamespace = lua["game"].get_or_create(); - gamespace.set_function("spawn", entitySpawn); - gamespace.set_function("worldRegister", worldRegister); + game = lua["game"].get_or_create(); - game.set_function("spawn", [this](sol::table t) { return spawn(t); }); ++ game.set_function("spawn", entitySpawn); ++ game.set_function("worldRegister", worldRegister); } sol::table ScriptSystem::spawn(sol::object param) diff --cc src/script.hpp index f86c8cd,87027d5..0ac9e63 --- a/src/script.hpp +++ b/src/script.hpp @@@ -45,13 -47,16 +47,17 @@@ private * interactions between C and Lua */ sol::state lua; + sol::table game; entityx::EntityManager& manager; + + // TODO possibly emit events to spawn worlds instead of passing the + // world system around like a toy + WorldSystem &worldSystem; public: - ScriptSystem(entityx::EntityManager& _manager): - manager(_manager) {} + ScriptSystem(entityx::EntityManager& _mg, WorldSystem& _ws): + manager(_mg), worldSystem(_ws) {} ~ScriptSystem(void) {} diff --cc src/text.cpp index 85c0ceb,0000000..8726b88 mode 100644,000000..100644 --- a/src/text.cpp +++ b/src/text.cpp @@@ -1,72 -1,0 +1,124 @@@ +#include "text.hpp" + +#include + - //FT_Library freetype; - //std::map fonts; - //std::map> fontData; - +void TextSystem::configure([[maybe_unused]] entityx::EntityManager& entities, + [[maybe_unused]] entityx::EventManager& events) +{ + if (FT_Init_FreeType(&freetype) != 0) { + // TODO handle error + } +} + +/** + * Draws the text for all entities. + */ +void TextSystem::update([[maybe_unused]] entityx::EntityManager& entites, + [[maybe_unused]] entityx::EventManager& events, + [[maybe_unused]] entityx::TimeDelta dt) +{ + // TODO render each Text component's text +} + +void TextSystem::loadFont(const std::string& name, + const std::string& file, + int size) +{ ++ // Find or load font at given size ++ // + + if (fonts.find(file) == fonts.end()) { + FT_Face face; + if (FT_New_Face(freetype, file.c_str(), 0, &face)) { + // TODO handle this error + } + fonts.emplace(file, face); + } + + auto& face = fonts[file]; + FT_Set_Pixel_Sizes(face, 0, size); - fontData.try_emplace(name, 95); - - char c = 32; - for (auto& d : fontData[name]) { - FT_Load_Char(face, c++, FT_LOAD_RENDER); - - glGenTextures(1, &d.tex); - glBindTexture(GL_TEXTURE_2D, d.tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // convert red-on-black to RGBA - auto& g = face->glyph; - std::vector buf (g->bitmap.width * g->bitmap.rows, 0xFFFFFF); - for (auto j = buf.size(); j--;) - buf[j] |= g->bitmap.buffer[j] << 24; - - d.wh = { g->bitmap.width, g->bitmap.rows }; - d.bl = { g->bitmap_left, g->bitmap_top }; - d.ad = { g->advance.x >> 6, g->advance.y >> 6 }; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g->bitmap.width, g->bitmap.rows, - 0, GL_RGBA, GL_UNSIGNED_BYTE, buf.data()); ++ fontData.try_emplace(name); ++ ++ // Calculate dimensions of final texture ++ // ++ ++ float width = 0, height = 0; ++ for (int c = 32; c < 128; c++) { ++ FT_Load_Char(face, c, FT_LOAD_RENDER); ++ width += face->glyph->bitmap.width + 1; ++ height = std::max(height, static_cast(face->glyph->bitmap.rows)); + } + - std::cout << "Loaded font: " << file << " (size: " << size << ')' - << std::endl; ++ // Generate texture to hold entire font ++ // ++ ++ auto& font = fontData[name]; ++ glGenTextures(1, &font.tex); ++ glGenBuffers(1, &font.vbo); ++ glBindTexture(GL_TEXTURE_2D, font.tex); ++ glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, ++ 0, GL_RED, GL_UNSIGNED_BYTE, 0); ++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); ++ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ ++ // // convert red-on-black to RGBA ++ // auto& g = face->glyph; ++ // std::vector buf (g->bitmap.width * g->bitmap.rows, 0xFFFFFF); ++ // for (auto j = buf.size(); j--;) ++ // buf[j] |= g->bitmap.buffer[j] << 24; ++ ++ // Load each character and add it to the texture ++ // ++ ++ float offsetX = 0, offsetY = 0; ++ for (int c = 32; c < 128; c++) { ++ FT_Load_Char(face, c, FT_LOAD_RENDER); ++ ++ auto* g = face->glyph; ++ glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, ++ g->bitmap.width, g->bitmap.rows, ++ GL_RED, GL_UNSIGNED_BYTE, ++ g->bitmap.buffer); ++ ++ auto& d = font.data[c - 32]; ++ d.dim = { g->bitmap.width, g->bitmap.rows }; ++ d.bitmap = { g->bitmap_left, g->bitmap_top }; ++ d.advance = { g->advance.x >> 6, g->advance.y >> 6 }; ++ ++ d.offset = { offsetX / width, offsetY / height }; ++ offsetX += g->bitmap.width; ++ // Keep offsetY at zero? ++ } ++ ++ std::cout << "Loaded font: " << file << " (size: " << size << ", tex: " ++ << font.tex << ")" << std::endl; ++} ++ ++void TextSystem::updateVBOs(void) ++{ ++ for (auto& data : fontData) { ++ auto& d = data.second; ++ d.buffer.clear(); ++ for (auto& text : d.text) { ++ for (char c : text.text) { ++ if (c < 32) ++ continue; ++ ++ d.buffer += { ++ text.x, text.y, text.z, ++ d.data[c].offset.first, d.data[c].offset.second, ++ 1.0f ++ }; ++ } ++ } ++ ++ glBindBuffer(GL_ARRAY_BUFFER, d.vbo); ++ glBufferData(GL_ARRAY_BUFFER, ++ d.text.size() * sizeof(TextMeshData), d.text.data(), ++ GL_STREAM_DRAW); ++ } +} + diff --cc src/text.hpp index d7fb790,0000000..f456500 mode 100644,000000..100644 --- a/src/text.hpp +++ b/src/text.hpp @@@ -1,74 -1,0 +1,94 @@@ +/** + * @file text.hpp + * Manages entity text. + * + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SYSTEM_TEXT_HPP_ +#define SYSTEM_TEXT_HPP_ + +#include +#include +#include ++#include +#include + - +#include +#include +#include +#include + ++struct TextMeshData ++{ ++ float posX, posY, posZ; ++ float texX, texY; ++ float transparency; ++} __attribute__ ((packed)); ++ +struct FT_Info { - std::pair wh; - std::pair bl; - std::pair ad; - GLuint tex; ++ std::pair offset; ++ std::pair dim; ++ std::pair bitmap; ++ std::pair advance; ++}; + - FT_Info(void) - : tex(0) {} ++struct Text { ++ std::string text; ++ float x; ++ float y; ++ float z; ++}; ++ ++// Stores texture and placement data for a font at a size. ++struct Font { ++ GLuint tex; ++ GLuint vbo; ++ ++ std::array data; ++ // Stores currently shown text at given index into VBO? ++ std::vector text; ++ std::basic_string buffer; +}; + - /** - * @class PhysicsSystem - * Handles the position and velocity updating of all entities - */ +class TextSystem : public entityx::System +{ +public: + /** + * Prepares the system for running. + */ + void configure(entityx::EntityManager& entities, + entityx::EventManager& events) final; + + /** + * Draws the text for all entities. + */ + void update(entityx::EntityManager& entites, + entityx::EventManager& events, + entityx::TimeDelta dt) final; + + void loadFont(const std::string& name, const std::string& file, int size); + +private: + FT_Library freetype; + std::map fonts; - std::map> fontData; ++ std::map fontData; ++ ++ void updateVBOs(void); +}; + +#endif // SYSTEM_TEXT_HPP_ +