#include "heightmap.h" #include #include #include #include #include namespace { typedef uf::ColoredMesh MESH_TYPE; } EXT_OBJECT_REGISTER_CPP(Heightmap) void ext::Heightmap::initialize() { uf::Object::initialize(); { this->addAlias(); } this->m_name = "Heightmap"; auto& mesh = this->getComponent(); auto& graphic = this->getComponent(); auto& transform = this->getComponent>(); // generate heightmap { pod::Vector3ui size = { 64, 8, 64 }; uf::PerlinNoise perlin; auto noise = perlin.collect( pod::Vector2ui{size.x, size.z}, {32, 32, 32}, [&](double&d)->double{ return d * 1.5; }); auto sampleHeightmap = [&]( pod::Vector3f& p )->double{ std::size_t i = p.x + p.z * (size.x); double d = noise[i]; return d; }; for ( int32_t z = 0; z < size.z - 1; ++z ) { for ( int32_t x = 0; x < size.x - 1; ++x ) { size_t offsets[6][2] = { {0, 0}, {0, 1}, {1, 1}, {1, 1}, {1, 0}, {0, 0}, }; for ( std::size_t i = 0; i < 6; ++i ) { MESH_TYPE::vertex_t vertex; vertex.position = { x + offsets[i][0], 0, z + offsets[i][1] }; vertex.position.y = sampleHeightmap( vertex.position ); { vertex.position.x += transform.position.x - (size.x / 2.0f); vertex.position.y += transform.position.y - (size.y / 2.0f); vertex.position.z += transform.position.z - (size.z / 2.0f); } vertex.uv = { offsets[i][0], offsets[i][1] }; vertex.normal = { 0, 1, 0 }; { pod::Vector4t& p = vertex.color; uint32_t l = 0xFFFF * fmin( fmax( vertex.position.y, 0.2 ), 1.0 ); p[0] = (l >> 12) & 0xF; p[1] = (l >> 8) & 0xF; p[2] = (l >> 4) & 0xF; p[3] = (l ) & 0xF; p[0] = (p[0] << 4) | p[0]; p[1] = (p[1] << 4) | p[1]; p[2] = (p[2] << 4) | p[2]; p[3] = (p[3] << 4) | p[3]; } vertex.position.y *= 5; mesh.vertices.push_back(vertex); } } } } { // graphic.texture.loadFromFile( "./data/textures/texture.png" ); graphic.initialize(); mesh.initialize(true); auto& texture = graphic.material.textures.emplace_back(); texture.loadFromFile( "./data/textures/texture.png" ); std::string suffix = ""; { std::string _ = this->getRootParent().getComponent()["shaders"]["region"]["suffix"].asString(); if ( _ != "" ) suffix = _ + "."; } graphic.material.attachShader("./data/shaders/heightmap.stereo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); graphic.material.attachShader("./data/shaders/heightmap."+suffix+"frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); /* graphic.initializeShaders({ {"./data/shaders/heightmap.stereo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, {"./data/shaders/heightmap."+suffix+"frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} }); mesh.initialize(true); graphic.bindUniform(); graphic.initialize(); graphic.autoAssign(); */ graphic.process = true; } } void ext::Heightmap::tick() { uf::Object::tick(); } void ext::Heightmap::destroy() { auto& graphic = this->getComponent(); graphic.destroy(); uf::Object::destroy(); } void ext::Heightmap::render() { uf::Object::render(); /* Update uniforms */ if ( this->hasComponent() ) { auto& mesh = this->getComponent(); auto& graphic = this->getComponent(); auto& root = this->getRootParent(); auto& player = *root.getController(); auto& camera = player.getComponent(); auto& transform = player.getComponent>(); auto& model = this->getComponent>(); if ( !graphic.initialized ) return; uf::Serializer& metadata = this->getComponent(); //auto& uniforms = graphic.uniforms(); // auto& uniforms = graphic.uniforms(); auto& uniforms = graphic.material.shaders.front().uniforms.front().get(); uniforms.matrices.model = uf::transform::model( this->getComponent>() ); for ( std::size_t i = 0; i < 2; ++i ) { uniforms.matrices.view[i] = camera.getView( i ); uniforms.matrices.projection[i] = camera.getProjection( i ); } // graphic.updateBuffer( uniforms, 0, false ); graphic.material.shaders.front().updateBuffer( uniforms, 0, false ); }; }