More work on heightmap probing.
This commit is contained in:
+179
-15
@@ -53,6 +53,69 @@ static const char *ps_code = R"(
|
||||
}
|
||||
)";
|
||||
|
||||
static const char *vs_heightmap_code = R"(
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec3 normal;
|
||||
layout (location = 2) in vec4 color;
|
||||
|
||||
uniform mat4 mmtx;
|
||||
uniform mat4 vmtx;
|
||||
uniform mat4 pmtx;
|
||||
uniform mat3 nmtx;
|
||||
|
||||
out vec3 eye_space_normal;
|
||||
out vec3 eye_space_position;
|
||||
out vec4 diffuse_color;
|
||||
|
||||
void main() {
|
||||
mat4 mvp = pmtx * vmtx * mmtx;
|
||||
gl_Position = mvp * vec4(position, 1.0);
|
||||
|
||||
eye_space_position = (vmtx * mmtx * vec4(position, 1)).xyz;
|
||||
eye_space_normal = normalize(nmtx * normal);
|
||||
|
||||
diffuse_color = color;
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
static const char *ps_heightmap_code = R"(
|
||||
#version 330
|
||||
|
||||
in vec3 eye_space_normal;
|
||||
in vec3 eye_space_position;
|
||||
in vec4 diffuse_color;
|
||||
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
vec3 normal = normalize(eye_space_normal);
|
||||
vec3 light_dir = normalize(vec3(0, 0, 1));
|
||||
vec4 ambient_color = vec4(0.1, 0.1, 0.1, 1);
|
||||
|
||||
float n_dot_l = max(dot(normal, light_dir), 0.0);
|
||||
color = n_dot_l * diffuse_color + ambient_color;
|
||||
}
|
||||
)";
|
||||
|
||||
static void add_vertex(std::vector<float>& buffer_data, glm::vec3 v, glm::vec3 n, glm::vec4 col) {
|
||||
buffer_data.push_back(v.x);
|
||||
buffer_data.push_back(v.y);
|
||||
buffer_data.push_back(v.z);
|
||||
|
||||
buffer_data.push_back(n.x);
|
||||
buffer_data.push_back(n.y);
|
||||
buffer_data.push_back(n.z);
|
||||
|
||||
buffer_data.push_back(col.r);
|
||||
buffer_data.push_back(col.g);
|
||||
buffer_data.push_back(col.b);
|
||||
buffer_data.push_back(col.a);
|
||||
}
|
||||
|
||||
static void add_vertex(std::vector<float>& buffer_data, glm::vec3 v, glm::vec4 col) {
|
||||
buffer_data.push_back(v.x);
|
||||
buffer_data.push_back(v.y);
|
||||
@@ -74,8 +137,28 @@ static void add_line(std::vector<float>& buffer_data, glm::vec3 from, glm::vec3
|
||||
add_vertex(buffer_data, to, col);
|
||||
}
|
||||
|
||||
static void add_triangle(std::vector<float>& buffer_data, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3, glm::vec3 n, glm::vec4 col) {
|
||||
add_vertex(buffer_data, p1, n, col);
|
||||
add_vertex(buffer_data, p2, n, col);
|
||||
add_vertex(buffer_data, p3, n, col);
|
||||
}
|
||||
|
||||
|
||||
void grbl::program_renderer::render(glm::mat4 model, glm::mat4 view, glm::mat4 projection, glm::mat3 normal_mat, glm::vec2 viewport_size) {
|
||||
// draw heightmap
|
||||
heightmap_shader->bind();
|
||||
heightmap_shader->set_mat4(glm::value_ptr(model), "mmtx");
|
||||
heightmap_shader->set_mat4(glm::value_ptr(view), "vmtx");
|
||||
heightmap_shader->set_mat4(glm::value_ptr(projection), "pmtx");
|
||||
heightmap_shader->set_mat3(glm::value_ptr(normal_mat), "nmtx");
|
||||
|
||||
glBindVertexArray(heightmap_vao_id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, heightmap_vertices_count);
|
||||
|
||||
heightmap_shader->unbind();
|
||||
|
||||
auto mvp = projection * view * model;
|
||||
|
||||
void grbl::program_renderer::render(glm::mat4 mvp, glm::vec2 viewport_size) {
|
||||
// draw model
|
||||
shader->bind();
|
||||
shader->set_mat4(glm::value_ptr(mvp), "mvp");
|
||||
@@ -109,25 +192,27 @@ void grbl::program_renderer::render(glm::mat4 mvp, glm::vec2 viewport_size) {
|
||||
void grbl::program_renderer::update(const grbl::program& pgm, const grbl::machine& cnc) {
|
||||
if (!initialized) {
|
||||
shader = new shader_program(vs_code, ps_code);
|
||||
heightmap_shader = new shader_program(vs_heightmap_code, ps_heightmap_code);
|
||||
|
||||
initialize_spindle_buffers();
|
||||
initialize_program_buffers();
|
||||
initialize_extents_buffers();
|
||||
initialize_heightmap_buffers();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// update program with machine status
|
||||
// build vbo and vao
|
||||
vertices_count = build_vbo(pgm);
|
||||
vertices_count = update_model_vbo(pgm);
|
||||
|
||||
auto work_pos = cnc.get_status().machine_pos;
|
||||
auto offsets = cnc.get_current_work_offset_values();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
work_pos[i] -= offsets[i];
|
||||
}
|
||||
|
||||
spindle_pos = glm::vec3(work_pos[0], work_pos[1], work_pos[2]);
|
||||
auto machine_pos = glm::vec3{cnc.get_status().machine_pos[0],
|
||||
cnc.get_status().machine_pos[1],
|
||||
cnc.get_status().machine_pos[2]};
|
||||
auto offsets = glm::vec3{cnc.get_current_work_offset_values()[0],
|
||||
cnc.get_current_work_offset_values()[1],
|
||||
cnc.get_current_work_offset_values()[2]};
|
||||
spindle_pos = machine_pos - offsets;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +284,7 @@ void grbl::program_renderer::initialize_extents_buffers() {
|
||||
// or at least we'll try to.
|
||||
|
||||
// construct box
|
||||
glm::vec4 col(1, 0, 1, 1);
|
||||
glm::vec4 col(1, 0.7, 0.3, 1);
|
||||
|
||||
|
||||
// box will range from [0,0,0] to [1,1,1] and we'll use
|
||||
@@ -251,7 +336,7 @@ void grbl::program_renderer::initialize_program_buffers() {
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
|
||||
GLsizei grbl::program_renderer::update_model_vbo(const grbl::program& pgm) {
|
||||
static auto movement_re = std::regex(R"(([gG]0*1?\s+|[xXyYzZ]\s*[0-9\.\-]+))");
|
||||
bool is_tool_on = false;
|
||||
|
||||
@@ -301,14 +386,14 @@ GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
|
||||
auto from_color = glm::vec4(1.0f);
|
||||
auto to_color = glm::vec4(1.0f);
|
||||
if (is_tool_on) {
|
||||
from_color = glm::vec4(1, 0, 0, 1);
|
||||
to_color = glm::vec4(1, 0, 0, 1);
|
||||
from_color = glm::vec4(1, 0.6, 0.6, 1);
|
||||
to_color = glm::vec4(1, 0.6, 0.6, 1);
|
||||
}
|
||||
|
||||
if (is_plunge) {
|
||||
to_color = glm::vec4(1, 0, 0, 1);
|
||||
to_color = glm::vec4(1, 0.6, 0.6, 1);
|
||||
} else if (is_retract) {
|
||||
to_color = glm::vec4(0, 1, 0, 1);
|
||||
to_color = glm::vec4(0.6, 1, 0.6, 1);
|
||||
}
|
||||
|
||||
add_line(buffer_data, tool_pos, from_color, new_pos, to_color);
|
||||
@@ -336,6 +421,83 @@ GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
|
||||
return number_of_vertices;
|
||||
}
|
||||
|
||||
|
||||
void grbl::program_renderer::update_grid(float from_x, float from_y, float to_x, float to_y, int resolution) {
|
||||
|
||||
int x_segments = ceil((to_x - from_x) / resolution);
|
||||
int y_segments = ceil((to_y - from_y) / resolution);
|
||||
|
||||
glm::vec4 color = {0.5, 0.3, 0, 1};
|
||||
|
||||
std::vector<glm::vec3> vertices;
|
||||
|
||||
float y_pos = from_y;
|
||||
for (int y = 0; y < (y_segments + 1); y++) {
|
||||
float x_pos = from_x;
|
||||
for (int x = 0; x < (x_segments + 1); x++) {
|
||||
vertices.emplace_back(x_pos, y_pos, 0);
|
||||
x_pos += resolution;
|
||||
}
|
||||
y_pos += resolution;
|
||||
}
|
||||
|
||||
std::vector<float> buffer_data;
|
||||
|
||||
for (int y = 0; y < y_segments; y++) {
|
||||
for (int x = 0; x < x_segments; x++) {
|
||||
int current = x + y * (x_segments + 1);
|
||||
int next = current + 1;
|
||||
int bottom = next + x_segments;
|
||||
int bottom_next = bottom + 1;
|
||||
|
||||
auto p1 = vertices[current];
|
||||
auto p2 = vertices[bottom];
|
||||
auto p3 = vertices[next];
|
||||
glm::vec3 normal = glm::normalize(glm::cross(p1 - p2, p3 - p1));
|
||||
add_triangle(buffer_data, p1, p2, p3, normal, color);
|
||||
|
||||
p1 = vertices[next];
|
||||
p2 = vertices[bottom];
|
||||
p3 = vertices[bottom_next];
|
||||
normal = glm::normalize(glm::cross(p1 - p2, p3 - p1));
|
||||
add_triangle(buffer_data, p1, p2, p3, normal, color);
|
||||
}
|
||||
}
|
||||
|
||||
const GLsizei size_of_vertex_in_bytes = 40;
|
||||
heightmap_vertices_count = buffer_data.size() * sizeof(float) / size_of_vertex_in_bytes;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, heightmap_vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buffer_data.size(), buffer_data.data(), GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void grbl::program_renderer::initialize_heightmap_buffers() {
|
||||
glGenBuffers(1, &heightmap_vbo_id);
|
||||
glGenVertexArrays(1, &heightmap_vao_id);
|
||||
|
||||
// for height map we are going to use solid rendering (triangles)
|
||||
// we also need to send normals so that we can better see the shape of the map through lighting
|
||||
|
||||
// vertex format: v.x, v.y, v.z, n.x, n.y, n.z, r, g, b, a
|
||||
// stride: 10 * 4 bytes => 40 bytes
|
||||
const GLsizei size_of_vertex_in_bytes = 40;
|
||||
|
||||
glBindVertexArray(heightmap_vao_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, heightmap_vbo_id);
|
||||
|
||||
glEnableVertexAttribArray(0); // vertices on stream 0
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) 0);
|
||||
|
||||
glEnableVertexAttribArray(1); // normals on stream 1
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) (sizeof(float) * 3));
|
||||
|
||||
glEnableVertexAttribArray(2); // vertex colors on stream 2
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) (sizeof(float) * 6));
|
||||
|
||||
// unbind vao
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
std::string get_shader_info_log(GLuint id) {
|
||||
GLint log_length = 0;
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
@@ -365,6 +527,7 @@ bool check_compile_error(GLuint shader_id) {
|
||||
|
||||
std::cerr << "Shader compile error: " << "(id: " << shader_id << ") - " << get_shader_info_log(shader_id) << std::endl;
|
||||
glDeleteShader(shader_id);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -376,6 +539,7 @@ bool check_link_error(GLuint program_id) {
|
||||
|
||||
std::cerr << "Shader program link error: " << "(id: " << program_id << ") - " << get_program_info_log(program_id) << std::endl;
|
||||
glDeleteProgram(program_id);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user