Render heightmap to layer
This commit is contained in:
@@ -2190,17 +2190,27 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
||||
glViewport(0, 0, layer.w, layer.h);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .1f, 1000.f);
|
||||
GLuint rboID;
|
||||
glGenRenderbuffers(1, &rboID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rboID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, layer.w, layer.h);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
||||
layer.m_rtt[i].bindFramebuffer();
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
|
||||
|
||||
observer(plane_camera, proj, i);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
layer.m_rtt[i].unbindFramebuffer();
|
||||
}
|
||||
|
||||
glDeleteRenderbuffers(1, &rboID);
|
||||
|
||||
// restore viewport and clear color states
|
||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||
|
||||
@@ -25,6 +25,8 @@ bool Image::load_file(std::string filename)
|
||||
{
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
uint8_t* buffer = stbi_load(filename.c_str(), &width, &height, nullptr, 4);
|
||||
if (!buffer)
|
||||
return false;
|
||||
comp = 4;
|
||||
m_data = std::unique_ptr<uint8_t[]>(buffer);
|
||||
return true;
|
||||
|
||||
@@ -304,90 +304,7 @@ void NodeCanvas::draw()
|
||||
for (auto& mode : Canvas::modes[(int)Canvas::kCanvasMode::Grid])
|
||||
mode->on_Draw(ortho_proj, proj, camera);
|
||||
|
||||
|
||||
if (App::I.grid->m_groud_opacity->get_value() > 0.f)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
bool blend = glIsEnabled(GL_BLEND);
|
||||
|
||||
auto mvp = proj * camera
|
||||
* glm::translate(glm::vec3(0, glm::pow(App::I.grid->m_groud_offset->get_value() - 0.5f, 3), 0))
|
||||
* glm::scale(glm::vec3(1, glm::pow(App::I.grid->m_hm_height->get_value() - 0.5f, 3.f) * 10.f, 1))
|
||||
* glm::eulerAngleX(glm::radians(90.f));
|
||||
|
||||
// DRAW SOLID
|
||||
if (App::I.grid->m_shade_mode == NodePanelGrid::ShadeMode::Solid)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
ShaderManager::use(kShader::Lambert);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
auto light_yaw = App::I.grid->m_hm_lyaw->get_value() * glm::pi<float>() * 2.f;
|
||||
auto light_pitch = App::I.grid->m_hm_lpitch->get_value();
|
||||
auto light_pos = glm::vec3(sinf(light_yaw), cosf(light_yaw), light_pitch);
|
||||
ShaderManager::u_vec3(kShaderUniform::LightDir, glm::normalize(-light_pos));
|
||||
App::I.grid->m_hm_plane.draw_fill();
|
||||
}
|
||||
else if (App::I.grid->m_shade_mode == NodePanelGrid::ShadeMode::Flat)
|
||||
{
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(
|
||||
glm::vec3(1.f - App::I.grid->m_groud_value->get_value()),
|
||||
App::I.grid->m_groud_opacity->get_value()
|
||||
));
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
App::I.grid->m_hm_plane.draw_fill();
|
||||
}
|
||||
|
||||
// DRAW GRIDS
|
||||
if (App::I.grid->m_hm_wireframe->get_value() > 0.f)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(
|
||||
glm::vec3(App::I.grid->m_groud_value->get_value()),
|
||||
App::I.grid->m_groud_opacity->get_value() *
|
||||
App::I.grid->m_hm_wireframe->get_value()
|
||||
));
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
if (App::I.grid->m_shade_mode == NodePanelGrid::ShadeMode::Transparent)
|
||||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
App::I.grid->m_hm_plane.draw_fill();
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
App::I.grid->m_hm_plane.draw_stroke();
|
||||
}
|
||||
|
||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
// box grid
|
||||
// ceiling
|
||||
// ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(
|
||||
// glm::vec3(App::I.grid->m_groud_value->get_value()),
|
||||
// App::I.grid->m_box_opacity->get_value()));
|
||||
// ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera
|
||||
// * glm::translate(glm::vec3(0, (App::I.grid->m_groud_height->get_value() + App::I.grid->m_box_height->get_value() - 0.5f) * 2.f, 0))
|
||||
// * glm::eulerAngleX(glm::radians(90.f))
|
||||
// * glm::scale(glm::vec3(grid_scale, grid_scale, 1))
|
||||
// );
|
||||
// m_grid.draw_stroke();
|
||||
|
||||
|
||||
//ShaderManager::use(kShader::Equirect);
|
||||
//ShaderManager::u_mat4(kShaderUniform::MVP, glm::scale(glm::vec3(.5, .5, 1)));
|
||||
//ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
//glBindTexture(GL_TEXTURE_CUBE_MAP, m_canvas->cube_id);
|
||||
//m_face_plane.draw_fill();
|
||||
//glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
|
||||
// ShaderManager::use(kShader::Color);
|
||||
// ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera);
|
||||
// ShaderManager::u_vec4(kShaderUniform::Col, { 1, 0, 0, 1 });
|
||||
// static glm::vec4 AB[4]{ {-.75, 0, -1, 1},{ -.75, 0, 1, 1 } };
|
||||
// m_line.update_vertices(AB);
|
||||
// m_line.draw_stroke();
|
||||
App::I.grid->draw_heightmap(proj, camera);
|
||||
|
||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
depth ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -108,6 +108,8 @@ void NodeCheckBox::set_icon(const std::string& icon_path)
|
||||
|
||||
void NodeCheckBox::update_icon()
|
||||
{
|
||||
if (m_icon_path.empty())
|
||||
return;
|
||||
auto& t = TextureManager::get(const_hash(m_icon_path.c_str()));
|
||||
if (!m_icon)
|
||||
m_icon = m_inner->add_child<NodeImage>();
|
||||
|
||||
@@ -38,19 +38,26 @@ void NodePanelGrid::init_controls()
|
||||
m_hm_lyaw = find<NodeSliderH>("grid-heightmap-lyaw");
|
||||
m_hm_lpitch = find<NodeSliderH>("grid-heightmap-lpitch");
|
||||
m_hm_shading = find<NodeComboBox>("grid-heightmap-shading");
|
||||
m_render = find<NodeButton>("grid-render");
|
||||
|
||||
m_hm_preview->SetHeight(0);
|
||||
m_hm_plane.create(1, 1, 100);
|
||||
|
||||
//m_hm_height->on_value_changed = update_hm;
|
||||
m_groud_resolution->on_value_changed = [this](Node* target, float v) {
|
||||
m_groud_resolution->on_value_final = [this](Node* target, float v) {
|
||||
if (m_hm_image.data())
|
||||
m_hm_plane.create(1, 1, m_hm_image, v * 5.f);
|
||||
m_hm_plane.create(1, 1, m_hm_image, v * 5.f, get_height());
|
||||
else
|
||||
m_hm_plane.create(1, 1, 100 * v * 5.f);
|
||||
LOG("resolution value %f", v);
|
||||
};
|
||||
|
||||
m_hm_height->on_value_final = [this](Node* target, float v) {
|
||||
if (m_hm_image.data())
|
||||
m_hm_plane.create(1, 1, m_hm_image, m_groud_resolution->get_value() * 5.f, get_height());
|
||||
LOG("height value %f", v);
|
||||
};
|
||||
|
||||
m_hm_shading->on_select = [this](Node*, int index) {
|
||||
m_shade_mode = (ShadeMode)index;
|
||||
};
|
||||
@@ -67,7 +74,8 @@ void NodePanelGrid::init_controls()
|
||||
m_hm_preview->tex.create_mipmaps();
|
||||
auto sz = m_hm_preview->tex.size();
|
||||
m_hm_preview->SetAspectRatio(sz.x / sz.y);
|
||||
m_hm_plane.create(1, 1, m_hm_image, m_groud_resolution->get_value() * 5.f);
|
||||
m_hm_plane.create(1, 1, m_hm_image,
|
||||
m_groud_resolution->get_value() * 5.f, get_height());
|
||||
m_hm_preview->SetHeight(100);
|
||||
if (m_groud_opacity->get_value() == 0.f)
|
||||
m_groud_opacity->set_value(1.f);
|
||||
@@ -95,8 +103,91 @@ void NodePanelGrid::init_controls()
|
||||
m_hm_preview->tex.create_mipmaps();
|
||||
auto sz = m_hm_preview->tex.size();
|
||||
m_hm_preview->SetAspectRatio(sz.x / sz.y);
|
||||
m_hm_plane.create(1, 1, m_hm_image, m_groud_resolution->get_value() * 5.f);
|
||||
m_hm_plane.create(1, 1, m_hm_image,
|
||||
m_groud_resolution->get_value() * 5.f, m_hm_height->get_value());
|
||||
m_hm_preview->SetHeight(100);
|
||||
}
|
||||
};
|
||||
|
||||
m_render->on_click = [this](Node*)
|
||||
{
|
||||
gl_state gl;
|
||||
gl.save();
|
||||
Canvas::I->draw_objects([this](const glm::mat4& camera, const glm::mat4& proj, int i) {
|
||||
draw_heightmap(proj, camera);
|
||||
});
|
||||
gl.restore();
|
||||
};
|
||||
}
|
||||
|
||||
float NodePanelGrid::get_height() const
|
||||
{
|
||||
return glm::pow(m_hm_height->get_value() - 0.5f, 3.f) * 10.f;
|
||||
}
|
||||
|
||||
float NodePanelGrid::get_offset() const
|
||||
{
|
||||
return glm::pow(m_groud_offset->get_value() - 0.5f, 3);
|
||||
}
|
||||
|
||||
void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camera) const
|
||||
{
|
||||
if (m_groud_opacity->get_value() > 0.f)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
auto mvp = proj * camera
|
||||
* glm::translate(glm::vec3(0, get_offset(), 0))
|
||||
* glm::scale(glm::vec3(1, get_height(), 1))
|
||||
* glm::eulerAngleX(glm::radians(90.f));
|
||||
|
||||
// DRAW SOLID
|
||||
if (m_hm_image.m_data)
|
||||
{
|
||||
if (m_shade_mode == ShadeMode::Solid)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
ShaderManager::use(kShader::Lambert);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
auto light_yaw = m_hm_lyaw->get_value() * glm::pi<float>() * 2.f;
|
||||
auto light_pitch = m_hm_lpitch->get_value();
|
||||
auto light_pos = glm::vec3(sinf(light_yaw), cosf(light_yaw), light_pitch);
|
||||
ShaderManager::u_vec3(kShaderUniform::LightDir, glm::normalize(-light_pos));
|
||||
m_hm_plane.draw_fill();
|
||||
}
|
||||
else if (m_shade_mode == ShadeMode::Flat)
|
||||
{
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(
|
||||
glm::vec3(1.f - m_groud_value->get_value()),
|
||||
m_groud_opacity->get_value()
|
||||
));
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
m_hm_plane.draw_fill();
|
||||
}
|
||||
}
|
||||
|
||||
// DRAW GRIDS
|
||||
auto wire_alpha = m_hm_image.m_data ? m_hm_wireframe->get_value() : 1.f;
|
||||
if (wire_alpha > 0.f)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(
|
||||
glm::vec3(m_groud_value->get_value()),
|
||||
m_groud_opacity->get_value() *
|
||||
wire_alpha
|
||||
));
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
if (m_hm_image.m_data && m_shade_mode == ShadeMode::Transparent)
|
||||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
m_hm_plane.draw_fill();
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
m_hm_plane.draw_stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
NodeSliderH* m_hm_wireframe;
|
||||
NodeSliderH* m_hm_lyaw;
|
||||
NodeSliderH* m_hm_lpitch;
|
||||
NodeButton* m_render;
|
||||
HeightmapPlane m_hm_plane;
|
||||
Image m_hm_image;
|
||||
std::string m_file_path;
|
||||
@@ -37,4 +38,7 @@ public:
|
||||
virtual void clone_finalize(Node* dest) const override;
|
||||
virtual void init() override;
|
||||
void init_controls();
|
||||
float get_height() const;
|
||||
float get_offset() const;
|
||||
void draw_heightmap(const glm::mat4& proj, const glm::mat4& camera) const;
|
||||
};
|
||||
|
||||
@@ -83,6 +83,8 @@ kEventResult NodeSliderH::handle_event(Event* e)
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
mouse_release();
|
||||
if (dragging && on_value_final)
|
||||
on_value_final(this, glm::length(m_value * m_mask));
|
||||
dragging = false;
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
|
||||
@@ -9,6 +9,7 @@ public:
|
||||
glm::vec2 m_value{0};
|
||||
glm::vec2 m_old_value;
|
||||
std::function<void(Node* target, float value)> on_value_changed;
|
||||
std::function<void(Node* target, float value)> on_value_final;
|
||||
virtual Node* clone_instantiate() const override;
|
||||
virtual void clone_copy(Node* dest) const override;
|
||||
virtual void init() override;
|
||||
|
||||
@@ -241,7 +241,7 @@ void Plane::create_impl(float w, float h, int div, GLushort *idx, vertex_t *vert
|
||||
}
|
||||
}
|
||||
|
||||
bool HeightmapPlane::create(float w, float h, const Image& img, float scale)
|
||||
bool HeightmapPlane::create(float w, float h, const Image& img, float scale, float height)
|
||||
{
|
||||
Image img_tmp;
|
||||
glm::u8vec4* px = (glm::u8vec4*)img.data();
|
||||
@@ -286,6 +286,7 @@ bool HeightmapPlane::create(float w, float h, const Image& img, float scale)
|
||||
}
|
||||
|
||||
// generate indices
|
||||
const glm::vec3 yscale(1, 1, height);
|
||||
for (int y = 0; y < div; y++)
|
||||
{
|
||||
int i = y * (div + 1);
|
||||
@@ -297,8 +298,8 @@ bool HeightmapPlane::create(float w, float h, const Image& img, float scale)
|
||||
*pi++ = i;
|
||||
*pi++ = i + div + 2;
|
||||
*pi++ = i + 1;
|
||||
auto n = glm::triangleNormal(xyz(vertices[i].pos),
|
||||
xyz(vertices[i + div + 1].pos), xyz(vertices[i + 1].pos));
|
||||
auto n = glm::triangleNormal(xyz(vertices[i].pos) * yscale,
|
||||
xyz(vertices[i + div + 1].pos) * yscale, xyz(vertices[i + 1].pos) * yscale);
|
||||
vertices[i].nor += n;
|
||||
vertices[i + 1].nor += n;
|
||||
vertices[i + div + 1].nor += n;
|
||||
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
class HeightmapPlane : public Shape
|
||||
{
|
||||
public:
|
||||
bool create(float w, float h, const Image& img, float scale);
|
||||
bool create(float w, float h, const Image& img, float scale, float height);
|
||||
bool create(float w, float h, int div);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user