Commit for 2018.06.03.7z

This commit is contained in:
mrq 2018-06-03 00:00:00 -05:00
parent 1ad9f50d5e
commit 739a50138f
15 changed files with 882 additions and 308 deletions

View File

@ -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";
} );

View File

@ -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:

View File

@ -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<return_t(const argument_t&)> function_t;
typedef std::unordered_map<std::string, std::vector<std::size_t>> 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<uf::Hook> vector_t;
typedef std::vector<uf::Hook::return_t> return_vector_t;
typedef std::unordered_map<uf::Hook::name_t, uf::HookHandler::vector_t> map_t;
typedef std::vector<uf::HookAlias> alias_vector_t;
typedef std::unordered_map<uf::Hook::name_t, uf::HookHandler::alias_vector_t> 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;
}

View File

@ -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<HEIGHT;y++) {
for (int x=0;x<WIDTH;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=WIDTH-1;x>=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;x<WIDTH;x++) {
Point p = Get( g, x, y );
Compare( g, p, x, y, -1, 0 );
Put( g, x, y, p );
}
}
};
for ( int y = 0; y < this->m_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() {

View File

@ -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<std::size_t>& vector = it->second;
for ( std::size_t id : vector ) uf::hooks.removeHook(name, id);
}
this->m_container.clear();
}
uf::HookHandler::HookHandler() :
m_preferReadable(false)

View File

@ -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<pod::Transform<>>();
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<pod::Transform<>>();
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<pod::Transform<>>();
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<uf::Hooks>().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<uf::Shader>();
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
glDisable(GL_CULL_FACE);
// glDisable(GL_CULL_FACE);
uf::String string( metadata["gui"]["text"].asString() );
auto str = string.translate<uf::locale::Utf8>();
auto str = string.translate<uf::locale::Utf16>();
// 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<float> 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<float> 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<uf::Texture>() ) {
ext::Gui& parent = this->getParent<ext::Gui>();

View File

@ -7,7 +7,7 @@
#include <uf/utils/window/window.h>
#include <uf/gl/camera/camera.h>
#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::Serializer>();
uf::Camera& camera = this->getComponent<uf::Camera>();
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<uf::GeometryBuffer>(); {
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<uf::Hooks>().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<uf::Hooks>().addHook( "window:Resized", [&](const std::string& event)->std::string{
uf::Serializer json = event;
// Update persistent window sized (size stored to JSON file)

View File

@ -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;
*/
};
}

View File

@ -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();

View File

@ -9,12 +9,30 @@
#include <uf/utils/audio/audio.h>
#include "../gui/gui.h"
#include "../light/light.h"
#include "../world.h"
namespace {
bool lockMouse = true;
bool croutching = false;
std::function<uf::Entity*(uf::Entity*, const std::string&)> 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<uf::Entity*(uf::Entity*, uint)> 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<uf::Hooks>().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<uf::Hooks>().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<uf::Hooks>().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<uf::Serializer>();
lMetadata["light"] = metadata["light"];
entity->initialize();
pod::Transform<>& parent = this->getComponent<pod::Transform<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();//entity->getComponent<uf::Camera>().getTransform();
transform = uf::transform::initialize( transform );
uf::transform::rotate( transform, transform.up, (360.0 / radius) * (3.1415926/180.0) * i );
entity->getComponent<uf::Camera>().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<uf::Serializer>();
lMetadata["light"] = metadata["light"];
entity->initialize();
pod::Transform<>& parent = this->getComponent<pod::Transform<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();//entity->getComponent<uf::Camera>().getTransform();
transform = uf::transform::initialize( transform );
uf::transform::rotate( transform, transform.right, 1.5708 * 1 );
entity->getComponent<uf::Camera>().setFov(120);
entity->getComponent<uf::Camera>().update(true);
}
}
}
#include <sstream>
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<uf::Camera>();
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
pod::Physics& physics = this->getComponent<pod::Physics>();
uf::Serializer& serializer = this->getComponent<uf::Serializer>();
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<uf::Serializer>()["light"]["should"].asBool() ) {
pod::Transform<>& parent = this->getComponent<pod::Transform<>>();
pod::Transform<>& camera = this->getComponent<uf::Camera>().getTransform();
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
// 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<uf::Serializer>();
uint uid = metadata["gui"]["Battery Element"].asUInt();
uf::Entity& parent = this->getRootParent<ext::World>();
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<uf::Serializer>();
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<uf::Serializer>();
gMetadata["gui"]["render"] = true;
gMetadata["gui"]["text"] = "Battery: " + string + "%";
}
} else {
if ( element ) {
uf::Serializer& gMetadata = element->getComponent<uf::Serializer>();
gMetadata["gui"]["render"] = false;
}
}
}
for ( uf::Entity* entity : this->getChildren() ) { if ( entity->getName() != "Light" ) continue;
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
transform.position = parent.position + camera.position + pod::Vector3{0, 1, 0};
uf::Serializer& lMetadata = entity->getComponent<uf::Serializer>();
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<uf::Entity*(uf::Entity*, const std::string&)> 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<uf::Entity*(uf::Entity*, uint)> 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<uf::Serializer>();
uint uid = metadata["gui"]["Sprinting Element"].asUInt();
uf::Entity& parent = this->getRootParent<ext::World>();
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<uf::Serializer>();
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() {

View File

@ -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<pod::Transform<>>();
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<float>& position = mesh.getPositions().getVertices();
std::vector<float>& uv = mesh.getUvs().getVertices();

View File

@ -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();
};

View File

@ -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<ext::Terrain>();
for ( const uf::Entity* pRegion : parent.getChildren() ) if ( pRegion->getName() == "Region" ) {
const pod::Transform<>& tRegion = pRegion->getComponent<pod::Transform<>>();
const pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
entity->getComponent<uf::Camera>().getTransform().reference = &transform;
transform = uf::transform::initialize( transform );
transform.position = parent.position;
uf::transform::rotate( transform, transform.right, 1.5708 * 1 );
entity->getComponent<uf::Camera>().setFov(120);
entity->getComponent<uf::Camera>().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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
entity->getComponent<uf::Camera>().getTransform().reference = &transform;
transform = uf::transform::initialize( transform );
transform.position = parent.position;
uf::transform::rotate( transform, transform.right, 1.5708 * 3 );
entity->getComponent<uf::Camera>().setFov(120);
entity->getComponent<uf::Camera>().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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();//entity->getComponent<uf::Camera>().getTransform();
entity->getComponent<uf::Camera>().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<uf::Camera>().update(true);
((ext::Light*)entity)->setColor( color );
}
}
generator.initialize(size);
generator.generate();
generator.generate(*this);
/* Collider */ {
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
@ -143,7 +62,98 @@ void ext::Region::load() {
}
}
// generator.rasterize(mesh, *this);
if ( this->getComponent<pod::Transform<>>().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<ext::Terrain>();
for ( const uf::Entity* pRegion : parent.getChildren() ) if ( pRegion->getName() == "Region" ) {
const pod::Transform<>& tRegion = pRegion->getComponent<pod::Transform<>>();
const pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();//entity->getComponent<uf::Camera>().getTransform();
entity->getComponent<uf::Camera>().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<uf::Camera>().update(true);
// ((ext::Light*)entity)->setColor( color );
uf::Serializer& lMetadata = entity->getComponent<uf::Serializer>();
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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
entity->getComponent<uf::Camera>().getTransform().reference = &transform;
transform = uf::transform::initialize( transform );
transform.position = parent.position;
uf::transform::rotate( transform, transform.right, 1.5708 * 1 );
entity->getComponent<uf::Camera>().setFov(120);
entity->getComponent<uf::Camera>().update(true);
// ((ext::Light*)entity)->setColor( color );
uf::Serializer& lMetadata = entity->getComponent<uf::Serializer>();
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<>>();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
entity->getComponent<uf::Camera>().getTransform().reference = &transform;
transform = uf::transform::initialize( transform );
transform.position = parent.position;
uf::transform::rotate( transform, transform.right, 1.5708 * 3 );
entity->getComponent<uf::Camera>().setFov(120);
entity->getComponent<uf::Camera>().update(true);
// ((ext::Light*)entity)->setColor( color );
uf::Serializer& lMetadata = entity->getComponent<uf::Serializer>();
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;

View File

@ -4,8 +4,29 @@
#include "generator.h"
#include "region.h"
#include "../light/light.h"
#include "../gui/gui.h"
#include <uf/utils/window/window.h>
namespace {
std::function<uf::Entity*(uf::Entity*, const std::string&)> 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<uf::Entity*(uf::Entity*, uint)> 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<uf::Serializer>();
/* Debug Information */ {
/* Terrain Metadata */ {
/* Terrain Metadata */ if ( false ) {
static uf::Timer<long long> 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<uf::Serializer>();
if ( !rMetadata["region"]["initialized"].asBool() ) continue;
rMetadata["region"]["modified"] = true;
rMetadata["region"]["rasterized"] = false;
// kv->getComponent<uf::Mesh>().clear();
// kv->getComponent<uf::Mesh>().destroy();
// kv->getComponent<uf::Mesh>() = uf::Mesh();
++i;
}
// this->getComponent<uf::Mesh>().clear();
// this->getComponent<uf::Mesh>().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<uf::Serializer>() = metadata;
uf::Serializer& m = region.getComponent<uf::Serializer>(); // = metadata;
m["region"] = metadata["region"];
m["terrain"] = metadata["terrain"];
pod::Transform<>& transform = region.getComponent<pod::Transform<>>();
transform.position.x = position.x * size.x;

View File

@ -16,6 +16,24 @@ namespace {
uf::Camera* camera;
uf::GeometryBuffer light;
}
namespace {
std::function<uf::Entity*(uf::Entity*, const std::string&)> 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<uf::Entity*(uf::Entity*, uint)> 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<void(const uf::Entity*, int)> 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<<entity->getName()<<": "<<entity->getUid()<<std::endl;
std::cout<<entity->getName()<<": "<<entity->getUid();
if ( entity->hasComponent<pod::Transform<>>() ) {
const pod::Transform<>& t = uf::transform::flatten(entity->getComponent<pod::Transform<>>());
std::cout << " (" << t.position.x << ", " << t.position.y << ", " << t.position.z << ")";
}
std::cout<<std::endl;
recurse(entity, indent + 1);
}
}; recurse(this, 0);
@ -73,6 +96,45 @@ void ext::World::tick() {
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
}
static bool first = false; if ( !first ) { first = true;
uf::thread::add( uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true ), [&]() -> int {
ext::Terrain* terrain = (ext::Terrain*) findByName(this, "Terrain");
if ( !terrain ) return 0;
uf::Serializer& metadata = terrain->getComponent<uf::Serializer>();
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<uf::Serializer>();
element->initialize();
pod::Transform<>& transform = element->getComponent<pod::Transform<>>();
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<uf::Serializer>()["light"] = metadata["moon"]["light"];
entity->getComponent<uf::Serializer>()["camera"] = metadata["moon"]["camera"];
entity->initialize();
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
transform = uf::transform::initialize( transform );
transform.position = position;
uf::transform::rotate( transform, transform.right, 1.5708 * 1 );
entity->getComponent<uf::Camera>().update(true);
}
}
return 0;}, true );
}
}
@ -84,23 +146,9 @@ void ext::World::render() {
uf::GeometryBuffer& buffer = this->getComponent<uf::GeometryBuffer>();
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
::camera = this->getPlayer().getComponentPointer<uf::Camera>();
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<uf::Camera>();
::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<ext::World>();
const ext::Player& player = world.getPlayer();
const pod::Vector3& position = player.getComponent<pod::Transform<>>().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<pod::Transform<>>() ) return false;
if ( !r->hasComponent<pod::Transform<>>() ) return true;
return uf::vector::magnitude( uf::vector::subtract( l->getComponent<pod::Transform<>>().position, position ) ) > uf::vector::magnitude( uf::vector::subtract( r->getComponent<pod::Transform<>>().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::Serializer>();
uf::GeometryBuffer& lightBuffer = metadata["light"]["dedicated"].asBool() ? light.getComponent<uf::GeometryBuffer>() : ::light;
uf::Serializer& lMetadata = light.getComponent<uf::Serializer>();
if ( !lMetadata["light"]["render"].asBool() ) continue;
uf::GeometryBuffer& lightBuffer = lMetadata["light"]["dedicated"].asBool() ? light.getComponent<uf::GeometryBuffer>() : ::light;
uf::Camera& lightCam = light.getComponent<uf::Camera>();
lightCam.updateView();
if ( !light.hasComponent<uf::GeometryBuffer>() || metadata["light"]["render_state"].asInt() == 0 ){
if ( !light.hasComponent<uf::GeometryBuffer>() || lMetadata["light"]["render_state"].asInt() == 0 ){
lightBuffer.bind();
glClear(GL_DEPTH_BUFFER_BIT);
::camera = light.getComponentPointer<uf::Camera>();
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<uf::Camera>();
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<uf::Camera>().getProjection());
shader.push("matrices.projectionInverse", uf::matrix::inverse(this->getPlayer().getComponent<uf::Camera>().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<uf::Hooks>().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::GeometryBuffer>(); {
uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{
this->getComponent<uf::Hooks>().addHook( "window:Resized", [&](const std::string& event)->std::string{
uf::Serializer json = event;
// Update persistent window sized (size stored to JSON file)