engine/ext/scenes/test/terrain/heightmap.cpp
2020-08-15 00:00:00 -05:00

142 lines
4.5 KiB
C++

#include "heightmap.h"
#include <uf/utils/graphic/graphic.h>
#include <uf/utils/graphic/mesh.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/noise/noise.h>
namespace {
typedef uf::ColoredMesh MESH_TYPE;
}
EXT_OBJECT_REGISTER_CPP(Heightmap)
void ext::Heightmap::initialize() {
uf::Object::initialize();
{
this->addAlias<MESH_TYPE, uf::Mesh>();
}
this->m_name = "Heightmap";
auto& mesh = this->getComponent<MESH_TYPE>();
auto& graphic = this->getComponent<uf::Graphic>();
auto& transform = this->getComponent<pod::Transform<>>();
// 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<uint8_t>& 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<uf::Scene>().getComponent<uf::Serializer>()["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<uf::StereoMeshDescriptor>();
graphic.initialize();
graphic.autoAssign();
*/
graphic.process = true;
}
}
void ext::Heightmap::tick() {
uf::Object::tick();
}
void ext::Heightmap::destroy() {
auto& graphic = this->getComponent<uf::Graphic>();
graphic.destroy();
uf::Object::destroy();
}
void ext::Heightmap::render() {
uf::Object::render();
/* Update uniforms */ if ( this->hasComponent<MESH_TYPE>() ) {
auto& mesh = this->getComponent<MESH_TYPE>();
auto& graphic = this->getComponent<uf::Graphic>();
auto& root = this->getRootParent<uf::Scene>();
auto& player = *root.getController();
auto& camera = player.getComponent<uf::Camera>();
auto& transform = player.getComponent<pod::Transform<>>();
auto& model = this->getComponent<pod::Transform<>>();
if ( !graphic.initialized ) return;
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
//auto& uniforms = graphic.uniforms<uf::StereoMeshDescriptor>();
// auto& uniforms = graphic.uniforms<uf::StereoMeshDescriptor>();
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<uf::StereoMeshDescriptor>();
uniforms.matrices.model = uf::transform::model( this->getComponent<pod::Transform<>>() );
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 );
};
}