Fixing drawing code for 2.5d view

This commit is contained in:
Matthias Koefferlein 2024-05-19 17:23:28 +02:00
parent cfdb3486ef
commit 74cc50a725
1 changed files with 319 additions and 298 deletions

View File

@ -1095,24 +1095,25 @@ D25ViewWidget::paintGL ()
return; return;
} }
if (! m_shapes_program || ! m_shapes_program_uniform_normals || ! m_lines_program || ! m_gridplane_program) {
return;
}
const qreal retina_scale = devicePixelRatio (); const qreal retina_scale = devicePixelRatio ();
glViewport (0, 0, width () * retina_scale, height () * retina_scale); glViewport (0, 0, width () * retina_scale, height () * retina_scale);
tl::Color c = mp_view->background_color (); tl::Color c = mp_view->background_color ();
float foreground_rgb = (c.to_mono () ? 0.0f : 1.0f); float foreground_rgb = (c.to_mono () ? 0.0f : 1.0f);
float ambient = (c.to_mono () ? 0.8f : 0.25f); float ambient = (c.to_mono () ? 0.8f : 0.25f);
QVector4D ambient_vec4 (ambient, ambient, ambient, 1.0);
float mist_factor = (c.to_mono () ? 0.2f : 0.4f); float mist_factor = (c.to_mono () ? 0.2f : 0.4f);
float mist_add = (c.to_mono () ? 0.8f : 0.2f); float mist_add = (c.to_mono () ? 0.8f : 0.2f);
// NOTE: z axis of illum points towards the scene because we include the z inversion in the scene transformation matrix
QVector3D illum_vec3 = QVector3D (-3.0, -4.0, 2.0).normalized ();
glClearColor (float (c.red ()) / 255.0f, float (c.green ()) / 255.0f, float (c.blue ()) / 255.0f, 1.0); glClearColor (float (c.red ()) / 255.0f, float (c.green ()) / 255.0f, float (c.blue ()) / 255.0f, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (! m_shapes_program || ! m_shapes_program_uniform_normals || ! m_lines_program || ! m_gridplane_program) {
return;
}
int positions = m_shapes_program->attributeLocation ("posAttr");
int normals = m_shapes_program->attributeLocation ("normalsAttr");
QMatrix4x4 scene_trans, scene_trans_wo_y; QMatrix4x4 scene_trans, scene_trans_wo_y;
// provide the displacement and scaling (in this order!) // provide the displacement and scaling (in this order!)
@ -1124,18 +1125,23 @@ D25ViewWidget::paintGL ()
scene_trans_wo_y = scene_trans; scene_trans_wo_y = scene_trans;
scene_trans_wo_y.translate (QVector3D (0.0, -m_displacement.y (), 0.0)); scene_trans_wo_y.translate (QVector3D (0.0, -m_displacement.y (), 0.0));
m_shapes_program->bind (); // draw walls (triangles with normals)
{
QOpenGLShaderProgram *program = m_shapes_program;
int positions = program->attributeLocation ("posAttr");
int normals = program->attributeLocation ("normalsAttr");
program->bind ();
// draw the actual layout // draw the actual layout
m_shapes_program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans); program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans);
program->setUniformValue ("illum", illum_vec3);
// NOTE: z axis of illum points towards the scene because we include the z inversion in the scene transformation matrix program->setUniformValue ("ambient", ambient_vec4);
m_shapes_program->setUniformValue ("illum", QVector3D (-3.0, -4.0, 2.0).normalized ()); program->setUniformValue ("mist_factor", mist_factor);
program->setUniformValue ("mist_add", mist_add);
m_shapes_program->setUniformValue ("ambient", QVector4D (ambient, ambient, ambient, 1.0));
m_shapes_program->setUniformValue ("mist_factor", mist_factor);
m_shapes_program->setUniformValue ("mist_add", mist_add);
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnableVertexAttribArray (positions); glEnableVertexAttribArray (positions);
@ -1145,7 +1151,7 @@ D25ViewWidget::paintGL ()
if (l->visible && l->fill_color [3] > 0.5) { if (l->visible && l->fill_color [3] > 0.5) {
m_shapes_program->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]); program->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]);
triangle_chunks_type::iterator v = l->vertex_chunk->begin (); triangle_chunks_type::iterator v = l->vertex_chunk->begin ();
triangle_chunks_type::iterator n = l->normals_chunk->begin (); triangle_chunks_type::iterator n = l->normals_chunk->begin ();
@ -1166,16 +1172,22 @@ D25ViewWidget::paintGL ()
glDisableVertexAttribArray (positions); glDisableVertexAttribArray (positions);
glDisableVertexAttribArray (normals); glDisableVertexAttribArray (normals);
m_shapes_program->release (); program->release ();
}
m_shapes_program_uniform_normals->bind (); // draw flat surfaces
// NOTE: z axis of illum points towards the scene because we include the z inversion in the scene transformation matrix {
m_shapes_program_uniform_normals->setUniformValue ("illum", QVector3D (-3.0, -4.0, 2.0).normalized ()); QOpenGLShaderProgram *program = m_shapes_program_uniform_normals;
m_shapes_program_uniform_normals->setUniformValue ("ambient", QVector4D (ambient, ambient, ambient, 1.0)); int positions = program->attributeLocation ("posAttr");
m_shapes_program_uniform_normals->setUniformValue ("mist_factor", mist_factor);
m_shapes_program_uniform_normals->setUniformValue ("mist_add", mist_add); program->bind ();
program->setUniformValue ("illum", illum_vec3);
program->setUniformValue ("ambient", ambient_vec4);
program->setUniformValue ("mist_factor", mist_factor);
program->setUniformValue ("mist_add", mist_add);
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnableVertexAttribArray (positions); glEnableVertexAttribArray (positions);
@ -1190,10 +1202,10 @@ D25ViewWidget::paintGL ()
QMatrix4x4 ytop; QMatrix4x4 ytop;
ytop.translate (QVector3D (0.0, z->first.second, 0.0)); ytop.translate (QVector3D (0.0, z->first.second, 0.0));
m_shapes_program_uniform_normals->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans * ytop); program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans * ytop);
m_shapes_program_uniform_normals->setUniformValue ("normal", QVector4D (0.0, -1.0, 0.0, 1.0)); program->setUniformValue ("normal", QVector4D (0.0, -1.0, 0.0, 1.0));
m_shapes_program_uniform_normals->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]); program->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]);
triangle_chunks_type::iterator v = z->second->begin (); triangle_chunks_type::iterator v = z->second->begin ();
@ -1207,10 +1219,10 @@ D25ViewWidget::paintGL ()
QMatrix4x4 ybottom; QMatrix4x4 ybottom;
ybottom.translate (QVector3D (0.0, z->first.first, 0.0)); ybottom.translate (QVector3D (0.0, z->first.first, 0.0));
m_shapes_program_uniform_normals->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans * ybottom); program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans * ybottom);
m_shapes_program_uniform_normals->setUniformValue ("normal", QVector4D (0.0, 1.0, 0.0, 1.0)); program->setUniformValue ("normal", QVector4D (0.0, 1.0, 0.0, 1.0));
m_shapes_program_uniform_normals->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]); program->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]);
v = z->second->begin (); v = z->second->begin ();
@ -1224,26 +1236,30 @@ D25ViewWidget::paintGL ()
} }
} }
} }
glDisableVertexAttribArray (positions); glDisableVertexAttribArray (positions);
glDisableVertexAttribArray (normals);
m_shapes_program_uniform_normals->release (); program->release ();
}
// wire lines // wire lines
m_lines_program->bind (); {
QOpenGLShaderProgram *program = m_lines_program;
m_lines_program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans); int positions = program->attributeLocation ("posAttr");
// NOTE: z axis of illum points towards the scene because we include the z inversion in the scene transformation matrix program->bind ();
m_lines_program->setUniformValue ("illum", QVector3D (-3.0, -4.0, 2.0).normalized ());
m_lines_program->setUniformValue ("ambient", QVector4D (ambient, ambient, ambient, 1.0)); program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans);
m_lines_program->setUniformValue ("mist_factor", mist_factor); program->setUniformValue ("illum", illum_vec3);
m_lines_program->setUniformValue ("mist_add", mist_add); program->setUniformValue ("ambient", ambient_vec4);
program->setUniformValue ("mist_factor", mist_factor);
program->setUniformValue ("mist_add", mist_add);
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnableVertexAttribArray (positions); glEnableVertexAttribArray (positions);
@ -1251,7 +1267,7 @@ D25ViewWidget::paintGL ()
for (std::vector<LayerInfo>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { for (std::vector<LayerInfo>::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) {
if (l->visible && l->frame_color [3] > 0.5) { if (l->visible && l->frame_color [3] > 0.5) {
m_lines_program->setUniformValue ("color", l->frame_color [0], l->frame_color [1], l->frame_color [2], l->frame_color [3]); program->setUniformValue ("color", l->frame_color [0], l->frame_color [1], l->frame_color [2], l->frame_color [3]);
// TODO: use glDrawElements to draw indexed buffers for better memory usage // TODO: use glDrawElements to draw indexed buffers for better memory usage
l->line_chunk->draw_to (this, positions, GL_LINES); l->line_chunk->draw_to (this, positions, GL_LINES);
} }
@ -1259,24 +1275,28 @@ D25ViewWidget::paintGL ()
glDisableVertexAttribArray (positions); glDisableVertexAttribArray (positions);
m_lines_program->release (); program->release ();
}
// decoration // decoration
positions = m_gridplane_program->attributeLocation ("posAttr"); {
QOpenGLShaderProgram *program = m_gridplane_program;
int positions = program->attributeLocation ("posAttr");
// a vertex buffer for the decoration // a vertex buffer for the decoration
lay::mem_chunks<float, 1024 * 18> vertexes; lay::mem_chunks<float, 1024 * 18> vertexes;
m_gridplane_program->bind (); program->bind ();
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnableVertexAttribArray (positions); glEnableVertexAttribArray (positions);
// draw pivot compass // draw pivot compass
m_gridplane_program->setUniformValue ("matrix", cam_perspective () * cam_trans ()); program->setUniformValue ("matrix", cam_perspective () * cam_trans ());
double compass_rad = 0.3; double compass_rad = 0.3;
double compass_bars = 0.4; double compass_bars = 0.4;
@ -1305,7 +1325,7 @@ D25ViewWidget::paintGL ()
} }
m_gridplane_program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.25f); program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.25f);
glLineWidth (2.0); glLineWidth (2.0);
vertexes.draw_to (this, positions, GL_LINES); vertexes.draw_to (this, positions, GL_LINES);
@ -1325,7 +1345,7 @@ D25ViewWidget::paintGL ()
// draw base plane // draw base plane
m_gridplane_program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans_wo_y); program->setUniformValue ("matrix", cam_perspective () * cam_trans () * scene_trans_wo_y);
std::pair<double, double> gg = find_grid (std::max (m_bbox.width (), m_bbox.height ())); std::pair<double, double> gg = find_grid (std::max (m_bbox.width (), m_bbox.height ()));
double gminor = gg.second, gmajor = gg.first; double gminor = gg.second, gmajor = gg.first;
@ -1345,7 +1365,7 @@ D25ViewWidget::paintGL ()
for (int major = 0; major < 2; ++major) { for (int major = 0; major < 2; ++major) {
m_gridplane_program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, major ? 0.25f : 0.15f); program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, major ? 0.25f : 0.15f);
double x, y; double x, y;
double step = (major ? gmajor : gminor); double step = (major ? gmajor : gminor);
@ -1383,7 +1403,7 @@ D25ViewWidget::paintGL ()
vertexes.add (r, 0.0, b); vertexes.add (r, 0.0, b);
vertexes.add (r, 0.0, t); vertexes.add (r, 0.0, t);
m_gridplane_program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.1f); program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.1f);
vertexes.draw_to (this, positions, GL_TRIANGLES); vertexes.draw_to (this, positions, GL_TRIANGLES);
@ -1401,7 +1421,7 @@ D25ViewWidget::paintGL ()
// into_top_right_corner.translate (0.5, 0.5, 0.0); // into_top_right_corner.translate (0.5, 0.5, 0.0);
into_top_right_corner.scale (2.0 * cube_size / double (height ()), 2.0 * cube_size / double (height ()), 1.0); into_top_right_corner.scale (2.0 * cube_size / double (height ()), 2.0 * cube_size / double (height ()), 1.0);
m_gridplane_program->setUniformValue ("matrix", into_top_right_corner * cam_perspective () * cam_trans ()); program->setUniformValue ("matrix", into_top_right_corner * cam_perspective () * cam_trans ());
vertexes.clear (); vertexes.clear ();
@ -1441,7 +1461,7 @@ D25ViewWidget::paintGL ()
vertexes.add (-1.0, 1.0, -1.0); vertexes.add (-1.0, 1.0, -1.0);
vertexes.add (1.0, 1.0, -1.0); vertexes.add (1.0, 1.0, -1.0);
m_gridplane_program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.2f); program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.2f);
vertexes.draw_to (this, positions, GL_LINES); vertexes.draw_to (this, positions, GL_LINES);
@ -1492,7 +1512,7 @@ D25ViewWidget::paintGL ()
vertexes.add (0.8f, -0.8f, 1.0f); vertexes.add (0.8f, -0.8f, 1.0f);
vertexes.add (0.8f, -0.6f, 1.0f); vertexes.add (0.8f, -0.6f, 1.0f);
m_gridplane_program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.3f); program->setUniformValue ("color", foreground_rgb, foreground_rgb, foreground_rgb, 0.3f);
vertexes.draw_to (this, positions, GL_TRIANGLES); vertexes.draw_to (this, positions, GL_TRIANGLES);
@ -1500,7 +1520,8 @@ D25ViewWidget::paintGL ()
glDisableVertexAttribArray (positions); glDisableVertexAttribArray (positions);
m_shapes_program->release (); program->release ();
}
} }
void void