Mercurial > octave
changeset 25871:d8e7532edf5f
Don't render with lighting if dimensions of normals don't match.
* gl-render.cc: Check dimensions of facenormals and vertexnormals and only
render with lighting if dimensions match dimensions of coordinates.
* graphics.cc (surface::properties::update_face_normals): Move calculation of
constant out of loop.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sun, 09 Sep 2018 18:01:06 +0200 |
parents | afab7be1466a |
children | c22a310c3294 |
files | libinterp/corefcn/gl-render.cc libinterp/corefcn/graphics.cc |
diffstat | 2 files changed, 27 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/gl-render.cc Sun Sep 09 14:08:35 2018 +0200 +++ b/libinterp/corefcn/gl-render.cc Sun Sep 09 18:01:06 2018 +0200 @@ -2392,7 +2392,15 @@ NDArray c; const NDArray vn = props.get_vertexnormals ().array_value (); + dim_vector vn_dims = vn.dims (); + bool has_vertex_normals = ((vn_dims(0) == z.rows ()) && + (vn_dims(1) == z.columns ()) && + (vn_dims(2) == 3)); const NDArray fn = props.get_facenormals ().array_value (); + dim_vector fn_dims = fn.dims (); + bool has_face_normals = ((fn_dims(0) == z.rows () - 1) && + (fn_dims(1) == z.columns () - 1) && + (fn_dims(2) == 3)); // FIXME: handle transparency Matrix a; @@ -2402,14 +2410,18 @@ (props.facecolor_is ("interp") ? 2 : (props.facecolor_is ("texturemap") ? 3 : -1)))); int fl_mode = (props.facelighting_is ("none") ? 0 : - (props.facelighting_is ("flat") ? 1 : 2)); + (props.facelighting_is ("flat") ? + (has_face_normals ? 1 : 0) : + (has_vertex_normals ? 2 : 0))); int fa_mode = (props.facealpha_is_double () ? 0 : (props.facealpha_is ("flat") ? 1 : 2)); int ec_mode = (props.edgecolor_is_rgb () ? 0 : (props.edgecolor_is ("flat") ? 1 : (props.edgecolor_is ("interp") ? 2 : -1))); int el_mode = (props.edgelighting_is ("none") ? 0 : - (props.edgelighting_is ("flat") ? 1 : 2)); + (props.edgelighting_is ("flat") ? + (has_face_normals ? 1 : 0) : + (has_vertex_normals ? 2 : 0))); int ea_mode = (props.edgealpha_is_double () ? 0 : (props.edgealpha_is ("flat") ? 1 : 2)); int bfl_mode = (props.backfacelighting_is ("lit") ? 0 :
--- a/libinterp/corefcn/graphics.cc Sun Sep 09 14:08:35 2018 +0200 +++ b/libinterp/corefcn/graphics.cc Sun Sep 09 18:01:06 2018 +0200 @@ -9527,13 +9527,18 @@ if (x.columns () != p || y.rows () != q) return; - NDArray n (dim_vector (q-1, p-1, 3), 0.0); - bool x_mat = (x.rows () == q); bool y_mat = (y.columns () == p); - - double dx = x(1,1) - x(0,0); - double dy = y(1,1) - y(0,0); + + double dx, dy; + dx = dy = 1; + if (x_mat) + dx = x(0,1) - x(0,0); + if (y_mat) + dy = y(1,0) - y(0,0); + + double nz = 2 * dx * dy; + NDArray n (dim_vector (q-1, p-1, 3), nz); int i1, i2, j1, j2; i1 = i2 = 0; @@ -9555,22 +9560,20 @@ j2 = j + 1; } - double& nx = n(j, i, 0); - double& ny = n(j, i, 1); - double& nz = n(j, i, 2); + double& nx = n(j,i,0); + double& ny = n(j,i,1); // calculate face normal with Newell's method // https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal#Newell.27s_Method nx = dy * (z(j1,i1) + z(j2,i1) - z(j1,i2) - z(j2,i2)); ny = dx * (z(j1,i1) + z(j1,i2) - z(j2,i1) - z(j2,i2)); - nz = 2 * dx * dy; double d = std::max (std::max (fabs (nx), fabs (ny)), fabs (nz)); nx /= d; ny /= d; - nz /= d; + n(j,i,2) /= d; } } facenormals = n;