diff --git a/data/layout.xml b/data/layout.xml
index 3bcb434..84da5fb 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -167,7 +167,7 @@
-
+
@@ -218,7 +218,7 @@
-
+
@@ -232,7 +232,7 @@
-
+
@@ -240,7 +240,7 @@
-
+
@@ -262,44 +262,45 @@
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
+
+
@@ -1042,7 +1043,7 @@ Here's a list of what's available in this release.
-
+
@@ -1097,9 +1098,7 @@ Here's a list of what's available in this release.
-
@@ -1123,7 +1122,7 @@ Here's a list of what's available in this release.
-
+
diff --git a/src/canvas.cpp b/src/canvas.cpp
index fcd32b8..b1dd401 100644
--- a/src/canvas.cpp
+++ b/src/canvas.cpp
@@ -2190,17 +2190,27 @@ void Canvas::draw_objects(std::function(buffer);
return true;
diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp
index 0c4b7d5..d7c5a73 100644
--- a/src/node_canvas.cpp
+++ b/src/node_canvas.cpp
@@ -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() * 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);
diff --git a/src/node_checkbox.cpp b/src/node_checkbox.cpp
index 4e89700..8838a66 100644
--- a/src/node_checkbox.cpp
+++ b/src/node_checkbox.cpp
@@ -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();
diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp
index f8c43fd..bc452b5 100644
--- a/src/node_panel_grid.cpp
+++ b/src/node_panel_grid.cpp
@@ -38,19 +38,26 @@ void NodePanelGrid::init_controls()
m_hm_lyaw = find("grid-heightmap-lyaw");
m_hm_lpitch = find("grid-heightmap-lpitch");
m_hm_shading = find("grid-heightmap-shading");
+ m_render = find("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() * 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();
+ }
+ }
}
diff --git a/src/node_panel_grid.h b/src/node_panel_grid.h
index c5d3691..aae4993 100644
--- a/src/node_panel_grid.h
+++ b/src/node_panel_grid.h
@@ -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;
};
diff --git a/src/node_slider.cpp b/src/node_slider.cpp
index b5ace62..d98b880 100644
--- a/src/node_slider.cpp
+++ b/src/node_slider.cpp
@@ -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:
diff --git a/src/node_slider.h b/src/node_slider.h
index b2589b0..28a8665 100644
--- a/src/node_slider.h
+++ b/src/node_slider.h
@@ -9,6 +9,7 @@ public:
glm::vec2 m_value{0};
glm::vec2 m_old_value;
std::function on_value_changed;
+ std::function on_value_final;
virtual Node* clone_instantiate() const override;
virtual void clone_copy(Node* dest) const override;
virtual void init() override;
diff --git a/src/shape.cpp b/src/shape.cpp
index 6e6d5f9..aadbc8c 100644
--- a/src/shape.cpp
+++ b/src/shape.cpp
@@ -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;
diff --git a/src/shape.h b/src/shape.h
index 28bf367..fe9a65f 100644
--- a/src/shape.h
+++ b/src/shape.h
@@ -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);
};