From 739a50138f4d4a0d24a96c04cdedd43b0a86d981 Mon Sep 17 00:00:00 2001 From: mrq Date: Sun, 3 Jun 2018 00:00:00 -0500 Subject: [PATCH] Commit for 2018.06.03.7z --- client/client/ext.cpp | 4 +- engine/inc/uf/gl/glyph/opengl.h | 21 ++- engine/inc/uf/utils/hook/hook.h | 67 ++-------- engine/src/gl/glyph/opengl.cpp | 158 +++++++++++++++++++++- engine/src/utils/hook/hook.cpp | 22 +++ ext/world/gui/gui.cpp | 200 ++++++++++++++++++++++++---- ext/world/light/light.cpp | 41 ++++-- ext/world/light/light.h | 5 +- ext/world/object/object.cpp | 2 +- ext/world/player/player.cpp | 229 +++++++++++++++++++++++++++----- ext/world/terrain/generator.cpp | 58 ++++---- ext/world/terrain/generator.h | 2 +- ext/world/terrain/region.cpp | 176 ++++++++++++------------ ext/world/terrain/terrain.cpp | 34 +++-- ext/world/world.cpp | 171 ++++++++++++++++-------- 15 files changed, 882 insertions(+), 308 deletions(-) diff --git a/client/client/ext.cpp b/client/client/ext.cpp index 1f359555..72e31585 100644 --- a/client/client/ext.cpp +++ b/client/client/ext.cpp @@ -83,7 +83,7 @@ void client::initialize() { client::window.setVisible(client::config["window"]["visible"].asBool()); client::window.setCursorVisible(client::config["cursor"]["visible"].asBool()); client::window.setKeyRepeatEnabled(client::config["keyboard"]["repeat"].asBool()); - client::window.centerWindow(); + // client::window.centerWindow(); client::window.setPosition({0, 0}); // client::window.setMouseGrabbed(true); @@ -159,7 +159,7 @@ void client::initialize() { } // Update viewport glViewport( 0, 0, size.x, size.y ); - client::window.centerWindow(); + // client::window.centerWindow(); return "true"; } ); diff --git a/engine/inc/uf/gl/glyph/opengl.h b/engine/inc/uf/gl/glyph/opengl.h index e7f28a65..3360f64e 100644 --- a/engine/inc/uf/gl/glyph/opengl.h +++ b/engine/inc/uf/gl/glyph/opengl.h @@ -15,9 +15,14 @@ namespace spec { namespace ogl { class UF_API GlyphTexture : public spec::ogl::Texture { protected: - pod::Vector2ui m_size; - pod::Vector2ui m_bearing; - pod::Vector2i m_advance; + pod::Vector2ui m_size = { 0, 0 }; + pod::Vector2ui m_bearing = { 0, 0 }; + pod::Vector2i m_advance = { 0, 0 }; + + pod::Vector2ui m_padding = { 0, 0 }; + + bool m_sdf = false; + int m_spread = 0; public: // OpenGL ops // void bind( uint ) const; @@ -25,14 +30,24 @@ namespace spec { void generate( ext::freetype::Glyph&, unsigned long, uint = 48 ); void generate( const std::string&, const uf::String&, uint = 48 ); void generate( ext::freetype::Glyph&, const uf::String&, uint = 48 ); + + void generateSdf( uint8_t* ); // Get const pod::Vector2ui& getSize() const; const pod::Vector2ui& getBearing() const; const pod::Vector2i& getAdvance() const; + const pod::Vector2ui& getPadding() const; + + bool isSdf() const; + int getSpread() const; // Set void setSize( const pod::Vector2ui& ); void setBearing( const pod::Vector2ui& ); void setAdvance( const pod::Vector2i& ); + void setPadding( const pod::Vector2ui& ); + + void useSdf( bool = true ); + void setSpread( int ); }; class UF_API GlyphMesh { protected: diff --git a/engine/inc/uf/utils/hook/hook.h b/engine/inc/uf/utils/hook/hook.h index f79bfa46..b293caf5 100644 --- a/engine/inc/uf/utils/hook/hook.h +++ b/engine/inc/uf/utils/hook/hook.h @@ -79,7 +79,7 @@ namespace uf { HookHandler(); std::size_t addHook( const Readable::name_t& name, const Readable::function_t& callback ); // Adds a hook that receives readable data - std::size_t addHook( const Optimal::name_t& name, const Optimal::function_t& callback ); // Adds a hook that receives optimal data + std::size_t addHook( const Optimal::name_t& name, const Optimal::function_t& callback ); // Adds a hook that receives optimal data void removeHook( const std::string&, std::size_t ); bool exists( const Readable::name_t& name ) const; // Is there a hook bound to a name in either lists? @@ -99,68 +99,17 @@ namespace uf { void call( const Readable::name_t& name, const Readable::argument_t& argument ); void call( const Optimal::name_t& name, const Optimal::argument_t& argument ); }; - -/* - class UF_API Hook { + class UF_API Hooks { public: - typedef std::string name_t; - - typedef int return_t; - typedef std::string argument_t; - - typedef std::function function_t; + typedef std::unordered_map> container_t; protected: - uf::Hook::name_t m_name; - uf::Hook::function_t m_function; + uf::Hooks::container_t m_container; public: - UF_API_CALL Hook( const uf::Hook::name_t& name, const uf::Hook::function_t& func ); - - const uf::Hook::name_t& UF_API_CALL getName() const; - const uf::Hook::function_t& UF_API_CALL getFunction() const; - - uf::Hook::return_t UF_API_CALL call( const uf::Hook::argument_t& arg ); + ~Hooks(); + void clear(); + std::size_t addHook( const uf::HookHandler::Readable::name_t& name, const uf::HookHandler::Readable::function_t& callback ); // Adds a hook that receives readable data + std::size_t addHook( const uf::HookHandler::Optimal::name_t& name, const uf::HookHandler::Optimal::function_t& callback ); // Adds a hook that receives optimal data }; - class UF_API HookAlias { - public: - typedef uf::Hook::name_t name_t; - typedef uf::Hook::argument_t argument_t; - protected: - uf::HookAlias::name_t m_name; - uf::HookAlias::name_t m_target; - uf::HookAlias::argument_t m_argument; - public: - UF_API_CALL HookAlias( const uf::HookAlias::name_t& name, const uf::HookAlias::name_t& target, const uf::HookAlias::argument_t& arg ); - const uf::HookAlias::name_t& UF_API_CALL getName() const; - const uf::HookAlias::name_t& UF_API_CALL getTarget() const; - const uf::HookAlias::argument_t& UF_API_CALL getArgument() const; - }; - class UF_API HookHandler { - public: - typedef std::vector vector_t; - typedef std::vector return_vector_t; - typedef std::unordered_map map_t; - - typedef std::vector alias_vector_t; - typedef std::unordered_map alias_map_t; - protected: - uf::HookHandler::map_t m_hooks; - uf::HookHandler::alias_map_t m_aliases; - public: - UF_API_CALL HookHandler(); - - void UF_API_CALL addHook( const uf::Hook::name_t& name, const uf::Hook::function_t& function ); - const uf::HookHandler::map_t& UF_API_CALL getHooks() const; - const uf::HookHandler::vector_t& UF_API_CALL getHooks( const uf::Hook::name_t& name ) const; - bool UF_API_CALL hookExists( const uf::Hook::name_t& name ) const; - - void UF_API_CALL addAlias( const uf::Hook::name_t& name, const uf::Hook::name_t& target, const uf::Hook::argument_t& arg = uf::Hook::argument_t() ); - const uf::HookHandler::alias_map_t& UF_API_CALL getAliases() const; - const uf::HookHandler::alias_vector_t& UF_API_CALL getAliases( const uf::Hook::name_t& name ) const; - bool UF_API_CALL aliasExists( const uf::Hook::name_t& name ) const; - - uf::HookHandler::return_vector_t UF_API_CALL call( const uf::Hook::name_t& name, const uf::Hook::argument_t& argument = uf::Hook::argument_t() ); - }; -*/ extern UF_API uf::HookHandler hooks; } \ No newline at end of file diff --git a/engine/src/gl/glyph/opengl.cpp b/engine/src/gl/glyph/opengl.cpp index ce78d658..163ad682 100644 --- a/engine/src/gl/glyph/opengl.cpp +++ b/engine/src/gl/glyph/opengl.cpp @@ -11,12 +11,45 @@ void spec::ogl::GlyphTexture::generate( ext::freetype::Glyph& glyph, unsigned lo if ( this->m_index ) this->destroy(); + this->m_sdf = false; this->setSize( { glyph.face->glyph->bitmap.width, glyph.face->glyph->bitmap.rows } ); this->setBearing( { glyph.face->glyph->bitmap_left, glyph.face->glyph->bitmap_top } ); this->setAdvance( {glyph.face->glyph->advance.x, glyph.face->glyph->advance.y} ); +// this->setPadding( {4, 4} ); GLuint type, format = GL_RED, internalFormat = GL_RED; type = GL_UNSIGNED_BYTE; + uint8_t* buffer = glyph.face->glyph->bitmap.buffer; + + bool cleanup = false; + pod::Vector2ui padding = this->getPadding(); + if ( padding.x > 0 && padding.y > 0 ) { cleanup = true; + uint8_t* bitmap = buffer; + uint8_t unheadache[this->m_size.x + padding.x * 2][this->m_size.y + padding.y * 2]; + buffer = new uint8_t[ ( this->m_size.x + padding.x * 2 ) * ( this->m_size.y + padding.y * 2 ) ]; + + // Zero out + for ( uint y = 0; y < this->m_size.y + padding.y * 2; ++y ) { + for ( uint x = 0; x < this->m_size.x + padding.x * 2; ++x ) { + unheadache[x][y] = 0; + } + } + // Fill + for ( uint y = 0; y < this->m_size.y; ++y ) { + for ( uint x = 0; x < this->m_size.x; ++x ) { + unheadache[x + padding.x][y + padding.y] = bitmap[y * this->m_size.x + x]; + } + } + // Migrate + this->setSize( pod::Vector2ui{ this->m_size.x + padding.x * 2, this->m_size.y + padding.y * 2 } ); + for ( uint y = 0; y < this->m_size.y; ++y ) { + for ( uint x = 0; x < this->m_size.x; ++x ) { + buffer[y * this->m_size.x + x] = unheadache[x][y]; + } + } + } + + if ( this->isSdf() ) this->generateSdf(buffer); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures( 1, &this->m_index ); @@ -31,12 +64,14 @@ void spec::ogl::GlyphTexture::generate( ext::freetype::Glyph& glyph, unsigned lo 0, format, type, - glyph.face->glyph->bitmap.buffer + buffer ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if ( cleanup ) delete[] buffer; } void spec::ogl::GlyphTexture::generate( const std::string& font, const uf::String& c, uint size ) { ext::freetype::Glyph glyph = ext::freetype::initialize(font); @@ -54,6 +89,9 @@ void spec::ogl::GlyphTexture::generate( ext::freetype::Glyph& glyph, const uf::S GLuint type, format = GL_RED, internalFormat = GL_RED; type = GL_UNSIGNED_BYTE; + uint8_t* buffer = glyph.face->glyph->bitmap.buffer; + + if ( this->isSdf() ) this->generateSdf(buffer); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures( 1, &this->m_index ); @@ -68,13 +106,111 @@ void spec::ogl::GlyphTexture::generate( ext::freetype::Glyph& glyph, const uf::S 0, format, type, - glyph.face->glyph->bitmap.buffer + buffer ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } +void spec::ogl::GlyphTexture::generateSdf( uint8_t* buffer ) { if ( !buffer ) return; + pod::Vector2ui size = this->getSize(); + this->m_sdf = true; + + int HEIGHT = size.y; int WIDTH = size.x; + struct Point { + int dx, dy; + int DistSq() const { return dx*dx + dy*dy; } + }; + struct Grid { + int w, h; + Point grid[128][128]; + /* + Point** grid; + Grid( int w, int h ) { this->w = w; this->h = h; this->grid = new Point*[h]; for (int y = 0; y < h; ++y ) this->grid[y] = new Point[w]; } + ~Grid() { std::cout << this->grid << std::endl; for ( int y = 0; y < this->w; ++y ) if ( this->grid[y] ) delete[] this->grid[y]; if ( this->grid ) delete[] this->grid; } + */ + }; + + Point inside = { 0, 0 }; + Point empty = { 9999, 9999 }; + Grid grid1; //( WIDTH, HEIGHT ); + Grid grid2; //( WIDTH, HEIGHT ); + + auto Get = [&]( Grid &g, int x, int y )->Point{ + return ( x >= 0 && y >= 0 && x < WIDTH && y < HEIGHT ) ? g.grid[y][x] : empty; + }; + auto Put = [&]( Grid &g, int x, int y, const Point &p )->void{ + g.grid[y][x] = p; + }; + auto Compare = [&]( Grid &g, Point &p, int x, int y, int offsetx, int offsety )->void{ + Point other = Get( g, x+offsetx, y+offsety ); + other.dx += offsetx; + other.dy += offsety; + if (other.DistSq() < p.DistSq()) p = other; + }; + auto GenerateSDF = [&]( Grid &g )->void{ + // Pass 0 + for (int y=0;y=0;x--) { + Point p = Get( g, x, y ); + Compare( g, p, x, y, 1, 0 ); + Put( g, x, y, p ); + } + } + // Pass 1 + for (int y=HEIGHT-1;y>=0;y--) { + for (int x=WIDTH-1;x>=0;x--) { + Point p = Get( g, x, y ); + Compare( g, p, x, y, 1, 0 ); + Compare( g, p, x, y, 0, 1 ); + Compare( g, p, x, y, -1, 1 ); + Compare( g, p, x, y, 1, 1 ); + Put( g, x, y, p ); + } + for (int x=0;xm_size.y; ++y ) { + for ( int x = 0; x < this->m_size.x; ++x ) { + int a = buffer[y * this->m_size.x + x]; + Put( grid1, x, y, a < 128 ? inside : empty ); + Put( grid2, x, y, a < 128 ? empty : inside ); + } + } + + GenerateSDF( grid1 ); + GenerateSDF( grid2 ); + + int lowest = 255; + int highest = 0; + for ( uint y = 0; y < this->m_size.y; ++y ) { + for ( uint x = 0; x < this->m_size.x; ++x ) { + int dist1 = (int)( sqrt( (double)Get( grid1, x, y ).DistSq() ) ); + int dist2 = (int)( sqrt( (double)Get( grid2, x, y ).DistSq() ) ); + int dist = dist1 - dist2; + + lowest = std::min( lowest, dist ); + highest = std::max( highest, dist ); + + buffer[y * this->m_size.x + x] = dist * this->getSpread() + 128; + } + } +} // Get const pod::Vector2ui& spec::ogl::GlyphTexture::getSize() const { return this->m_size; @@ -85,6 +221,15 @@ const pod::Vector2ui& spec::ogl::GlyphTexture::getBearing() const { const pod::Vector2i& spec::ogl::GlyphTexture::getAdvance() const { return this->m_advance; } +const pod::Vector2ui& spec::ogl::GlyphTexture::getPadding() const { + return this->m_padding; +} +int spec::ogl::GlyphTexture::getSpread() const { + return this->m_spread; +} +bool spec::ogl::GlyphTexture::isSdf() const { + return this->m_sdf; +} // Set void spec::ogl::GlyphTexture::setSize( const pod::Vector2ui& size ) { this->m_size = size; @@ -95,6 +240,15 @@ void spec::ogl::GlyphTexture::setBearing( const pod::Vector2ui& bearing ) { void spec::ogl::GlyphTexture::setAdvance( const pod::Vector2i& advance ) { this->m_advance = advance; } +void spec::ogl::GlyphTexture::setPadding( const pod::Vector2ui& padding ) { + this->m_padding = padding; +} +void spec::ogl::GlyphTexture::setSpread( int spread ) { + this->m_spread = spread; +} +void spec::ogl::GlyphTexture::useSdf( bool b ) { + this->m_sdf = b; +} // OpenGL ops void spec::ogl::GlyphMesh::generate() { diff --git a/engine/src/utils/hook/hook.cpp b/engine/src/utils/hook/hook.cpp index 781eb3cd..cec8f7a9 100644 --- a/engine/src/utils/hook/hook.cpp +++ b/engine/src/utils/hook/hook.cpp @@ -5,6 +5,28 @@ uf::HookHandler uf::hooks; namespace { std::size_t hooks = 0; } +uf::Hooks::~Hooks() { + this->clear(); +} + +std::size_t uf::Hooks::addHook( const uf::HookHandler::Readable::name_t& name, const uf::HookHandler::Readable::function_t& callback ) { + std::size_t id = uf::hooks.addHook( name, callback ); + this->m_container[name].push_back( id ); + return id; +} +std::size_t uf::Hooks::addHook( const uf::HookHandler::Optimal::name_t& name, const uf::HookHandler::Optimal::function_t& callback ) { + std::size_t id = uf::hooks.addHook( name, callback ); + this->m_container[name].push_back( id ); + return id; +} +void uf::Hooks::clear() { + for ( uf::Hooks::container_t::iterator it = this->m_container.begin(); it != this->m_container.end(); ++it ) { + const std::string& name = it->first; + const std::vector& vector = it->second; + for ( std::size_t id : vector ) uf::hooks.removeHook(name, id); + } + this->m_container.clear(); +} uf::HookHandler::HookHandler() : m_preferReadable(false) diff --git a/ext/world/gui/gui.cpp b/ext/world/gui/gui.cpp index d9089c29..c8dbe911 100644 --- a/ext/world/gui/gui.cpp +++ b/ext/world/gui/gui.cpp @@ -28,6 +28,13 @@ void ext::Gui::initialize() { if ( this->m_name == "Gui Manager" ) for ( uint i = 0; i < metadata["gui"]["list"].size(); ++i ) { std::string config = metadata["gui"]["list"][i].asString(); + /* Load entity file */ { + uf::Serializer json; + struct { bool exists = false; std::string filename; } file; + file.filename = "./entities/" + config; + /* Read from file */ if ( !(file.exists = json.readFromFile(file.filename)) ) { uf::iostream << "Error loading `" << file.filename << "!" << "\n"; continue; } + if ( json["ignore"].asBool() ) continue; + } uf::Entity* entity = new ext::Gui; ext::Gui& gui = *((ext::Gui*) entity); if ( !gui.load(config) ) { uf::iostream << "Error loading `" << config << "!" << "\n"; delete entity; continue; } @@ -35,6 +42,12 @@ void ext::Gui::initialize() { entity->initialize(); } else { + if ( metadata["gui"]["position"] != Json::nullValue ) { + pod::Transform<>& transform = this->getComponent>(); + transform.position.x = metadata["gui"]["position"][0].asDouble(); + transform.position.y = metadata["gui"]["position"][1].asDouble(); + transform.position.z = metadata["gui"]["position"][2].asDouble(); + } if ( metadata["gui"]["text"] != Json::nullValue ) { // First time initialization if ( ::glyphs.empty() ) { @@ -62,18 +75,15 @@ void ext::Gui::initialize() { std::cout << "Text: " << metadata["gui"]["text"] << std::endl; std::cout << uf::String( metadata["gui"]["text"].asString() ) << std::endl; - + + pod::Transform<>& transform = this->getComponent>(); + if ( metadata["gui"]["position"][0].asDouble() != metadata["gui"]["position"][0].asInt() ) transform.position.x = (int) (metadata["gui"]["position"][0].asDouble() * size.x); + if ( metadata["gui"]["position"][1].asDouble() != metadata["gui"]["position"][1].asInt() ) transform.position.y = (int) (metadata["gui"]["position"][1].asDouble() * size.y); } if ( metadata["gui"]["scale"] == Json::nullValue ) metadata["gui"]["scale"] = 1.0; } - if ( metadata["gui"]["position"] != Json::nullValue ) { - pod::Transform<>& transform = this->getComponent>(); - transform.position.x = metadata["gui"]["position"][0].asDouble(); - transform.position.y = metadata["gui"]["position"][1].asDouble(); - transform.position.z = metadata["gui"]["position"][2].asDouble(); - } metadata["gui"]["render"] = true; - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file) @@ -90,6 +100,13 @@ void ext::Gui::initialize() { transform.scale = pod::Vector3{ (double) texture.getImage().getDimensions().x / 1920, (double) texture.getImage().getDimensions().y / 1080, 1 }; } + // Relative scaling + if ( metadata["gui"]["text"] != Json::nullValue ) { + double t = 0; + if ( (t = metadata["gui"]["position"][0].asDouble()) != ((int) t) ) transform.position.x = (int) (t * size.x); + if ( (t = metadata["gui"]["position"][1].asDouble()) != ((int) t) ) transform.position.y = (int) (t * size.y); + } + ::matrix = uf::matrix::ortho( 0.0, (double) size.x, 0.0, (double) size.y ); ::size = size; @@ -113,18 +130,124 @@ void ext::Gui::render() { uf::Shader& shader = this->getComponent(); pod::Transform<>& transform = this->getComponent>(); - glDisable(GL_CULL_FACE); + // glDisable(GL_CULL_FACE); uf::String string( metadata["gui"]["text"].asString() ); - auto str = string.translate(); + auto str = string.translate(); // auto str = string.getString(); int X = 0; int Y = 0; uint biggest = 0; + + + // Find tallest glyph for new line for ( auto it = str.begin(); it != str.end(); ++it ) { unsigned long c = *it; if ( c == '\n' ) continue; uf::GlyphTexture& glyph = ::glyphs[c]; - if ( !glyph.generated() ) glyph.generate( ::glyph, c, metadata["gui"]["size"].asInt() ); + if ( !glyph.generated() ) { + glyph.setPadding( { metadata["gui"]["padding"][0].asUInt(), metadata["gui"]["padding"][1].asUInt() } ); + glyph.setSpread( metadata["gui"]["spread"].asUInt() ); + if ( metadata["gui"]["sdf"].asBool() ) glyph.useSdf(true); + glyph.generate( ::glyph, c, metadata["gui"]["size"].asInt() ); + } biggest = std::max( biggest, glyph.getSize().y); + } + // Set origin if ( metadata["gui"]["origin"] == "top" ) Y = ::size.y - transform.position.y - biggest; else Y += biggest; + + struct { + int X; int Y; + } old; old.X = X; old.Y = Y; + /* Render Shadow Box */ if ( metadata["gui"]["shadowbox"] != Json::nullValue && !metadata["gui"]["shadowbox"]["ignore"].asBool() ) { + std::vector sdim; + for ( auto it = str.begin(); it != str.end(); ++it ) { + unsigned long c = *it; if ( c == '\n' ) { + if ( metadata["gui"]["direction"] == "up" ) Y += biggest; else Y -= biggest; + X = 0; + continue; + } + uf::GlyphTexture& glyph = ::glyphs[c]; + struct { + float x, y, w, h; + } dim; + float scale = metadata["gui"]["scale"].asFloat(); + X += glyph.getPadding().x * scale; + dim.x = X + transform.position.x + glyph.getBearing().x * scale; + dim.w = glyph.getSize().x * scale; + if ( dim.x + dim.w >= ::size.x ) { + if ( metadata["gui"]["direction"] == "up" ) Y += biggest; else Y -= biggest; + dim.x -= X; X = 0; + } + dim.y = Y + transform.position.y - (glyph.getSize().y - glyph.getBearing().y) * scale; + dim.h = glyph.getSize().y * scale; + + X += (glyph.getAdvance().x >> 6) * scale; + Y += (glyph.getAdvance().y >> 6) * scale; + + X += glyph.getPadding().x * scale; + // Y += glyph.getPadding().y * scale; + + if ( sdim.empty() ) { + sdim = { + dim.x, dim.y, 1, 1, + dim.x, dim.y, 0, 1, + dim.x, dim.y, 0, 0, + + dim.x, dim.y, 1, 0, + dim.x, dim.y, 1, 1, + dim.x, dim.y, 0, 0, + }; + } + + sdim[4*0] = std::max( sdim[4*0], dim.x + dim.w ); + sdim[4*3] = std::max( sdim[4*3], dim.x + dim.w ); + sdim[4*4] = std::max( sdim[4*4], dim.x + dim.w ); + + sdim[1+4*2] = std::max( sdim[1+4*2], dim.y + dim.h ); + sdim[1+4*3] = std::max( sdim[1+4*3], dim.y + dim.h ); + sdim[1+4*5] = std::max( sdim[1+4*5], dim.y + dim.h ); + } + + if ( metadata["gui"]["shadowbox"]["padding"]["left"] != Json::nullValue ) { + float offset = metadata["gui"]["shadowbox"]["padding"]["left"].asDouble(); + if ( offset != (int) offset ) offset = (int) (offset * size.x); + sdim[4*1] -= offset; + sdim[4*2] -= offset; + sdim[4*5] -= offset; + } + if ( metadata["gui"]["shadowbox"]["padding"]["right"] != Json::nullValue ) { + float offset = metadata["gui"]["shadowbox"]["padding"]["right"].asDouble(); + if ( offset != (int) offset ) offset = (int) (offset * size.x); + sdim[4*0] += offset; + sdim[4*3] += offset; + sdim[4*4] += offset; + } + if ( metadata["gui"]["shadowbox"]["padding"]["top"] != Json::nullValue ) { + float offset = metadata["gui"]["shadowbox"]["padding"]["top"].asDouble(); + if ( offset != (int) offset ) offset = (int) (offset * size.y); + sdim[1+4*0] -= offset; + sdim[1+4*1] -= offset; + sdim[1+4*4] -= offset; + } + if ( metadata["gui"]["shadowbox"]["padding"]["bottom"] != Json::nullValue ) { + float offset = metadata["gui"]["shadowbox"]["padding"]["bottom"].asDouble(); + if ( offset != (int) offset ) offset = (int) (offset * size.y); + sdim[1+4*2] += offset; + sdim[1+4*3] += offset; + sdim[1+4*5] += offset; + } + + shader.bind(); { + shader.push("gui.shadowbox", true); + shader.push("gui.color", pod::Vector3{metadata["gui"]["shadowbox"]["color"][0].asFloat(), metadata["gui"]["shadowbox"]["color"][1].asFloat(), metadata["gui"]["shadowbox"]["color"][2].asFloat()}); + shader.push("matrices.model", ::matrix); + } + + ::mesh.getPoints().getVertices() = sdim; + ::mesh.generate(); + ::mesh.render(); + // Calculate shadow box bounds + } + X = old.X; Y = old.Y; + // Render Glyphs for ( auto it = str.begin(); it != str.end(); ++it ) { unsigned long c = *it; if ( c == '\n' ) { if ( metadata["gui"]["direction"] == "up" ) Y += biggest; else Y -= biggest; @@ -144,35 +267,58 @@ void ext::Gui::render() { } dim.y = Y + transform.position.y - (glyph.getSize().y - glyph.getBearing().y) * scale; dim.h = glyph.getSize().y * scale; - X += (glyph.getAdvance().x >> 6) * scale; Y += (glyph.getAdvance().y >> 6) * scale; + X += glyph.getPadding().x * scale; std::vector vertices = { - dim.x , dim.y + dim.h, 0, 0, + dim.x + dim.w, dim.y , 1, 1, dim.x , dim.y , 0, 1, - dim.x + dim.w, dim.y , 1, 1, - dim.x , dim.y + dim.h, 0, 0, - dim.x + dim.w, dim.y , 1, 1, + dim.x + dim.w, dim.y + dim.h, 1, 0, + dim.x + dim.w, dim.y , 1, 1, + dim.x , dim.y + dim.h, 0, 0, }; - - shader.bind(); { - int i = 0; - glyph.bind(i); - shader.push("gui.texture", i++); - shader.push("gui.color", pod::Vector3{metadata["gui"]["color"][0].asFloat(), metadata["gui"]["color"][1].asFloat(), metadata["gui"]["color"][2].asFloat()}); - shader.push("matrices.model", ::matrix); - } - ::mesh.getPoints().getVertices() = vertices; ::mesh.generate(); - ::mesh.render(); + if ( (metadata["gui"]["sdf"].asBool() && glyph.isSdf()) || (metadata["gui"]["sdf"] != Json::nullValue && glyph.isSdf()) ) { + /* Text */ { + shader.bind(); { + // if ( uf::Window::isKeyPressed("M") ) metadata["gui"]["weight"] = metadata["gui"]["weight"] = 0.01f * uf::physics::time::delta; + // if ( uf::Window::isKeyPressed("B") ) metadata["gui"]["weight"] = metadata["gui"]["weight"] = 0.01f * uf::physics::time::delta; + // if ( uf::Window::isKeyPressed("H") ) metadata["gui"]["scale"] = metadata["gui"]["scale"].asFloat() + 0.01f * uf::physics::time::delta; + // if ( uf::Window::isKeyPressed("N") ) metadata["gui"]["scale"] = metadata["gui"]["scale"].asFloat() - 0.01f * uf::physics::time::delta; + int i = 0; + glyph.bind(i); + shader.push("gui.texture", i++); + shader.push("gui.color", pod::Vector3{metadata["gui"]["color"][0].asFloat(), metadata["gui"]["color"][1].asFloat(), metadata["gui"]["color"][2].asFloat()}); + shader.push("gui.stroke", pod::Vector3{metadata["gui"]["stroke"][0].asFloat(), metadata["gui"]["stroke"][1].asFloat(), metadata["gui"]["stroke"][2].asFloat()}); + shader.push("gui.weight", metadata["gui"]["weight"].asFloat()); + shader.push("gui.spread", glyph.getSpread()); + shader.push("gui.scale", scale); + shader.push("gui.sdf", true); + shader.push("matrices.model", ::matrix); + } + ::mesh.render(); + } + } else { + shader.bind(); { + int i = 0; + glyph.bind(i); + shader.push("gui.texture", i++); + shader.push("gui.color", pod::Vector3{metadata["gui"]["color"][0].asFloat(), metadata["gui"]["color"][1].asFloat(), metadata["gui"]["color"][2].asFloat()}); + shader.push("gui.sdf", false); + shader.push("matrices.model", ::matrix); + } + ::mesh.render(); + } } - glEnable(GL_CULL_FACE); + X = old.X; Y = old.Y; + + // glEnable(GL_CULL_FACE); } else if ( this->hasComponent() ) { ext::Gui& parent = this->getParent(); diff --git a/ext/world/light/light.cpp b/ext/world/light/light.cpp index 280ab887..0f3bc8b4 100644 --- a/ext/world/light/light.cpp +++ b/ext/world/light/light.cpp @@ -7,7 +7,7 @@ #include #include #include "../world.h" - +/* const pod::Vector3& ext::Light::getColor() const { return this->m_color; } @@ -32,7 +32,7 @@ float ext::Light::getPower() const { void ext::Light::setPower( float power ) { this->m_power = power; } - +*/ void ext::Light::initialize() { ext::Object::initialize(); @@ -58,6 +58,9 @@ void ext::Light::initialize() { uf::Serializer& metadata = this->getComponent(); uf::Camera& camera = this->getComponent(); + if ( metadata["light"]["camera"] != Json::nullValue && metadata["camera"] == Json::nullValue ) + metadata["camera"] = metadata["light"]["camera"]; + settings.mode = metadata["camera"]["ortho"].asBool() ? -1 : 1; settings.perspective.size.x = metadata["camera"]["settings"]["size"]["x"].asDouble(); settings.perspective.size.y = metadata["camera"]["settings"]["size"]["y"].asDouble(); @@ -95,14 +98,33 @@ void ext::Light::initialize() { camera.update(true); metadata["light"]["state"] = 0; + metadata["light"]["render"] = true; - /* Attenuation */ { + if ( metadata["light"]["attenuation"] == Json::nullValue ) metadata["light"]["attenuation"] = 0.00125f; + if ( metadata["light"]["power"] == Json::nullValue ) metadata["light"]["power"] = 100.0f; + if ( metadata["light"]["specular"] == Json::nullValue ) { + metadata["light"]["specular"][0] = 1; + metadata["light"]["specular"][1] = 1; + metadata["light"]["specular"][2] = 1; + } + if ( metadata["light"]["color"] == Json::nullValue ) { + metadata["light"]["color"][0] = 1; + metadata["light"]["color"][1] = 1; + metadata["light"]["color"][2] = 1; + } + + /* + pod::Vector3 m_color = {1, 1, 1}; + pod::Vector3 m_specular = {1, 1, 1}; + float m_attenuation = 0.00125f; + float m_power = 100.0f; + + { + // Attenuation if ( metadata["light"]["attenuation"] != Json::nullValue ) this->setAttenuation( metadata["light"]["attenuation"].asFloat() ); - } - /* Power */ { + // Power if ( metadata["light"]["power"] != Json::nullValue ) this->setPower(metadata["light"]["power"].asFloat() ); - } - /* Specular */ { + // Specular if ( metadata["light"]["specular"] != Json::nullValue ) { pod::Vector3 specular; specular.x = metadata["light"]["specular"][0].asDouble(); @@ -111,11 +133,12 @@ void ext::Light::initialize() { this->setSpecular(specular); } } + */ if ( metadata["light"]["dedicated"].asBool() ) { uf::GeometryBuffer& buffer = this->getComponent(); { if ( metadata["camera"]["settings"]["size"]["auto"].asBool() ) { - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file) @@ -152,7 +175,7 @@ void ext::Light::initialize() { } } if ( metadata["camera"]["settings"]["size"]["auto"].asBool() ) { - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file) diff --git a/ext/world/light/light.h b/ext/world/light/light.h index 1c16dbfd..75529aba 100644 --- a/ext/world/light/light.h +++ b/ext/world/light/light.h @@ -16,16 +16,18 @@ namespace ext { class EXT_API Light : public ext::Object { protected: +/* pod::Vector3 m_color = {1, 1, 1}; pod::Vector3 m_specular = {1, 1, 1}; float m_attenuation = 0.00125f; float m_power = 100.0f; +*/ uint m_state = 0; public: void initialize(); void tick(); void render(); - +/* void setColor( const pod::Vector3& ); const pod::Vector3& getColor() const; @@ -37,5 +39,6 @@ namespace ext { void setPower( float ); float getPower() const; +*/ }; } \ No newline at end of file diff --git a/ext/world/object/object.cpp b/ext/world/object/object.cpp index 6c2beff7..262eca5f 100644 --- a/ext/world/object/object.cpp +++ b/ext/world/object/object.cpp @@ -67,7 +67,7 @@ void ext::Object::render() { std::string name = "bones_" + std::to_string(bone.index); shader.push(name, bone.matrix); } - shader.push("debug", uf::Window::isKeyPressed("RControl")); + // shader.push("debug", uf::Window::isKeyPressed("RControl")); } } mesh.render(); diff --git a/ext/world/player/player.cpp b/ext/world/player/player.cpp index b3f5ac45..9e0d393e 100644 --- a/ext/world/player/player.cpp +++ b/ext/world/player/player.cpp @@ -9,12 +9,30 @@ #include #include "../gui/gui.h" +#include "../light/light.h" #include "../world.h" namespace { bool lockMouse = true; bool croutching = false; + + std::function findByName = [&]( uf::Entity* parent, const std::string& name ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getName() == name ) return entity; + uf::Entity* p = findByName(entity, name); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; + std::function findByUid = [&]( uf::Entity* parent, uint id ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getUid() == id ) return entity; + uf::Entity* p = findByUid(entity, id); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; } void ext::Player::initialize() { @@ -80,7 +98,7 @@ void ext::Player::initialize() { // Update viewport if ( metadata["camera"]["settings"]["size"]["auto"].asBool() ) { - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file) @@ -99,7 +117,7 @@ void ext::Player::initialize() { } // Rotate Camera - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Mouse.Moved", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Mouse.Moved", [&](const std::string& event)->std::string{ static bool ignoreNext = false; if ( ignoreNext ) { ignoreNext = false; return "true"; } uf::Serializer json = event; @@ -151,7 +169,7 @@ void ext::Player::initialize() { return "true"; }); // Rotate model - metadata["hooks"]["window:Resized"][metadata["hooks"].size()] = uf::hooks.addHook( "window:Mouse.Moved", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Mouse.Moved", [&](const std::string& event)->std::string{ static bool ignoreNext = false; if ( ignoreNext ) { ignoreNext = false; return "true"; } uf::Serializer json = event; @@ -207,7 +225,47 @@ void ext::Player::initialize() { } return "true"; }); + + // Player Light + if ( metadata["light"]["should"].asBool() ) { + pod::Vector3 color = { 1, 1, 1 }; + int radius = 3; + for ( int i = 0; i < radius; ++i ) { + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } + this->addChild(*entity); + + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"] = metadata["light"]; + + entity->initialize(); + + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& transform = entity->getComponent>();//entity->getComponent().getTransform(); + transform = uf::transform::initialize( transform ); + uf::transform::rotate( transform, transform.up, (360.0 / radius) * (3.1415926/180.0) * i ); + entity->getComponent().update(true); + } + /* down */ { + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } + this->addChild(*entity); + + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"] = metadata["light"]; + + entity->initialize(); + + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& transform = entity->getComponent>();//entity->getComponent().getTransform(); + transform = uf::transform::initialize( transform ); + uf::transform::rotate( transform, transform.right, 1.5708 * 1 ); + entity->getComponent().setFov(120); + entity->getComponent().update(true); + } + } } +#include void ext::Player::tick() { bool updateCamera = true; bool deltaCrouch = false; @@ -218,44 +276,133 @@ void ext::Player::tick() { float limitSquared = 4*4; } speed; + struct { + bool running; + bool light; + } keys = { + .running = uf::Window::isKeyPressed("LShift"), + .light = uf::Window::isKeyPressed("F"), + }; + uf::Camera& camera = this->getComponent(); pod::Transform<>& transform = this->getComponent>(); pod::Physics& physics = this->getComponent(); uf::Serializer& serializer = this->getComponent(); - camera.update(true); - - if (uf::Window::isKeyPressed("LShift")) speed.move = 8; + if (keys.running) speed.move = 8; speed.limitSquared = speed.move * speed.move; + /* Update light positions */ if ( this->getComponent()["light"]["should"].asBool() ) { + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& camera = this->getComponent().getTransform(); + + uf::Serializer& metadata = this->getComponent(); + // if ( metadata["light"]["battery"] == Json::nullValue ) { + if ( metadata["light"]["battery"]["level"] == Json::nullValue ) metadata["light"]["battery"]["level"] = 1.0; + if ( metadata["light"]["battery"]["rate"] == Json::nullValue ) metadata["light"]["battery"]["rate"] = 0.1; + if ( metadata["light"]["battery"]["depleted"] == Json::nullValue ) metadata["light"]["battery"]["depleted"] = false; + if ( metadata["light"]["battery"]["attenuation"]["from"] == Json::nullValue ) metadata["light"]["battery"]["attenuation"]["from"] = 0.05; + if ( metadata["light"]["battery"]["attenuation"]["to"] == Json::nullValue ) metadata["light"]["battery"]["attenuation"]["to"] = 0.0005; + // } + struct { + float level; + float rate; + bool depleted; + float from; + float to; + } battery = { + .level = metadata["light"]["battery"]["level"].asFloat(), + .rate = metadata["light"]["battery"]["rate"].asFloat(), + .depleted = metadata["light"]["battery"]["depleted"].asBool(), + }; + + /* Calculate ""battery"" */ { + if ( battery.level < 0 ) { + battery.depleted = true; + } + if ( keys.light && !battery.depleted ) { + battery.level -= battery.rate * uf::physics::time::delta; + } else if ( battery.level < 1 ) { + battery.level += battery.rate * uf::physics::time::delta; + if ( battery.level >= 1 ) { + battery.level = 1; + battery.depleted = false; + } + } + metadata["light"]["battery"]["level"] = battery.level; + metadata["light"]["battery"]["rate"] = battery.rate; + metadata["light"]["battery"]["depleted"] = battery.depleted; + } + /* Light Element */ { + uf::Serializer& metadata = this->getComponent(); + uint uid = metadata["gui"]["Battery Element"].asUInt(); + uf::Entity& parent = this->getRootParent(); + ext::Gui* gui = (ext::Gui*) ::findByName(&parent, "Gui Manager"); + uf::Entity* element = ::findByUid(gui, uid); + if ( keys.light ) { + if ( !element ) { + std::string config = "./gui/text/config.json"; + element = new ext::Gui; + ext::Gui& guiElement = *((ext::Gui*) element); + if ( !guiElement.load(config) ) { uf::iostream << "Error loading `" << config << "!" << "\n"; delete element; } + else { + gui->addChild(*element); + uf::Serializer& gMetadata = element->getComponent(); + gMetadata["type"] = "Battery Element"; + gMetadata["gui"]["text"] = "Battery: ?%"; + gMetadata["gui"]["position"][0] = 0.02; + gMetadata["gui"]["position"][1] = 0.8; + gMetadata["gui"]["origin"] = "bottom"; + gMetadata["gui"]["direction"] = "up"; + element->initialize(); + metadata["gui"]["Battery Element"] = element->getUid(); + } + } else { + std::string string = "?"; { + std::stringstream sstream; sstream.precision(0); + sstream << std::fixed << battery.level * 100; + string = sstream.str(); + } + uf::Serializer& gMetadata = element->getComponent(); + gMetadata["gui"]["render"] = true; + gMetadata["gui"]["text"] = "Battery: " + string + "%"; + } + } else { + if ( element ) { + uf::Serializer& gMetadata = element->getComponent(); + gMetadata["gui"]["render"] = false; + } + } + } + for ( uf::Entity* entity : this->getChildren() ) { if ( entity->getName() != "Light" ) continue; + pod::Transform<>& transform = entity->getComponent>(); + transform.position = parent.position + camera.position + pod::Vector3{0, 1, 0}; + + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"]["render"] = battery.depleted ? false : keys.light; + /* + lMetadata["light"]["color"][0] = battery; + lMetadata["light"]["color"][1] = battery; + lMetadata["light"]["color"][2] = battery; + */ + float atten = 0.05; { + atten = uf::vector::lerp( pod::Vector1{ battery.from }, pod::Vector1{ battery.to }, battery.level ).x; + } + lMetadata["light"]["attenuation"] = atten; + } + } + /* Running Element */ { - std::function findByName = [&]( uf::Entity* parent, const std::string& name ) { - for ( uf::Entity* entity : parent->getChildren() ) { - if ( entity->getName() == name ) return entity; - uf::Entity* p = findByName(entity, name); - if ( p ) return p; - } - return (uf::Entity*) NULL; - }; - std::function findByUid = [&]( uf::Entity* parent, uint id ) { - for ( uf::Entity* entity : parent->getChildren() ) { - if ( entity->getUid() == id ) return entity; - uf::Entity* p = findByUid(entity, id); - if ( p ) return p; - } - return (uf::Entity*) NULL; - }; - uf::Serializer& metadata = this->getComponent(); uint uid = metadata["gui"]["Sprinting Element"].asUInt(); uf::Entity& parent = this->getRootParent(); - ext::Gui* gui = (ext::Gui*) findByName(&parent, "Gui Manager"); - uf::Entity* element = findByUid(gui, uid); + ext::Gui* gui = (ext::Gui*) ::findByName(&parent, "Gui Manager"); + uf::Entity* element = ::findByUid(gui, uid); - if ( uf::Window::isKeyPressed("LShift") ) { + if ( keys.running ) { if ( !element ) { - std::string config = "./text/config.json"; + std::string config = "./gui/text/config.json"; element = new ext::Gui; ext::Gui& guiElement = *((ext::Gui*) element); if ( !guiElement.load(config) ) { uf::iostream << "Error loading `" << config << "!" << "\n"; delete element; } @@ -264,14 +411,24 @@ void ext::Player::tick() { uf::Serializer& gMetadata = element->getComponent(); - gMetadata["type"] = "Running Element"; - gMetadata["gui"]["text"] = "Sprinting"; - gMetadata["gui"]["position"][0] = 0; - gMetadata["gui"]["position"][1] = 0; - gMetadata["gui"]["origin"] = "top"; - gMetadata["gui"]["direction"] = "down"; - gMetadata["gui"]["size"] = 18; - + gMetadata["type"] = "Sprinting Element"; + gMetadata["gui"]["text"] = "Sprint"; + gMetadata["gui"]["position"][0] = 0.02; + gMetadata["gui"]["position"][1] = 0.02; + gMetadata["gui"]["origin"] = "bottom"; + gMetadata["gui"]["direction"] = "up"; + /* + gMetadata["gui"]["size"] = 32; + gMetadata["gui"]["scale"] = 1.5; + gMetadata["gui"]["shadowbox"]["color"][0] = 0.05; + gMetadata["gui"]["shadowbox"]["color"][1] = 0.05; + gMetadata["gui"]["shadowbox"]["color"][2] = 0.05; + gMetadata["gui"]["shadowbox"]["padding"]["left"] = 5; + gMetadata["gui"]["shadowbox"]["padding"]["right"] = 5; + gMetadata["gui"]["shadowbox"]["padding"]["bottom"] = 5; + gMetadata["gui"]["shadowbox"]["padding"]["top"] = 5; + gMetadata["gui"]["shadowbox"]["ignore"] = true; + */ element->initialize(); metadata["gui"]["Sprinting Element"] = element->getUid(); @@ -412,6 +569,8 @@ void ext::Player::tick() { } } + camera.update(true); + ext::Craeture::tick(); } void ext::Player::render() { diff --git a/ext/world/terrain/generator.cpp b/ext/world/terrain/generator.cpp index bc8681ee..c67b7b3e 100644 --- a/ext/world/terrain/generator.cpp +++ b/ext/world/terrain/generator.cpp @@ -26,28 +26,30 @@ void ext::TerrainGenerator::destroy(){ if ( !this->m_voxels ) return; delete[] this->m_voxels; this->m_voxels = NULL; } -void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; +void ext::TerrainGenerator::generate( ext::Region& region ){ if ( this->m_voxels ) return; /* - struct { - ext::TerrainVoxel::uid_t floor = ext::TerrainVoxelFloor().uid(); - ext::TerrainVoxel::uid_t wall = ext::TerrainVoxelWall().uid(); - ext::TerrainVoxel::uid_t ceiling = ext::TerrainVoxelCeiling().uid(); - } atlas; - this->m_voxels = new ext::TerrainVoxel::uid_t**[this->m_size.x]; - for ( uint x = 0; x < this->m_size.x; ++x ) { this->m_voxels[x] = new ext::TerrainVoxel::uid_t*[this->m_size.y]; - for ( uint y = 0; y < this->m_size.y; ++y ) { this->m_voxels[x][y] = new ext::TerrainVoxel::uid_t[this->m_size.z]; - for ( uint z = 0; z < this->m_size.z; ++z ) { ext::TerrainVoxel::uid_t voxel = 0; - if ( x == 0 ) voxel = atlas.wall; if ( x == this->m_size.x - 1 ) voxel = atlas.wall; - if ( z == 0 ) voxel = atlas.wall; if ( z == this->m_size.z - 1 ) voxel = atlas.wall; + { + struct { + ext::TerrainVoxel::uid_t floor = ext::TerrainVoxelFloor().uid(); + ext::TerrainVoxel::uid_t wall = ext::TerrainVoxelWall().uid(); + ext::TerrainVoxel::uid_t ceiling = ext::TerrainVoxelCeiling().uid(); + } atlas; + this->m_voxels = new ext::TerrainVoxel::uid_t**[this->m_size.x]; + for ( uint x = 0; x < this->m_size.x; ++x ) { this->m_voxels[x] = new ext::TerrainVoxel::uid_t*[this->m_size.y]; + for ( uint y = 0; y < this->m_size.y; ++y ) { this->m_voxels[x][y] = new ext::TerrainVoxel::uid_t[this->m_size.z]; + for ( uint z = 0; z < this->m_size.z; ++z ) { ext::TerrainVoxel::uid_t voxel = 0; + if ( x == 0 ) voxel = atlas.wall; if ( x == this->m_size.x - 1 ) voxel = atlas.wall; + if ( z == 0 ) voxel = atlas.wall; if ( z == this->m_size.z - 1 ) voxel = atlas.wall; - if ( y == 0 ) voxel = atlas.floor; if ( y == this->m_size.y - 1 ) voxel = atlas.ceiling; + if ( y == 0 ) voxel = atlas.floor; if ( y == this->m_size.y - 1 ) voxel = atlas.ceiling; - if ( y > 0 && y < this->m_size.y - 1 ) { - if ( x > 4 && x < this->m_size.x - 4 ) voxel = 0; - if ( z > 4 && z < this->m_size.z - 4 ) voxel = 0; + if ( y > 0 && y < this->m_size.y - 1 ) { + if ( x > 4 && x < this->m_size.x - 4 ) voxel = 0; + if ( z > 4 && z < this->m_size.z - 4 ) voxel = 0; + } + + this->m_voxels[x][y][z] = voxel; } - - this->m_voxels[x][y][z] = voxel; } } } @@ -59,6 +61,13 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; uint half_y = this->m_size.y / 2; uint half_z = this->m_size.z / 2; + const pod::Transform<>& transform = region.getComponent>(); + const pod::Vector3i location = { + transform.position.x / this->m_size.x, + transform.position.y / this->m_size.y, + transform.position.z / this->m_size.z, + }; + struct { ext::TerrainVoxel::uid_t floor = ext::TerrainVoxelFloor().uid();// = uf::World::atlas.getFromString("Regular Floor").getUid(); ext::TerrainVoxel::uid_t wall = ext::TerrainVoxelWall().uid();// = uf::World::atlas.getFromString("Regular Wall").getUid(); @@ -73,8 +82,9 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; for ( uint z = 0; z < this->m_size.z; ++z ) this->m_voxels[x][y][z] = 0; } } - if ( true ) { + if ( location.y <= 0 ) { int roomType = rand() % 6; + if ( location.y == 0 ) roomType = rand() % 2; static bool first = false; if ( !first ) roomType = 0, first = true; for ( uint x = 0; x < this->m_size.x; x++ ) { @@ -89,7 +99,6 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; // Floor if ( y == 0 ) this->m_voxels[x][y][z] = atlas.floor; // Ceiling - if ( y + 1 == this->m_size.y ) this->m_voxels[x][y][z] = rand() % 10 < 8.0f ? 0 : atlas.ceiling; } } } @@ -99,6 +108,9 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; case 0: break; // Typical Room default: + for ( uint x = 0; x < this->m_size.x; x++ ) + for ( uint y = 0; y < this->m_size.y; y++ ) + for ( uint z = 0; z < this->m_size.z; z++ ) if ( y + 1 == this->m_size.y ) this->m_voxels[x][y][z] = rand() % 10 < 8.0f ? 0 : atlas.ceiling; // North for ( uint y = 0; y < this->m_size.y; y++ ) { for ( uint x = 0; x < this->m_size.x; x++ ) { @@ -136,7 +148,7 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; } // Default Room // Hole room - case 2: + case 1: for ( uint x = half_x - (half_x / 2); x < half_x + (half_x / 2) + 1; x++ ) for ( uint z = half_z - (half_z / 2); z < half_z + (half_z / 2) + 1; z++ ) if ( rand() % 10 > 1.25f ) this->m_voxels[x][0][z] = 0; @@ -149,7 +161,7 @@ void ext::TerrainGenerator::generate(){ if ( this->m_voxels ) return; if ( rand() % 10 > 1.25f ) this->m_voxels[x][y][z] = atlas.pillar; break; // Stair room - case -4: + case 4: int randed_direction = rand() % 2; int start_x = std::max(half_x - 3, (uint) 0); int stop_x = std::min(half_x + 5, this->m_size.x); @@ -206,7 +218,7 @@ ext::TerrainVoxel::uid_t*** ext::TerrainGenerator::getVoxels() { return this->m_voxels; } void ext::TerrainGenerator::rasterize( uf::Mesh& mesh, const ext::Region& region, bool isolated, bool modelMatrixed ){ - if ( !this->m_voxels ) this->generate(); + if ( !this->m_voxels ) return; std::vector& position = mesh.getPositions().getVertices(); std::vector& uv = mesh.getUvs().getVertices(); diff --git a/ext/world/terrain/generator.h b/ext/world/terrain/generator.h index 7567dad1..7bdfedfc 100644 --- a/ext/world/terrain/generator.h +++ b/ext/world/terrain/generator.h @@ -19,7 +19,7 @@ namespace ext { void initialize( const pod::Vector3ui& = { 8, 8, 8 } ); void destroy(); - void generate(); + void generate( ext::Region& ); void rasterize( uf::Mesh&, const ext::Region&, bool = true, bool = true ); ext::TerrainVoxel::uid_t*** getVoxels(); }; diff --git a/ext/world/terrain/region.cpp b/ext/world/terrain/region.cpp index 860593dc..1b821c42 100644 --- a/ext/world/terrain/region.cpp +++ b/ext/world/terrain/region.cpp @@ -36,89 +36,8 @@ void ext::Region::load() { metadata["region"]["rasterized"] = false; } - float r = (rand() % 100) / 100.0; - bool addLight = r < metadata["region"]["light"]["random"].asFloat(); - static bool first = false; if ( !first ) { - addLight = (first = true); - } - // Guarantee at least one light source (per XZ plane) - if ( !addLight ) { addLight = true; - ext::Terrain& parent = this->getParent(); - for ( const uf::Entity* pRegion : parent.getChildren() ) if ( pRegion->getName() == "Region" ) { - const pod::Transform<>& tRegion = pRegion->getComponent>(); - const pod::Transform<>& transform = this->getComponent>(); - if ( tRegion.position.y != transform.position.y ) continue; - for ( const uf::Entity* pLight : pRegion->getChildren() ) if ( pLight->getName() == "Light" ) { - addLight = false; - break; - } - if ( !addLight ) break; - } - } - - if ( addLight ) { - pod::Vector3 color = { 1.0, 1.0, 1.0 }; { - float r = (rand() % 256) / 256.0; color.x -= r; - float g = (rand() % 256) / 256.0; color.y -= g; - float b = (rand() % 256) / 256.0; color.z -= b; - - color = uf::vector::normalize( color ); - } - int radius = metadata["region"]["light"]["radius"].asInt(); - /* Up */ if ( metadata["region"]["light"]["up"].asBool() ) { - uf::Entity* entity = new ext::Light; - if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } - this->addChild(*entity); - entity->initialize(); - - pod::Transform<>& parent = this->getComponent>(); - pod::Transform<>& transform = entity->getComponent>(); - entity->getComponent().getTransform().reference = &transform; - - transform = uf::transform::initialize( transform ); - transform.position = parent.position; - uf::transform::rotate( transform, transform.right, 1.5708 * 1 ); - entity->getComponent().setFov(120); - entity->getComponent().update(true); - ((ext::Light*)entity)->setColor( color ); - } - /* Down */ if ( metadata["region"]["light"]["down"].asBool() ) { - uf::Entity* entity = new ext::Light; - if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } - this->addChild(*entity); - entity->initialize(); - - pod::Transform<>& parent = this->getComponent>(); - pod::Transform<>& transform = entity->getComponent>(); - entity->getComponent().getTransform().reference = &transform; - - transform = uf::transform::initialize( transform ); - transform.position = parent.position; - uf::transform::rotate( transform, transform.right, 1.5708 * 3 ); - entity->getComponent().setFov(120); - entity->getComponent().update(true); - ((ext::Light*)entity)->setColor( color ); - } - for ( int i = 0; i < radius; ++i ) { - uf::Entity* entity = new ext::Light; - if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } - this->addChild(*entity); - entity->initialize(); - - pod::Transform<>& parent = this->getComponent>(); - pod::Transform<>& transform = entity->getComponent>();//entity->getComponent().getTransform(); - entity->getComponent().getTransform().reference = &transform; - - transform = uf::transform::initialize( transform ); - transform.position = parent.position; - uf::transform::rotate( transform, transform.up, (360.0 / radius) * (3.1415926/180.0) * i ); - entity->getComponent().update(true); - ((ext::Light*)entity)->setColor( color ); - } - } - generator.initialize(size); - generator.generate(); + generator.generate(*this); /* Collider */ { pod::Transform<>& transform = this->getComponent>(); @@ -143,7 +62,98 @@ void ext::Region::load() { } } -// generator.rasterize(mesh, *this); + if ( this->getComponent>().position.y < 0 ) { + float r = (rand() % 100) / 100.0; + bool addLight = r < metadata["region"]["light"]["random"].asFloat(); + static bool first = false; if ( !first ) addLight = first = true; + // Guarantee at least one light source (per XZ plane) + if ( false && !addLight ) { addLight = true; + ext::Terrain& parent = this->getParent(); + for ( const uf::Entity* pRegion : parent.getChildren() ) if ( pRegion->getName() == "Region" ) { + const pod::Transform<>& tRegion = pRegion->getComponent>(); + const pod::Transform<>& transform = this->getComponent>(); + if ( tRegion.position.y != transform.position.y ) continue; + for ( const uf::Entity* pLight : pRegion->getChildren() ) if ( pLight->getName() == "Light" ) { + addLight = false; + break; + } + if ( !addLight ) break; + } + } + + if ( addLight ) { + pod::Vector3 color = { 1.0, 1.0, 1.0 }; { + float r = (rand() % 256) / 256.0; color.x -= r; + float g = (rand() % 256) / 256.0; color.y -= g; + float b = (rand() % 256) / 256.0; color.z -= b; + + color = uf::vector::normalize( color ); + } + int radius = metadata["region"]["light"]["radius"].asInt(); + for ( int i = 0; i < radius; ++i ) { + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } + this->addChild(*entity); + entity->initialize(); + + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& transform = entity->getComponent>();//entity->getComponent().getTransform(); + entity->getComponent().getTransform().reference = &transform; + + transform = uf::transform::initialize( transform ); + transform.position = parent.position; + uf::transform::rotate( transform, transform.up, (360.0 / radius) * (3.1415926/180.0) * i ); + entity->getComponent().update(true); + // ((ext::Light*)entity)->setColor( color ); + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"]["color"][0] = color.x; + lMetadata["light"]["color"][1] = color.y; + lMetadata["light"]["color"][2] = color.z; + } + /* Down */ if ( metadata["region"]["light"]["down"].asBool() ) { + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } + this->addChild(*entity); + entity->initialize(); + + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& transform = entity->getComponent>(); + entity->getComponent().getTransform().reference = &transform; + + transform = uf::transform::initialize( transform ); + transform.position = parent.position; + uf::transform::rotate( transform, transform.right, 1.5708 * 1 ); + entity->getComponent().setFov(120); + entity->getComponent().update(true); + // ((ext::Light*)entity)->setColor( color ); + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"]["color"][0] = color.x; + lMetadata["light"]["color"][1] = color.y; + lMetadata["light"]["color"][2] = color.z; + } + /* Up */ if ( metadata["region"]["light"]["up"].asBool() ) { + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return; } + this->addChild(*entity); + entity->initialize(); + + pod::Transform<>& parent = this->getComponent>(); + pod::Transform<>& transform = entity->getComponent>(); + entity->getComponent().getTransform().reference = &transform; + + transform = uf::transform::initialize( transform ); + transform.position = parent.position; + uf::transform::rotate( transform, transform.right, 1.5708 * 3 ); + entity->getComponent().setFov(120); + entity->getComponent().update(true); + // ((ext::Light*)entity)->setColor( color ); + uf::Serializer& lMetadata = entity->getComponent(); + lMetadata["light"]["color"][0] = color.x; + lMetadata["light"]["color"][1] = color.y; + lMetadata["light"]["color"][2] = color.z; + } + } + } } void ext::Region::render() { if ( !this->m_parent ) return; diff --git a/ext/world/terrain/terrain.cpp b/ext/world/terrain/terrain.cpp index f915aa01..fea97b1e 100644 --- a/ext/world/terrain/terrain.cpp +++ b/ext/world/terrain/terrain.cpp @@ -4,8 +4,29 @@ #include "generator.h" #include "region.h" +#include "../light/light.h" +#include "../gui/gui.h" + #include +namespace { + std::function findByName = [&]( uf::Entity* parent, const std::string& name ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getName() == name ) return entity; + uf::Entity* p = findByName(entity, name); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; + std::function findByUid = [&]( uf::Entity* parent, uint id ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getUid() == id ) return entity; + uf::Entity* p = findByUid(entity, id); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; +} void ext::Terrain::initialize() { ext::Object::initialize(); @@ -30,7 +51,7 @@ void ext::Terrain::tick() { uf::Serializer& metadata = this->getComponent(); /* Debug Information */ { - /* Terrain Metadata */ { + /* Terrain Metadata */ if ( false ) { static uf::Timer timer(false); if ( !timer.running() ) timer.start(); if ( uf::Window::isKeyPressed("L") && timer.elapsed().asDouble() >= 1 ) { timer.reset(); @@ -42,20 +63,14 @@ void ext::Terrain::tick() { if ( !timer.running() ) timer.start(); if ( uf::Window::isKeyPressed("G") && timer.elapsed().asDouble() >= 1 ) { timer.reset(); std::cout << "Regenerating "; - uint i = 0; /* Retrieve changed regions */ for ( uf::Entity* kv : this->m_children ) { if ( !kv ) continue; if ( kv->getName() != "Region" ) continue; uf::Serializer& rMetadata = kv->getComponent(); if ( !rMetadata["region"]["initialized"].asBool() ) continue; rMetadata["region"]["modified"] = true; rMetadata["region"]["rasterized"] = false; -// kv->getComponent().clear(); -// kv->getComponent().destroy(); -// kv->getComponent() = uf::Mesh(); ++i; } -// this->getComponent().clear(); -// this->getComponent().destroy(); metadata["terrain"]["modified"] = true; std::cout << i << " regions" << std::endl; } @@ -185,7 +200,6 @@ void ext::Terrain::tick() { mesh.copy(nesh); mesh.generate(); metadata["terrain"]["state"] = "open"; - std::cout << "Finished!" << std::endl; return 0;}, true ); return 0;}, true ); } else { @@ -390,7 +404,9 @@ void ext::Terrain::generate( const pod::Vector3i& position ) { // uf::iostream << "Generating Region @ ( " << position.x << ", " << position.y << ", " << position.z << ")" << "\n"; uf::Entity* base = new ext::Region; this->addChild(*base); { ext::Region& region = *((ext::Region*)base); - uf::Serializer& m = region.getComponent() = metadata; + uf::Serializer& m = region.getComponent(); // = metadata; + m["region"] = metadata["region"]; + m["terrain"] = metadata["terrain"]; pod::Transform<>& transform = region.getComponent>(); transform.position.x = position.x * size.x; diff --git a/ext/world/world.cpp b/ext/world/world.cpp index 243bddc2..9d17603e 100644 --- a/ext/world/world.cpp +++ b/ext/world/world.cpp @@ -16,6 +16,24 @@ namespace { uf::Camera* camera; uf::GeometryBuffer light; } +namespace { + std::function findByName = [&]( uf::Entity* parent, const std::string& name ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getName() == name ) return entity; + uf::Entity* p = findByName(entity, name); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; + std::function findByUid = [&]( uf::Entity* parent, uint id ) { + for ( uf::Entity* entity : parent->getChildren() ) { + if ( entity->getUid() == id ) return entity; + uf::Entity* p = findByUid(entity, id); + if ( p ) return p; + } + return (uf::Entity*) NULL; + }; +} void ext::World::initialize() { uf::Entity::initialize(); @@ -29,7 +47,7 @@ void ext::World::tick() { uf::Entity::tick(); /* Calibrates Polyfill */ { - static float x = 1.07986, y = 24.7805; + static float x = 2.98986, y = 24.7805; if ( uf::Window::isKeyPressed("L") ) x += 0.01; if ( uf::Window::isKeyPressed("J") ) x -= 0.01; if ( uf::Window::isKeyPressed("I") ) y += 0.01; @@ -44,7 +62,12 @@ void ext::World::tick() { std::function recurse = [&]( const uf::Entity* parent, int indent ) { for ( const uf::Entity* entity : parent->getChildren() ) { for ( int i = 0; i < indent; ++i ) std::cout<<"\t"; - std::cout<getName()<<": "<getUid()<getName()<<": "<getUid(); + if ( entity->hasComponent>() ) { + const pod::Transform<>& t = uf::transform::flatten(entity->getComponent>()); + std::cout << " (" << t.position.x << ", " << t.position.y << ", " << t.position.z << ")"; + } + std::cout< int { + ext::Terrain* terrain = (ext::Terrain*) findByName(this, "Terrain"); + if ( !terrain ) return 0; + uf::Serializer& metadata = terrain->getComponent(); + pod::Vector3 position = { 0, 32, 0 }; + /* Element */ { + ext::Gui* gui = (ext::Gui*) findByName(this, "Gui Manager"); + if ( !gui ) return 0; + uf::Entity* element = new ext::Gui; + ext::Gui& guiElement = *((ext::Gui*) element); + std::string config = "./terrain/moon/config.json"; + if ( !guiElement.load(config) ) { uf::iostream << "Error loading `" << config << "!" << "\n"; delete element; return 0; } { + gui->addChild(*element); + uf::Serializer& gMetadata = element->getComponent(); + element->initialize(); + pod::Transform<>& transform = element->getComponent>(); + position = transform.position; + } + + if ( !metadata["moon"]["light"]["should"].asBool() ) return 0; + + uf::Entity* entity = new ext::Light; + if ( !((ext::Object*) entity)->load("./light/config.json") ) { uf::iostream << "Error loading `" << "./light/config.json" << "!" << "\n"; delete entity; return 0; } { + terrain->addChild(*entity); + entity->getComponent()["light"] = metadata["moon"]["light"]; + entity->getComponent()["camera"] = metadata["moon"]["camera"]; + entity->initialize(); + + pod::Transform<>& transform = entity->getComponent>(); + transform = uf::transform::initialize( transform ); + transform.position = position; + uf::transform::rotate( transform, transform.right, 1.5708 * 1 ); + entity->getComponent().update(true); + } + } + return 0;}, true ); + } } @@ -84,23 +146,9 @@ void ext::World::render() { uf::GeometryBuffer& buffer = this->getComponent(); uf::Serializer& metadata = this->getComponent(); - ::camera = this->getPlayer().getComponentPointer(); - - if ( !metadata["buffer"]["deferred"].asBool() ) { - buffer.unbind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - metadata["state"] = 0; - uf::Entity::render(); - - metadata["state"] = 2; - glEnable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - for ( uf::Entity* entity : this->getChildren() ) if ( entity->getName() == "Gui Manager" ) entity->render(); - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - return; + { + ::camera = this->getPlayer().getComponentPointer(); + ::camera->update(true); } /* Prepare Geometry Buffer */ { @@ -133,33 +181,48 @@ void ext::World::render() { } }; recurse(this, 0); + /* Sort by closest to farthest */ { + const ext::World& world = this->getRootParent(); + const ext::Player& player = world.getPlayer(); + const pod::Vector3& position = player.getComponent>().position; + std::sort( lights.begin(), lights.end(), [&]( const uf::Entity* l, const uf::Entity* r ){ + if ( !l ) return false; + if ( !r ) return true; + if ( !l->hasComponent>() ) return false; + if ( !r->hasComponent>() ) return true; + return uf::vector::magnitude( uf::vector::subtract( l->getComponent>().position, position ) ) > uf::vector::magnitude( uf::vector::subtract( r->getComponent>().position, position ) ); + } ); + } + if ( uf::Window::isKeyPressed("G") ) { + ::camera->update(true); + ::camera->update(true); + } for ( ext::Light* entity : lights ) { ext::Light& light = *entity; - uf::Serializer& metadata = light.getComponent(); - uf::GeometryBuffer& lightBuffer = metadata["light"]["dedicated"].asBool() ? light.getComponent() : ::light; + uf::Serializer& lMetadata = light.getComponent(); + if ( !lMetadata["light"]["render"].asBool() ) continue; + uf::GeometryBuffer& lightBuffer = lMetadata["light"]["dedicated"].asBool() ? light.getComponent() : ::light; uf::Camera& lightCam = light.getComponent(); - - lightCam.updateView(); - - if ( !light.hasComponent() || metadata["light"]["render_state"].asInt() == 0 ){ + if ( !light.hasComponent() || lMetadata["light"]["render_state"].asInt() == 0 ){ lightBuffer.bind(); glClear(GL_DEPTH_BUFFER_BIT); ::camera = light.getComponentPointer(); glViewport( 0, 0, ::camera->getSize().x, ::camera->getSize().y ); glEnable(GL_POLYGON_OFFSET_FILL); glDisable(GL_CULL_FACE); + // ::camera->update(true); uf::Entity::render(); glDisable(GL_POLYGON_OFFSET_FILL); glEnable(GL_CULL_FACE); ::camera = this->getPlayer().getComponentPointer(); glViewport( 0, 0, ::camera->getSize().x, ::camera->getSize().y ); } - if ( (metadata["light"]["render_state"]=metadata["light"]["render_state"].asInt()+1).asInt()-1 >= metadata["light"]["rate"].asInt() ) metadata["light"]["render_state"] = 0; + if ( (lMetadata["light"]["render_state"]=lMetadata["light"]["render_state"].asInt()+1).asInt()-1 >= lMetadata["light"]["rate"].asInt() ) lMetadata["light"]["render_state"]= 0; { metadata["buffer"]["lightmap"].asBool() ? ::light.bind() : buffer.unbind(); - if ( metadata["light"]["blend"] != Json::nullValue ) { + if ( lMetadata["light"]["blend"] != Json::nullValue ) { glEnable(GL_BLEND); GLenum parameters[4] = { GL_ONE, @@ -167,30 +230,32 @@ void ext::World::render() { GL_ONE, GL_ONE, }; - for ( int i = 0; i < metadata["light"]["blend"].size(); ++i ) { - if ( metadata["light"]["blend"][i] == "ZERO" || metadata["light"]["blend"][i] == "GL_ZERO" ) parameters[i] = GL_ZERO; - if ( metadata["light"]["blend"][i] == "ONE" || metadata["light"]["blend"][i] == "GL_ONE" ) parameters[i] = GL_ONE; - if ( metadata["light"]["blend"][i] == "SRC_COLOR" || metadata["light"]["blend"][i] == "GL_SRC_COLOR" ) parameters[i] = GL_SRC_COLOR; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_SRC_COLOR" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_COLOR" ) parameters[i] = GL_ONE_MINUS_SRC_COLOR; - if ( metadata["light"]["blend"][i] == "DST_COLOR" || metadata["light"]["blend"][i] == "GL_DST_COLOR" ) parameters[i] = GL_DST_COLOR; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_DST_COLOR" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_DST_COLOR" ) parameters[i] = GL_ONE_MINUS_DST_COLOR; - if ( metadata["light"]["blend"][i] == "SRC_ALPHA" || metadata["light"]["blend"][i] == "GL_SRC_ALPHA" ) parameters[i] = GL_SRC_ALPHA; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_SRC_ALPHA" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_ALPHA" ) parameters[i] = GL_ONE_MINUS_SRC_ALPHA; - if ( metadata["light"]["blend"][i] == "DST_ALPHA" || metadata["light"]["blend"][i] == "GL_DST_ALPHA" ) parameters[i] = GL_DST_ALPHA; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_DST_ALPHA" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_DST_ALPHA" ) parameters[i] = GL_ONE_MINUS_DST_ALPHA; - if ( metadata["light"]["blend"][i] == "CONSTANT_COLOR" || metadata["light"]["blend"][i] == "GL_CONSTANT_COLOR" ) parameters[i] = GL_CONSTANT_COLOR; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_CONSTANT_COLOR" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_CONSTANT_COLOR" ) parameters[i] = GL_ONE_MINUS_CONSTANT_COLOR; - if ( metadata["light"]["blend"][i] == "CONSTANT_ALPHA" || metadata["light"]["blend"][i] == "GL_CONSTANT_ALPHA" ) parameters[i] = GL_CONSTANT_ALPHA; - if ( metadata["light"]["blend"][i] == "ONE_MINUS_CONSTANT_ALPHA" || metadata["light"]["blend"][i] == "GL_ONE_MINUS_CONSTANT_ALPHA" ) parameters[i] = GL_ONE_MINUS_CONSTANT_ALPHA; - if ( metadata["light"]["blend"][i] == "SRC_ALPHA_SATURATE" || metadata["light"]["blend"][i] == "GL_SRC_ALPHA_SATURATE" ) parameters[i] = GL_SRC_ALPHA_SATURATE; - if ( metadata["light"]["blend"][i] == "SRC1_COLOR" || metadata["light"]["blend"][i] == "GL_SRC1_COLOR" ) parameters[i] = GL_SRC1_COLOR; - if ( metadata["light"]["blend"][i] == "SRC1_ALPHA" || metadata["light"]["blend"][i] == "GL_SRC1_ALPHA" ) parameters[i] = GL_SRC1_ALPHA; + for ( int i = 0; i < lMetadata["light"]["blend"].size(); ++i ) { + if ( lMetadata["light"]["blend"][i] == "ZERO" || lMetadata["light"]["blend"][i] == "GL_ZERO" ) parameters[i] = GL_ZERO; + if ( lMetadata["light"]["blend"][i] == "ONE" || lMetadata["light"]["blend"][i] == "GL_ONE" ) parameters[i] = GL_ONE; + if ( lMetadata["light"]["blend"][i] == "SRC_COLOR" || lMetadata["light"]["blend"][i] == "GL_SRC_COLOR" ) parameters[i] = GL_SRC_COLOR; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_SRC_COLOR" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_COLOR" ) parameters[i] = GL_ONE_MINUS_SRC_COLOR; + if ( lMetadata["light"]["blend"][i] == "DST_COLOR" || lMetadata["light"]["blend"][i] == "GL_DST_COLOR" ) parameters[i] = GL_DST_COLOR; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_DST_COLOR" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_DST_COLOR" ) parameters[i] = GL_ONE_MINUS_DST_COLOR; + if ( lMetadata["light"]["blend"][i] == "SRC_ALPHA" || lMetadata["light"]["blend"][i] == "GL_SRC_ALPHA" ) parameters[i] = GL_SRC_ALPHA; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_SRC_ALPHA" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_ALPHA" ) parameters[i] = GL_ONE_MINUS_SRC_ALPHA; + if ( lMetadata["light"]["blend"][i] == "DST_ALPHA" || lMetadata["light"]["blend"][i] == "GL_DST_ALPHA" ) parameters[i] = GL_DST_ALPHA; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_DST_ALPHA" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_DST_ALPHA" ) parameters[i] = GL_ONE_MINUS_DST_ALPHA; + if ( lMetadata["light"]["blend"][i] == "CONSTANT_COLOR" || lMetadata["light"]["blend"][i] == "GL_CONSTANT_COLOR" ) parameters[i] = GL_CONSTANT_COLOR; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_CONSTANT_COLOR" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_CONSTANT_COLOR" ) parameters[i] = GL_ONE_MINUS_CONSTANT_COLOR; + if ( lMetadata["light"]["blend"][i] == "CONSTANT_ALPHA" || lMetadata["light"]["blend"][i] == "GL_CONSTANT_ALPHA" ) parameters[i] = GL_CONSTANT_ALPHA; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_CONSTANT_ALPHA" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_CONSTANT_ALPHA" ) parameters[i] = GL_ONE_MINUS_CONSTANT_ALPHA; + if ( lMetadata["light"]["blend"][i] == "SRC_ALPHA_SATURATE" || lMetadata["light"]["blend"][i] == "GL_SRC_ALPHA_SATURATE" ) parameters[i] = GL_SRC_ALPHA_SATURATE; + if ( lMetadata["light"]["blend"][i] == "SRC1_COLOR" || lMetadata["light"]["blend"][i] == "GL_SRC1_COLOR" ) parameters[i] = GL_SRC1_COLOR; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_SRC_COLOR" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_COLOR" ) parameters[i] = GL_ONE_MINUS_SRC_COLOR; + if ( lMetadata["light"]["blend"][i] == "SRC1_ALPHA" || lMetadata["light"]["blend"][i] == "GL_SRC1_ALPHA" ) parameters[i] = GL_SRC1_ALPHA; + if ( lMetadata["light"]["blend"][i] == "ONE_MINUS_SRC_ALPHA" || lMetadata["light"]["blend"][i] == "GL_ONE_MINUS_SRC_ALPHA" ) parameters[i] = GL_ONE_MINUS_SRC_ALPHA; } - if ( metadata["light"]["blend"].size() == 2 ) { + if ( lMetadata["light"]["blend"].size() == 2 ) { glBlendEquation(GL_FUNC_ADD); glBlendFunc(parameters[0], parameters[1]); - } else if ( metadata["light"]["blend"].size() == 4 ) { + } else if ( lMetadata["light"]["blend"].size() == 4 ) { glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(parameters[0], parameters[1], parameters[2], parameters[3]); } @@ -212,10 +277,10 @@ void ext::World::render() { shader.push("matrices.projection", this->getPlayer().getComponent().getProjection()); shader.push("matrices.projectionInverse", uf::matrix::inverse(this->getPlayer().getComponent().getProjection())); - shader.push("parameters.color", light.getColor()); - shader.push("parameters.attenuation", light.getAttenuation()); - shader.push("parameters.power", light.getPower()); - shader.push("parameters.specular", light.getSpecular()); + if ( lMetadata["light"]["color"] != Json::nullValue ) shader.push("parameters.color", {lMetadata["light"]["color"][0].asFloat(),lMetadata["light"]["color"][1].asFloat(),lMetadata["light"]["color"][2].asFloat()});//light.getColor()); + if ( lMetadata["light"]["attenuation"] != Json::nullValue ) shader.push("parameters.attenuation", lMetadata["light"]["attenuation"].asFloat());//light.getAttenuation()); + if ( lMetadata["light"]["power"] != Json::nullValue ) shader.push("parameters.power", lMetadata["light"]["power"].asFloat());//light.getPower()); + if ( lMetadata["light"]["specular"] != Json::nullValue ) shader.push("parameters.specular", {lMetadata["light"]["specular"][0].asFloat(),lMetadata["light"]["specular"][1].asFloat(),lMetadata["light"]["specular"][2].asFloat()});//light.getColor()); shader.push("parameters.position", lightTransform.position); shader.push("parameters.view", lightCam.getView()); @@ -319,7 +384,7 @@ bool ext::World::load() { /* Geometry Buffer */ { /* Generate default light shadowmap */ { uf::GeometryBuffer& buffer = ::light; - uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file) @@ -345,7 +410,7 @@ bool ext::World::load() { } ); } uf::GeometryBuffer& buffer = this->getComponent(); { - uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{ + this->getComponent().addHook( "window:Resized", [&](const std::string& event)->std::string{ uf::Serializer json = event; // Update persistent window sized (size stored to JSON file)