26#if defined (HAVE_CONFIG_H)
34#if defined (HAVE_WINDOWS_H)
35# define WIN32_LEAN_AND_MEAN
51#if defined (HAVE_OPENGL)
54next_power_of_2 (
int n)
58 while (m < n && m < std::numeric_limits<int>::max ())
64#define LIGHT_MODE GL_FRONT_AND_BACK
94#if ! defined (CALLBACK)
107 : m_glfcns (glfcns), m_id (), m_w (), m_h (), m_tw (), m_th (),
108 m_tx (), m_ty (), m_valid (
false)
113 : m_glfcns (glfcns), m_id (
id), m_w (w), m_h (h), m_tw (tw), m_th (th),
114 m_tx (
double(m_w)/m_tw), m_ty (
double(m_h)/m_th), m_valid (
true)
117 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (texture_rep)
122 m_glfcns.glDeleteTextures (1, &m_id);
125 void bind (
int mode)
const
128 m_glfcns.glBindTexture (mode, m_id);
131 void tex_coord (
double q,
double r)
const
134 m_glfcns.glTexCoord2d (q*m_tx, r*m_ty);
147 opengl_texture () =
delete;
150 : m_rep (
new texture_rep (glfcns))
155 : m_rep (
new texture_rep (glfcns,
id, w, h, tw, th))
158 OCTAVE_DEFAULT_COPY_DELETE (opengl_texture)
163 void bind (
int mode = GL_TEXTURE_2D)
const { m_rep->bind (mode); }
165 void tex_coord (
double q,
double r)
const { m_rep->tex_coord (q, r); }
167 bool is_valid ()
const {
return m_rep->m_valid; }
171 opengl_texture (
const std::shared_ptr<texture_rep>& new_rep)
175 std::shared_ptr<texture_rep> m_rep;
181 opengl_texture retval (glfcns);
186 if (dv.
ndims () == 3 && (dv(2) == 3 || dv(2) == 4))
191 h = dv(0),
w = dv(1);
196 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_size);
197 static bool warned =
false;
198 if (h > max_size || w > max_size)
202 warning (
"opengl_texture::create: the opengl library in use "
203 "doesn't support images with either dimension larger "
204 "than %d. Not rendering.", max_size);
208 return opengl_texture (glfcns);
214 tw = next_power_of_2 (w);
215 th = next_power_of_2 (h);
226 for (
int i = 0; i < h; i++)
228 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
230 a[idx] = xdata(i, j, 0);
231 a[idx+1] = xdata(i, j, 1);
232 a[idx+2] = xdata(i, j, 2);
236 glfcns.
glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0, GL_RGB,
246 for (
int i = 0; i < h; i++)
248 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
250 a[idx] = xdata(i, j, 0);
251 a[idx+1] = xdata(i, j, 1);
252 a[idx+2] = xdata(i, j, 2);
256 glfcns.
glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0, GL_RGB,
265 for (
int i = 0; i < h; i++)
267 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
269 a[idx] = xdata(i, j, 0);
270 a[idx+1] = xdata(i, j, 1);
271 a[idx+2] = xdata(i, j, 2);
276 GL_RGB, GL_UNSIGNED_SHORT, a);
284 for (
int i = 0; i < h; i++)
286 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
288 a[idx] = xdata(i, j, 0);
289 a[idx+1] = xdata(i, j, 1);
290 a[idx+2] = xdata(i, j, 2);
295 GL_RGB, GL_UNSIGNED_BYTE, a);
303 for (
int i = 0; i < h; i++)
305 for (
int j = 0, idx = i*tw*4; j <
w; j++, idx += 4)
307 a[idx] = xdata(i, j, 0);
308 a[idx+1] = xdata(i, j, 1);
309 a[idx+2] = xdata(i, j, 2);
310 a[idx+3] = xdata(i, j, 3);
314 glfcns.
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0,
315 GL_RGBA, GL_UNSIGNED_BYTE, a);
320 warning (
"opengl_texture::create: invalid image data type, expected double, single, uint8, or uint16");
331 warning (
"opengl_texture::create: OpenGL error while generating texture data");
333 retval = opengl_texture (glfcns,
id, w, h, tw, th);
337 warning (
"opengl_texture::create: invalid texture data size");
342class opengl_tessellator
345#if defined (HAVE_FRAMEWORK_OPENGL) && defined (HAVE_GLUTESSCALLBACK_THREEDOTS)
346 typedef GLvoid (
CALLBACK *fcn) (...);
353 opengl_tessellator () : m_glu_tess (nullptr), m_fill () { init (); }
355 OCTAVE_DISABLE_COPY_MOVE (opengl_tessellator)
357 virtual ~opengl_tessellator ()
358 {
if (m_glu_tess) gluDeleteTess (m_glu_tess); }
360 void begin_polygon (
bool filled =
true)
362 gluTessProperty (m_glu_tess, GLU_TESS_BOUNDARY_ONLY,
363 (filled ? GL_FALSE : GL_TRUE));
365 gluTessBeginPolygon (m_glu_tess,
this);
368 void end_polygon ()
const
369 { gluTessEndPolygon (m_glu_tess); }
371 void begin_contour ()
const
372 { gluTessBeginContour (m_glu_tess); }
374 void end_contour ()
const
375 { gluTessEndContour (m_glu_tess); }
377 void add_vertex (
double *loc,
void *data)
const
378 { gluTessVertex (m_glu_tess, loc, data); }
381 virtual void begin (GLenum ) { }
383 virtual void end () { }
385 virtual void vertex (
void * ) { }
387 virtual void combine (GLdouble [3] ,
void *[4] ,
388 GLfloat [4] ,
void ** ) { }
390 virtual void edge_flag (GLboolean ) { }
392 virtual void error (GLenum err)
393 { ::error (
"OpenGL tessellation error (%d)", err); }
397 m_glu_tess = gluNewTess ();
399 gluTessCallback (m_glu_tess, GLU_TESS_BEGIN_DATA,
400 reinterpret_cast<fcn
> (tess_begin));
401 gluTessCallback (m_glu_tess, GLU_TESS_END_DATA,
402 reinterpret_cast<fcn
> (tess_end));
403 gluTessCallback (m_glu_tess, GLU_TESS_VERTEX_DATA,
404 reinterpret_cast<fcn
> (tess_vertex));
405 gluTessCallback (m_glu_tess, GLU_TESS_COMBINE_DATA,
406 reinterpret_cast<fcn
> (tess_combine));
407 gluTessCallback (m_glu_tess, GLU_TESS_EDGE_FLAG_DATA,
408 reinterpret_cast<fcn
> (tess_edge_flag));
409 gluTessCallback (m_glu_tess, GLU_TESS_ERROR_DATA,
410 reinterpret_cast<fcn
> (tess_error));
413 bool is_filled ()
const {
return m_fill; }
416 static void CALLBACK tess_begin (GLenum type,
void *t)
417 {
reinterpret_cast<opengl_tessellator *
> (t)->begin (type); }
419 static void CALLBACK tess_end (
void *t)
420 {
reinterpret_cast<opengl_tessellator *
> (t)->end (); }
422 static void CALLBACK tess_vertex (
void *v,
void *t)
423 {
reinterpret_cast<opengl_tessellator *
> (t)->vertex (v); }
425 static void CALLBACK tess_combine (GLdouble c[3],
void *v[4], GLfloat w[4],
427 {
reinterpret_cast<opengl_tessellator *
> (t)->combine (c, v, w, out); }
429 static void CALLBACK tess_edge_flag (GLboolean flag,
void *t)
430 {
reinterpret_cast<opengl_tessellator *
> (t)->edge_flag (flag); }
432 static void CALLBACK tess_error (GLenum err,
void *t)
433 {
reinterpret_cast<opengl_tessellator *
> (t)->error (err); }
437 GLUtesselator *m_glu_tess;
445 class vertex_data_rep
450 : m_coords (), m_color (), m_vertex_normal (), m_face_normal (),
451 m_alpha (), m_ambient (), m_diffuse (), m_specular (),
452 m_specular_exp (), m_specular_color_refl ()
456 const Matrix& fn,
double a,
float as,
float ds,
float ss,
458 : m_coords (c), m_color (col), m_vertex_normal (vn),
459 m_face_normal (fn), m_alpha (a), m_ambient (as), m_diffuse (ds),
460 m_specular (ss), m_specular_exp (se), m_specular_color_refl (scr)
463 OCTAVE_DEFAULT_COPY (vertex_data_rep)
465 ~vertex_data_rep () =
default;
475 float m_specular_exp;
476 float m_specular_color_refl;
482 vertex_data () : m_rep (nil_rep ()) { }
485 const Matrix& fn,
double a,
float as,
float ds,
float ss,
487 : m_rep (new vertex_data_rep (c, col, vn, fn, a, as, ds, ss, se, scr))
490 vertex_data (
const vertex_data&) =
default;
492 ~vertex_data () =
default;
494 vertex_data& operator = (
const vertex_data&) =
default;
496 vertex_data_rep * get_rep ()
const {
return m_rep.get (); }
500 static std::shared_ptr<vertex_data_rep> nil_rep ()
502 static std::shared_ptr<vertex_data_rep> nr (
new vertex_data_rep ());
507 std::shared_ptr<vertex_data_rep> m_rep;
510class opengl_renderer::patch_tessellator :
public opengl_tessellator
516 : opengl_tessellator (), m_renderer (r),
517 m_color_mode (cmode), m_light_mode (lmode), m_face_lighting (fl),
518 m_index (idx), m_first (true), m_tmp_vdata ()
521 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (patch_tessellator)
523 ~patch_tessellator () =
default;
526 void begin (GLenum type)
539 m_renderer->set_polygon_offset (
true, m_index);
550 m_renderer->set_polygon_offset (
false);
553 void vertex (
void *data)
557 vertex_data::vertex_data_rep *v
558 =
reinterpret_cast<vertex_data::vertex_data_rep *
> (data);
564 if (m_color_mode ==
INTERP || (m_color_mode ==
FLAT && ! is_filled ()))
568 if (col.
numel () == 3)
570 glfcns.
glColor4d (col(0), col(1), col(2), v->m_alpha);
571 if (m_light_mode > 0)
574 float buf[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
577 for (
int k = 0; k < 3; k++)
578 buf[k] = (v->m_specular
579 * (v->m_specular_color_refl +
580 (1 - v->m_specular_color_refl) * col(k)));
584 for (
int k = 0; k < 3; k++)
585 buf[k] = (v->m_diffuse * col(k));
588 for (
int k = 0; k < 3; k++)
589 buf[k] = (v->m_ambient * col(k));
595 if (m_light_mode ==
FLAT && m_first)
597 else if (m_light_mode ==
GOURAUD)
605 void combine (GLdouble xyz[3],
void *data[4], GLfloat w[4],
void **out_data)
607 vertex_data::vertex_data_rep *v[4];
610 for (
int i = 0; i < 4; i++)
612 v[i] =
reinterpret_cast<vertex_data::vertex_data_rep *
> (data[i]);
614 if (vmax == 4 && ! v[i])
628 if (v[0]->m_color.numel ())
631 for (
int ic = 0; ic < 3; ic++)
632 for (
int iv = 0; iv < vmax; iv++)
633 cc(ic) += (
w[iv] * v[iv]->m_color (ic));
636 if (v[0]->m_vertex_normal.numel () > 0)
638 for (
int in = 0; in < 3; in++)
639 for (
int iv = 0; iv < vmax; iv++)
640 vnn(in) += (
w[iv] * v[iv]->m_vertex_normal (in));
643 if (v[0]->m_face_normal.numel () > 0)
645 for (
int in = 0; in < 3; in++)
646 for (
int iv = 0; iv < vmax; iv++)
647 fnn(in) += (
w[iv] * v[iv]->m_face_normal (in));
650 for (
int iv = 0; iv < vmax; iv++)
651 aa += (w[iv] * v[iv]->m_alpha);
653 vertex_data new_v (vv, cc, vnn, fnn, aa, v[0]->m_ambient, v[0]->m_diffuse,
654 v[0]->m_specular, v[0]->m_specular_exp,
655 v[0]->m_specular_color_refl);
656 m_tmp_vdata.push_back (new_v);
658 *out_data = new_v.get_rep ();
668 bool m_face_lighting;
671 std::list<vertex_data> m_tmp_vdata;
676class opengl_renderer::patch_tessellator
681OCTAVE_NORETURN
static void
682error_unexpected (
const char *name)
684 error (
"unexpected call to %s when HAVE_OPENGL is not defined - please report this bug", name);
690 : m_glfcns (glfcns), m_xmin (), m_xmax (), m_ymin (), m_ymax (),
691 m_zmin (), m_zmax (), m_devpixratio (1.0), m_xform (), m_toolkit (),
692 m_xZ1 (), m_xZ2 (), m_marker_id (), m_filled_marker_id (),
693 m_camera_pos (), m_camera_dir (), m_view_vector (),
694 m_interpreter (
"none"), m_txt_renderer (), m_current_light (0),
695 m_max_lights (0), m_selecting (false), m_printing (false)
701#if defined (HAVE_OPENGL)
706 static bool ok = (
sizeof (
int) <=
sizeof (GLsizei));
709 error (
"the size of GLsizei is smaller than the size of int");
721 if (! go.valid_object ())
724 const base_properties& props = go.get_properties ();
727 m_toolkit = props.get_toolkit ();
729 if (go.isa (
"figure"))
730 draw_figure (
dynamic_cast<const figure::properties&
> (props));
731 else if (go.isa (
"axes"))
732 draw_axes (
dynamic_cast<const axes::properties&
> (props));
733 else if (go.isa (
"line"))
734 draw_line (
dynamic_cast<const line::properties&
> (props));
735 else if (go.isa (
"surface"))
736 draw_surface (
dynamic_cast<const surface::properties&
> (props));
737 else if (go.isa (
"patch"))
738 draw_patch (
dynamic_cast<const patch::properties&
> (props));
739 else if (go.isa (
"scatter"))
740 draw_scatter (
dynamic_cast<const scatter::properties&
> (props));
741 else if (go.isa (
"light"))
742 draw_light (
dynamic_cast<const light::properties&
> (props));
743 else if (go.isa (
"hggroup"))
744 draw_hggroup (
dynamic_cast<const hggroup::properties&
> (props));
745 else if (go.isa (
"text"))
746 draw_text (
dynamic_cast<const text::properties&
> (props));
747 else if (go.isa (
"image"))
748 draw_image (
dynamic_cast<const image::properties&
> (props));
749 else if (go.isa (
"uimenu") || go.isa (
"uicontrol")
750 || go.isa (
"uicontextmenu") || go.isa (
"uitoolbar")
751 || go.isa (
"uipushtool") || go.isa (
"uitoggletool")
752 || go.isa (
"uitable"))
754 else if (go.isa (
"uipanel"))
757 draw_uipanel (
dynamic_cast<const uipanel::properties&
> (props), go);
759 else if (go.isa (
"uibuttongroup"))
766 warning (
"opengl_renderer: cannot render object of type '%s'",
767 props.graphics_object_name ().c_str ());
770#if defined (HAVE_OPENGL)
774 warning (
"opengl_renderer: Error '%s' (%d) occurred drawing '%s' object",
775 gluErrorString (gl_error), gl_error,
776 props.graphics_object_name ().c_str ());
784 m_printing = props.is___printing__ ();
787 init_gl_context (props.is_graphicssmoothing (), props.get_color_rgb ());
789#if defined (HAVE_OPENGL)
791 props.set___gl_extensions__ (get_string (GL_EXTENSIONS));
792 props.set___gl_renderer__ (get_string (GL_RENDERER));
793 props.set___gl_vendor__ (get_string (GL_VENDOR));
794 props.set___gl_version__ (get_string (GL_VERSION));
800 draw (props.get_all_children (),
false);
805 const graphics_object& go)
807 graphics_object fig = go.get_ancestor (
"figure");
808 const figure::properties& figProps
809 =
dynamic_cast<const figure::properties&
> (fig.get_properties ());
814 props.get_backgroundcolor_rgb ());
818 draw (props.get_all_children (),
false);
823 const graphics_object& go)
825 graphics_object fig = go.get_ancestor (
"figure");
826 const figure::properties& figProps
827 =
dynamic_cast<const figure::properties&
> (fig.get_properties ());
832 props.get_backgroundcolor_rgb ());
836 draw (props.get_all_children (),
false);
842#if defined (HAVE_OPENGL)
856 bool has_multisample =
false;
859 GLint iMultiSample, iNumSamples;
862 if (iMultiSample == GL_TRUE && iNumSamples > 0)
863 has_multisample =
true;
866 if (! has_multisample)
893 warning (
"opengl_renderer: Error '%s' (%d) occurred in init_gl_context",
894 gluErrorString (gl_error), gl_error);
898 octave_unused_parameter (enhanced);
899 octave_unused_parameter (c);
904 error_unexpected (
"opengl_renderer::init_gl_context");
911 const std::string& gridstyle,
912 const Matrix& gridcolor,
const double gridalpha,
913 const Matrix& ticks,
double lim1,
double lim2,
914 double p1,
double p1N,
double p2,
double p2N,
917#if defined (HAVE_OPENGL)
922 for (
int i = 0; i < ticks.
numel (); i++)
924 double val = ticks(i);
925 if (lim1 <= val && val <= lim2)
958 double black[3] = {0, 0, 0};
963 octave_unused_parameter (linewidth);
964 octave_unused_parameter (gridstyle);
965 octave_unused_parameter (gridcolor);
966 octave_unused_parameter (gridalpha);
967 octave_unused_parameter (ticks);
968 octave_unused_parameter (lim1);
969 octave_unused_parameter (lim2);
970 octave_unused_parameter (p1);
971 octave_unused_parameter (p1N);
972 octave_unused_parameter (p2);
973 octave_unused_parameter (p2N);
974 octave_unused_parameter (xyz);
975 octave_unused_parameter (is_3D);
980 error_unexpected (
"opengl_renderer::render_grid");
987 double lim1,
double lim2,
988 double p1,
double p1N,
989 double p2,
double p2N,
990 double dx,
double dy,
double dz,
991 int xyz,
bool mirror,
bool tickdir_both)
993#if defined (HAVE_OPENGL)
997 for (
int i = 0; i < ticks.
numel (); i++)
999 double val = ticks(i);
1001 if (lim1 <= val && val <= lim2)
1006 p2 + (tickdir_both ? -dz : 0));
1011 p2N + (tickdir_both ? dz : 0));
1018 p2 + (tickdir_both ? -dz : 0));
1023 p2N + (tickdir_both ? dz : 0));
1030 p2 + (tickdir_both ? -dy : 0), val);
1035 p2N + (tickdir_both ? dy : 0), val);
1046 octave_unused_parameter (ticks);
1047 octave_unused_parameter (lim1);
1048 octave_unused_parameter (lim2);
1049 octave_unused_parameter (p1);
1050 octave_unused_parameter (p1N);
1051 octave_unused_parameter (p2);
1052 octave_unused_parameter (p2N);
1053 octave_unused_parameter (dx);
1054 octave_unused_parameter (dy);
1055 octave_unused_parameter (dz);
1056 octave_unused_parameter (xyz);
1057 octave_unused_parameter (mirror);
1062 error_unexpected (
"opengl_renderer::render_tickmarks");
1070 double lim1,
double lim2,
1071 double p1,
double p2,
1072 int xyz,
int ha,
int va,
1073 int& wmax,
int& hmax)
1075#if defined (HAVE_OPENGL)
1077 int nticks = ticks.
numel ();
1078 int nlabels = ticklabels.
numel ();
1083 for (
int i = 0; i < nticks; i++)
1085 double val = ticks(i);
1087 if (lim1 <= val && val <= lim2)
1091 std::string label (ticklabels(i % nlabels));
1092 label.erase (0, label.find_first_not_of (
' '));
1093 label = label.substr (0, label.find_last_not_of (
' ')+1);
1110 wmax = std::max (wmax,
static_cast<int> (b(2)));
1111 hmax = std::max (hmax,
static_cast<int> (b(3)));
1117 octave_unused_parameter (ticks);
1118 octave_unused_parameter (ticklabels);
1119 octave_unused_parameter (lim1);
1120 octave_unused_parameter (lim2);
1121 octave_unused_parameter (p1);
1122 octave_unused_parameter (p2);
1123 octave_unused_parameter (xyz);
1124 octave_unused_parameter (ha);
1125 octave_unused_parameter (va);
1126 octave_unused_parameter (wmax);
1127 octave_unused_parameter (hmax);
1132 error_unexpected (
"opengl_renderer::render_ticktexts");
1140#if defined (HAVE_OPENGL)
1150 octave_unused_parameter (x1);
1151 octave_unused_parameter (x2);
1152 octave_unused_parameter (y1);
1153 octave_unused_parameter (y2);
1158 error_unexpected (
"opengl_renderer::draw_zoom_rect");
1165 int x1,
int y1,
int x2,
int y2,
1166 const Matrix& overlaycolor,
1167 double overlayalpha,
1168 const Matrix& bordercolor,
1169 double borderalpha,
double borderwidth)
1171#if defined (HAVE_OPENGL)
1208 octave_unused_parameter (width);
1209 octave_unused_parameter (height);
1210 octave_unused_parameter (x1);
1211 octave_unused_parameter (x2);
1212 octave_unused_parameter (y1);
1213 octave_unused_parameter (y2);
1214 octave_unused_parameter (overlaycolor);
1215 octave_unused_parameter (overlayalpha);
1216 octave_unused_parameter (bordercolor);
1217 octave_unused_parameter (borderalpha);
1218 octave_unused_parameter (borderwidth);
1223 error_unexpected (
"opengl_renderer::draw_zoom_box");
1231#if defined (HAVE_OPENGL)
1246 idx(0) = idx_vector::make_range (height - 1, -1, height);
1247 idx(1) = idx_vector::colon;
1248 idx(2) = idx_vector::colon;
1250 return pix.
permute (perm).index (idx);
1257 octave_unused_parameter (width);
1258 octave_unused_parameter (height);
1260 error_unexpected (
"opengl_renderer::get_pixels");
1268#if defined (HAVE_OPENGL)
1277 error_unexpected (
"opengl_renderer::finish");
1285#if defined (HAVE_OPENGL)
1289 Matrix x_zlim = props.get_transform_zlim ();
1293 const double expansion_fac = 100.0;
1297 const double single_prec_fac = 10.0;
1299 double avgZ = x_zlim(0) / 2.0 + x_zlim(1) / 2.0;
1301 = std::max (expansion_fac * (x_zlim(1)-x_zlim(0)),
1302 single_prec_fac * std::abs (avgZ)
1303 * std::numeric_limits<float>::epsilon ());
1304 m_xZ1 = avgZ - span;
1305 m_xZ2 = avgZ + span;
1307 Matrix x_mat1 = props.get_opengl_matrix_1 ();
1308 Matrix x_mat2 = props.get_opengl_matrix_2 ();
1326 m_xform = props.get_transform ();
1330 octave_unused_parameter (props);
1335 error_unexpected (
"opengl_renderer::setup_opengl_transformation");
1341opengl_renderer::draw_axes_planes (
const axes::properties& props)
1343#if defined (HAVE_OPENGL)
1345 Matrix axe_color = props.get_color_rgb ();
1346 if (axe_color.
isempty () || ! props.is_visible ())
1349 double xPlane = props.get_xPlane ();
1350 double yPlane = props.get_yPlane ();
1351 double zPlane = props.get_zPlane ();
1352 double xPlaneN = props.get_xPlaneN ();
1353 double yPlaneN = props.get_yPlaneN ();
1354 double zPlaneN = props.get_zPlaneN ();
1355 bool is2D = props.get_is2D ();
1390 octave_unused_parameter (props);
1395 error_unexpected (
"opengl_renderer::draw_axes_planes");
1401opengl_renderer::draw_axes_boxes (
const axes::properties& props)
1403#if defined (HAVE_OPENGL)
1405 if (! props.is_visible ())
1408 bool xySym = props.get_xySym ();
1409 bool layer2Dtop = props.get_layer2Dtop ();
1410 bool is2D = props.get_is2D ();
1411 bool isXOrigin = props.xaxislocation_is (
"origin")
1412 && ! props.yscale_is (
"log");
1413 bool isYOrigin = props.yaxislocation_is (
"origin")
1414 && ! props.xscale_is (
"log");
1415 bool boxFull = (props.get_boxstyle () ==
"full");
1416 double linewidth = props.get_linewidth ();
1417 double xPlane = props.get_xPlane ();
1418 double yPlane = props.get_yPlane ();
1419 double zPlane = props.get_zPlane ();
1420 double xPlaneN = props.get_xPlaneN ();
1421 double yPlaneN = props.get_yPlaneN ();
1422 double zPlaneN = props.get_zPlaneN ();
1423 double xpTick = props.get_xpTick ();
1424 double ypTick = props.get_ypTick ();
1425 double zpTick = props.get_zpTick ();
1426 double xpTickN = props.get_xpTickN ();
1427 double ypTickN = props.get_ypTickN ();
1428 double zpTickN = props.get_zpTickN ();
1430 bool plotyy = (props.has_property (
"__plotyy_axes__"));
1440 std::swap (zpTick, zpTickN);
1443 Matrix color = props.get_xcolor_rgb ();
1449 if (! isXOrigin || props.is_box() || ! is2D)
1455 if (props.is_box ())
1473 color = props.get_ycolor_rgb ();
1478 if (! isYOrigin || props.is_box() || ! is2D)
1484 if (props.is_box () && ! plotyy)
1503 color = props.get_zcolor_rgb ();
1505 if (! color.
isempty () && ! is2D)
1520 if (props.is_box ())
1550 octave_unused_parameter (props);
1555 error_unexpected (
"opengl_renderer::draw_axes_boxes");
1561opengl_renderer::draw_axes_x_grid (
const axes::properties& props)
1563#if defined (HAVE_OPENGL)
1567 int xstate = props.get_xstate ();
1569 if (xstate != AXE_DEPTH_DIR
1570 && (props.is_visible ()
1571 || (m_selecting && props.pickableparts_is (
"all"))))
1573 int zstate = props.get_zstate ();
1574 bool x2Dtop = props.get_x2Dtop ();
1575 bool layer2Dtop = props.get_layer2Dtop ();
1576 bool xyzSym = props.get_xyzSym ();
1577 bool nearhoriz = props.get_nearhoriz ();
1578 double xticklen = props.get_xticklen ();
1579 double xtickoffset = props.get_xtickoffset ();
1580 double fy = props.get_fy ();
1581 double fz = props.get_fz ();
1582 double x_min = props.get_x_min ();
1583 double x_max = props.get_x_max ();
1584 double y_min = props.get_y_min ();
1585 double y_max = props.get_y_max ();
1586 double yPlane = props.get_yPlane ();
1587 double yPlaneN = props.get_yPlaneN ();
1588 double ypTick = props.get_ypTick ();
1589 double ypTickN = props.get_ypTickN ();
1590 double zPlane = props.get_zPlane ();
1591 double zPlaneN = props.get_zPlaneN ();
1592 double zpTick = props.get_zpTick ();
1593 double zpTickN = props.get_zpTickN ();
1596 Matrix xticks =
m_xform.xscale (props.get_xtick ().matrix_value ());
1597 Matrix xmticks =
m_xform.xscale (props.get_xminortickvalues ().matrix_value ());
1598 bool do_xtick = ! props.tickdir_is (
"none") && ! xticks.
isempty ();
1599 bool do_xminortick = do_xtick && props.is_xminortick ();
1600 string_vector xticklabels = props.get_xticklabel ().string_vector_value ();
1603 bool tick_along_z = nearhoriz || math::isinf (fy);
1604 double linewidth = props.get_linewidth ();
1605 std::string gridstyle = props.get_gridlinestyle ();
1606 std::string minorgridstyle = props.get_minorgridlinestyle ();
1607 Matrix gridcolor = props.get_gridcolor_rgb ();
1608 Matrix minorgridcolor = props.get_minorgridcolor_rgb ();
1609 double gridalpha = props.get_gridalpha ();
1610 double minorgridalpha = props.get_minorgridalpha ();
1611 bool do_xgrid = (props.is_xgrid () && (gridstyle !=
"none"));
1612 bool do_xminorgrid = (props.is_xminorgrid ()
1613 && (minorgridstyle !=
"none")
1615 bool is_origin = props.xaxislocation_is (
"origin") && props.get_is2D ()
1616 && ! props.yscale_is (
"log");
1617 bool is_origin_low = is_origin && (y_min + y_max) < 0;
1618 bool mirror = props.is_box () && xstate != AXE_ANY_DIR;
1619 bool is_tickdir_both = props.tickdir_is (
"both");
1624 if (props.gridcolormode_is (
"auto"))
1625 if (props.xcolormode_is (
"manual") && ! props.xcolor_is (
"none"))
1626 gridcolor = props.get_xcolor_rgb ();
1628 if (props.minorgridcolormode_is (
"auto"))
1629 if (props.xcolormode_is (
"manual") && ! props.xcolor_is (
"none"))
1630 minorgridcolor = props.get_xcolor_rgb ();
1635 if (minorgridcolor.
isempty ())
1636 do_xminorgrid =
false;
1639 if (do_xminorgrid && ! do_xgrid)
1641 gridstyle = minorgridstyle;
1642 gridcolor = minorgridcolor;
1643 gridalpha = minorgridalpha;
1650 minorgridstyle, minorgridcolor, minorgridalpha,
1651 xmticks, x_min, x_max,
1652 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN,
1653 0, (zstate != AXE_DEPTH_DIR));
1658 gridstyle, gridcolor, gridalpha,
1659 xticks, x_min, x_max,
1660 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN,
1661 0, (zstate != AXE_DEPTH_DIR));
1664 if (props.xcolor_is (
"none"))
1670 double y_axis_pos = 0.;
1673 y_axis_pos = math::max (math::min (0., y_max), y_min);
1686 is_origin ? y_axis_pos : ypTick, ypTick,
1688 0., 0., (is_origin_low ? -1. : 1.) *
1689 math::
signum (zpTick-zpTickN)*fz*xticklen/2,
1690 0, ! is_origin && mirror, is_tickdir_both);
1693 is_origin ? y_axis_pos : ypTick, ypTickN,
1695 0., (is_origin_low ? -1. : 1.) *
1696 math::
signum (ypTick-ypTickN)*fy*xticklen/2, 0.,
1697 0, ! is_origin && mirror, is_tickdir_both);
1705 is_origin ? y_axis_pos : ypTick, ypTick,
1707 0., 0., (is_origin_low ? -1. : 1.) *
1708 math::
signum (zpTick-zpTickN)*fz*xticklen,
1709 0, ! is_origin && mirror, is_tickdir_both);
1712 is_origin ? y_axis_pos : ypTick, ypTickN,
1714 0., (is_origin_low ? -1. : 1.) *
1715 math::
signum (ypTick-ypTickN)*fy*xticklen, 0.,
1716 0, ! is_origin && mirror, is_tickdir_both);
1720 if (xticklabels.
numel () > 0)
1722 int halign = (xstate == AXE_HORZ_DIR
1724 : (xyzSym || is_origin_low ? 0 : 2));
1725 int valign = (xstate == AXE_VERT_DIR
1727 : (x2Dtop || is_origin_low ? 0 : 2));
1731 is_origin ? y_axis_pos : ypTick,
1733 (is_origin_low ? -1. : 1.) *
1734 math::
signum (zpTick-zpTickN)*fz*xtickoffset,
1735 0, halign, valign, wmax, hmax);
1738 (is_origin ? y_axis_pos : ypTick) +
1739 (is_origin_low ? -1. : 1.) *
1740 math::
signum (ypTick-ypTickN)*fy*xtickoffset,
1741 zpTick, 0, halign, valign, wmax, hmax);
1744 gh_mgr.
get_object (props.get_xlabel ()).set (
"visible",
"on");
1747 gh_mgr.
get_object (props.get_xlabel ()).set (
"visible",
"off");
1751 octave_unused_parameter (props);
1756 error_unexpected (
"opengl_renderer::draw_axes_x_grid");
1762opengl_renderer::draw_axes_y_grid (
const axes::properties& props)
1764#if defined (HAVE_OPENGL)
1768 int ystate = props.get_ystate ();
1770 if (ystate != AXE_DEPTH_DIR && props.is_visible ()
1771 && (props.is_visible ()
1772 || (m_selecting && props.pickableparts_is (
"all"))))
1774 int zstate = props.get_zstate ();
1775 bool y2Dright = props.get_y2Dright ();
1776 bool layer2Dtop = props.get_layer2Dtop ();
1777 bool xyzSym = props.get_xyzSym ();
1778 bool nearhoriz = props.get_nearhoriz ();
1779 double yticklen = props.get_yticklen ();
1780 double ytickoffset = props.get_ytickoffset ();
1781 double fx = props.get_fx ();
1782 double fz = props.get_fz ();
1783 double xPlane = props.get_xPlane ();
1784 double xPlaneN = props.get_xPlaneN ();
1785 double xpTick = props.get_xpTick ();
1786 double xpTickN = props.get_xpTickN ();
1787 double y_min = props.get_y_min ();
1788 double y_max = props.get_y_max ();
1789 double x_min = props.get_x_min ();
1790 double x_max = props.get_x_max ();
1791 double zPlane = props.get_zPlane ();
1792 double zPlaneN = props.get_zPlaneN ();
1793 double zpTick = props.get_zpTick ();
1794 double zpTickN = props.get_zpTickN ();
1797 Matrix yticks =
m_xform.yscale (props.get_ytick ().matrix_value ());
1798 Matrix ymticks =
m_xform.yscale (props.get_yminortickvalues ().matrix_value ());
1799 bool do_ytick = ! props.tickdir_is (
"none") && ! yticks.
isempty ();
1800 bool do_yminortick = do_ytick && props.is_yminortick ();
1801 string_vector yticklabels = props.get_yticklabel ().string_vector_value ();
1804 bool tick_along_z = nearhoriz || math::isinf (fx);
1805 double linewidth = props.get_linewidth ();
1806 std::string gridstyle = props.get_gridlinestyle ();
1807 std::string minorgridstyle = props.get_minorgridlinestyle ();
1808 Matrix gridcolor = props.get_gridcolor_rgb ();
1809 Matrix minorgridcolor = props.get_minorgridcolor_rgb ();
1810 double gridalpha = props.get_gridalpha ();
1811 double minorgridalpha = props.get_minorgridalpha ();
1812 bool do_ygrid = (props.is_ygrid () && (gridstyle !=
"none"));
1813 bool do_yminorgrid = (props.is_yminorgrid ()
1814 && (minorgridstyle !=
"none")
1816 bool is_origin = props.yaxislocation_is (
"origin") && props.get_is2D ()
1817 && ! props.xscale_is (
"log");
1818 bool is_origin_low = is_origin && (x_min + x_max) < 0;
1819 bool mirror = props.is_box () && ystate != AXE_ANY_DIR
1820 && (! props.has_property (
"__plotyy_axes__"));
1821 bool is_tickdir_both = props.tickdir_is (
"both");
1826 if (props.gridcolormode_is (
"auto"))
1827 if (props.ycolormode_is (
"manual") && ! props.ycolor_is (
"none"))
1828 gridcolor = props.get_ycolor_rgb ();
1830 if (props.minorgridcolormode_is (
"auto"))
1831 if (props.ycolormode_is (
"manual") && ! props.ycolor_is (
"none"))
1832 minorgridcolor = props.get_ycolor_rgb ();
1837 if (minorgridcolor.
isempty ())
1838 do_yminorgrid =
false;
1841 if (do_yminorgrid && ! do_ygrid)
1843 gridstyle = minorgridstyle;
1844 gridcolor = minorgridcolor;
1845 gridalpha = minorgridalpha;
1852 minorgridstyle, minorgridcolor, minorgridalpha,
1853 ymticks, y_min, y_max,
1854 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN,
1855 1, (zstate != AXE_DEPTH_DIR));
1860 gridstyle, gridcolor, gridalpha,
1861 yticks, y_min, y_max,
1862 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN,
1863 1, (zstate != AXE_DEPTH_DIR));
1866 if (props.ycolor_is (
"none"))
1872 double x_axis_pos = 0.;
1875 x_axis_pos = math::max (math::min (0., x_max), x_min);
1888 is_origin ? x_axis_pos : xpTick, xpTick,
1890 0., 0., (is_origin_low ? -1. : 1.) *
1891 math::
signum (zpTick-zpTickN)*fz*yticklen/2,
1892 1, ! is_origin && mirror, is_tickdir_both);
1895 is_origin ? x_axis_pos : xpTick, xpTickN,
1897 (is_origin_low ? -1. : 1.) *
1898 math::
signum (xpTick-xpTickN)*fx*yticklen/2, 0., 0.,
1899 1, ! is_origin && mirror, is_tickdir_both);
1907 is_origin ? x_axis_pos : xpTick, xpTick,
1909 0., 0., (is_origin_low ? -1. : 1.) *
1910 math::
signum (zpTick-zpTickN)*fz*yticklen,
1911 1, ! is_origin && mirror, is_tickdir_both);
1914 is_origin ? x_axis_pos : xpTick, xpTickN,
1916 (is_origin_low ? -1. : 1.) *
1917 math::
signum (xPlaneN-xPlane)*fx*yticklen, 0., 0.,
1918 1, ! is_origin && mirror, is_tickdir_both);
1922 if (yticklabels.
numel () > 0)
1924 int halign = (ystate == AXE_HORZ_DIR
1926 : (! xyzSym || y2Dright || is_origin_low ? 0 : 2));
1927 int valign = (ystate == AXE_VERT_DIR
1929 : (is_origin_low ? 0 : 2));
1933 is_origin ? x_axis_pos : xpTick,
1935 (is_origin_low ? -1. : 1.) *
1936 math::
signum (zpTick-zpTickN)*fz*ytickoffset,
1937 1, halign, valign, wmax, hmax);
1940 (is_origin ? x_axis_pos : xpTick) +
1941 (is_origin_low ? -1. : 1.) *
1942 math::
signum (xpTick-xpTickN)*fx*ytickoffset,
1943 zpTick, 1, halign, valign, wmax, hmax);
1946 gh_mgr.
get_object (props.get_ylabel ()).set (
"visible",
"on");
1949 gh_mgr.
get_object (props.get_ylabel ()).set (
"visible",
"off");
1953 octave_unused_parameter (props);
1958 error_unexpected (
"opengl_renderer::draw_axes_y_grid");
1964opengl_renderer::draw_axes_z_grid (
const axes::properties& props)
1968 int zstate = props.get_zstate ();
1970 if (zstate != AXE_DEPTH_DIR && props.is_visible ()
1971 && (props.is_visible ()
1972 || (m_selecting && props.pickableparts_is (
"all"))))
1974 bool xySym = props.get_xySym ();
1975 bool zSign = props.get_zSign ();
1976 double zticklen = props.get_zticklen ();
1977 double ztickoffset = props.get_ztickoffset ();
1978 double fx = props.get_fx ();
1979 double fy = props.get_fy ();
1980 double xPlane = props.get_xPlane ();
1981 double xPlaneN = props.get_xPlaneN ();
1982 double yPlane = props.get_yPlane ();
1983 double yPlaneN = props.get_yPlaneN ();
1984 double z_min = props.get_z_min ();
1985 double z_max = props.get_z_max ();
1988 Matrix zticks =
m_xform.zscale (props.get_ztick ().matrix_value ());
1989 Matrix zmticks =
m_xform.zscale (props.get_zminortickvalues ().matrix_value ());
1990 bool do_ztick = ! props.tickdir_is (
"none") && ! zticks.
isempty ();
1991 bool do_zminortick = do_ztick && props.is_zminortick ();
1992 string_vector zticklabels = props.get_zticklabel ().string_vector_value ();
1995 double linewidth = props.get_linewidth ();
1996 std::string gridstyle = props.get_gridlinestyle ();
1997 std::string minorgridstyle = props.get_minorgridlinestyle ();
1998 Matrix gridcolor = props.get_gridcolor_rgb ();
1999 Matrix minorgridcolor = props.get_minorgridcolor_rgb ();
2000 double gridalpha = props.get_gridalpha ();
2001 double minorgridalpha = props.get_minorgridalpha ();
2002 bool do_zgrid = (props.is_zgrid () && (gridstyle !=
"none"));
2003 bool do_zminorgrid = (props.is_zminorgrid ()
2004 && (minorgridstyle !=
"none")
2006 bool mirror = props.is_box () && zstate != AXE_ANY_DIR;
2007 bool is_tickdir_both = props.tickdir_is (
"both");
2012 if (props.gridcolormode_is (
"auto"))
2013 if (props.zcolormode_is (
"manual") && ! props.zcolor_is (
"none"))
2014 gridcolor = props.get_zcolor_rgb ();
2016 if (props.minorgridcolormode_is (
"auto"))
2017 if (props.zcolormode_is (
"manual") && ! props.zcolor_is (
"none"))
2018 minorgridcolor = props.get_zcolor_rgb ();
2023 if (minorgridcolor.
isempty ())
2024 do_zminorgrid =
false;
2027 if (do_zminorgrid && ! do_zgrid)
2029 gridstyle = minorgridstyle;
2030 gridcolor = minorgridcolor;
2031 gridalpha = minorgridalpha;
2038 minorgridstyle, minorgridcolor, minorgridalpha,
2039 zmticks, z_min, z_max,
2040 xPlane, xPlaneN, yPlane, yPlaneN, 2,
true);
2045 gridstyle, gridcolor, gridalpha,
2046 zticks, z_min, z_max,
2047 xPlane, xPlaneN, yPlane, yPlaneN, 2,
true);
2050 if (props.zcolor_is (
"none"))
2060 if (math::isinf (fy))
2063 math::signum (xPlaneN-xPlane)*fx*zticklen/2, 0., 0.,
2064 2, mirror, is_tickdir_both);
2068 0., math::signum (yPlane-yPlaneN)*fy*zticklen/2, 0.,
2069 2,
false, is_tickdir_both);
2073 if (math::isinf (fx))
2076 0., math::signum (yPlaneN-yPlane)*fy*zticklen/2, 0.,
2077 2, mirror, is_tickdir_both);
2081 math::signum (xPlane-xPlaneN)*fx*zticklen/2, 0., 0.,
2082 2,
false, is_tickdir_both);
2091 if (math::isinf (fy))
2094 math::signum (xPlaneN-xPlane)*fx*zticklen, 0., 0.,
2095 2, mirror, is_tickdir_both);
2099 0., math::signum (yPlane-yPlaneN)*fy*zticklen, 0.,
2100 2,
false, is_tickdir_both);
2104 if (math::isinf (fx))
2107 0., math::signum (yPlaneN-yPlane)*fy*zticklen, 0.,
2108 2, mirror, is_tickdir_both);
2112 math::signum (xPlane-xPlaneN)*fx*zticklen, 0., 0.,
2113 2,
false, is_tickdir_both);
2118 if (zticklabels.
numel () > 0)
2121 int valign = (zstate == AXE_VERT_DIR ? 1 : (zSign ? 3 : 2));
2125 if (math::isinf (fy))
2127 xPlaneN + math::signum (xPlaneN-xPlane)*fx*ztickoffset,
2128 yPlane, 2, halign, valign, wmax, hmax);
2131 yPlane + math::signum (yPlane-yPlaneN)*fy*ztickoffset,
2132 2, halign, valign, wmax, hmax);
2136 if (math::isinf (fx))
2138 yPlaneN + math::signum (yPlaneN-yPlane)*fy*ztickoffset,
2139 2, halign, valign, wmax, hmax);
2142 xPlane + math::signum (xPlane-xPlaneN)*fx*ztickoffset,
2143 yPlaneN, 2, halign, valign, wmax, hmax);
2147 gh_mgr.
get_object (props.get_zlabel ()).set (
"visible",
"on");
2150 gh_mgr.
get_object (props.get_zlabel ()).set (
"visible",
"off");
2154opengl_renderer::draw_axes_grids (
const axes::properties& props)
2156#if defined (HAVE_OPENGL)
2158 GLboolean antialias;
2162 if (antialias == GL_TRUE)
2170 draw_axes_x_grid (props);
2171 draw_axes_y_grid (props);
2172 draw_axes_z_grid (props);
2174 if (antialias == GL_TRUE)
2178 octave_unused_parameter (props);
2183 error_unexpected (
"opengl_renderer::draw_axes_grids");
2189opengl_renderer::draw_all_lights (
const base_properties& props,
2190 std::list<graphics_object>& obj_list)
2192#if defined (HAVE_OPENGL)
2195 Matrix children = props.get_all_children ();
2199 graphics_object go = gh_mgr.
get_object (children(i));
2201 base_properties& p = go.get_properties ();
2204 || (m_selecting && p.pickableparts_is (
"all")))
2206 if (go.isa (
"light") && ! m_selecting)
2208 if (m_current_light-GL_LIGHT0 < m_max_lights)
2215 else if (go.isa (
"hggroup")
2216 && ! (m_selecting && p.pickableparts_is (
"none")))
2217 draw_all_lights (go.get_properties (), obj_list);
2218 else if (! (m_selecting && p.pickableparts_is (
"none")))
2219 obj_list.push_back (go);
2224 octave_unused_parameter (props);
2225 octave_unused_parameter (obj_list);
2230 error_unexpected (
"opengl_renderer::draw_all_lights");
2236opengl_renderer::draw_axes_children (
const axes::properties& props)
2238#if defined (HAVE_OPENGL)
2240 std::list<graphics_object> obj_list;
2241 std::list<graphics_object>::iterator it;
2255 if (props.get_num_lights () > m_max_lights)
2257 "light: Maximum number of lights (%d) in these axes is "
2258 "exceeded.", m_max_lights);
2260 m_current_light = GL_LIGHT0;
2261 draw_all_lights (props, obj_list);
2264 for (
unsigned int i = props.get_num_lights (); i < m_max_lights; i++)
2269 m_view_vector = props.get_cameraposition ().matrix_value ();
2271 float cb[4] = { 1.0, 1.0, 1.0, 1.0 };
2272 ColumnVector ambient_color = props.get_ambientlightcolor_rgb ();
2273 for (
int i = 0; i < 3; i++)
2274 cb[i] = ambient_color(i);
2279 it = obj_list.begin ();
2280 while (it != obj_list.end ())
2282 graphics_object go = (*it);
2286 if (! go.isa (
"text") || go.get (
"units").string_value () ==
"data")
2291 it = obj_list.erase (it);
2301 for (
const graphics_object& go : obj_list)
2314 octave_unused_parameter (props);
2319 error_unexpected (
"opengl_renderer::draw_axes_children");
2327#if defined (HAVE_OPENGL)
2330 if (! props.is_visible () && props.get_tag () ==
"legend")
2335 if (m_selecting && props.pickableparts_is (
"none"))
2338 static double floatmax = std::numeric_limits<float>::max ();
2340 double x_min = props.get_x_min ();
2341 double x_max = props.get_x_max ();
2342 double y_min = props.get_y_min ();
2343 double y_max = props.get_y_max ();
2344 double z_min = props.get_z_min ();
2345 double z_max = props.get_z_max ();
2347 if (x_max > floatmax || y_max > floatmax || z_max > floatmax
2348 || x_min < -floatmax || y_min < -floatmax || z_min < -floatmax)
2350 warning (
"opengl_renderer: data values greater than float capacity. (1) Scale data, or (2) Use gnuplot");
2358 bool is2D = props.get_is2D (
true);
2364 draw_axes_planes (props);
2366 if (! is2D || props.layer_is (
"bottom"))
2368 draw_axes_grids (props);
2369 if (props.get_tag () !=
"legend" || props.get_box () !=
"off")
2370 draw_axes_boxes (props);
2373 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
2375 draw_axes_children (props);
2377 if (is2D && props.layer_is (
"top"))
2379 draw_axes_grids (props);
2380 if (props.get_tag () !=
"legend" || props.get_box () !=
"off")
2381 draw_axes_boxes (props);
2386 octave_unused_parameter (props);
2391 error_unexpected (
"opengl_renderer::draw_axes");
2399#if defined (HAVE_OPENGL)
2401 bool draw_all = m_selecting && props.pickableparts_is (
"all");
2404 Matrix y =
m_xform.yscale (props.get_ydata ().matrix_value ());
2405 Matrix z =
m_xform.zscale (props.get_zdata ().matrix_value ());
2407 bool has_z = (z.
numel () > 0);
2408 int n =
static_cast<int> (std::min (std::min (
x.numel (), y.
numel ()),
2410 : std::numeric_limits<int>::max ())));
2411 uint8_t clip_mask = (props.is_clipping () ? 0x7F : 0x40);
2412 uint8_t clip_ok = 0x40;
2414 std::vector<uint8_t> clip (n);
2417 for (
int i = 0; i < n; i++)
2418 clip[i] = (clip_code (
x(i), y(i), z(i)) & clip_mask);
2423 for (
int i = 0; i < n; i++)
2424 clip[i] = (clip_code (
x(i), y(i), z_mid) & clip_mask);
2427 if (! props.linestyle_is (
"none") && ! props.color_is (
"none"))
2430 set_linestyle (props.get_linestyle (),
false, props.get_linewidth ());
2439 for (
int i = 1; i < n; i++)
2441 if ((clip[i-1] & clip[i]) == clip_ok)
2465 for (
int i = 1; i < n; i++)
2467 if ((clip[i-1] & clip[i]) == clip_ok)
2494 if (! props.marker_is (
"none")
2495 && ! (props.markeredgecolor_is (
"none")
2496 && props.markerfacecolor_is (
"none")))
2502 else if (props.markeredgecolor_is (
"auto"))
2503 lc = props.get_color_rgb ();
2504 else if (! props.markeredgecolor_is (
"none"))
2505 lc = props.get_markeredgecolor_rgb ();
2509 if (props.markerfacecolor_is (
"auto"))
2510 fc = props.get_color_rgb ();
2511 else if (! props.markerfacecolor_is (
"none"))
2512 fc = props.get_markerfacecolor_rgb ();
2514 init_marker (props.get_marker (), props.get_markersize (),
2515 props.get_linewidth ());
2517 for (
int i = 0; i < n; i++)
2519 if (clip[i] == clip_ok)
2532 octave_unused_parameter (props);
2537 error_unexpected (
"opengl_renderer::draw_line");
2545#if defined (HAVE_OPENGL)
2547 bool draw_all = m_selecting && props.pickableparts_is (
"all");
2549 const Matrix x =
m_xform.xscale (props.get_xdata ().matrix_value ());
2550 const Matrix y =
m_xform.yscale (props.get_ydata ().matrix_value ());
2551 const Matrix z =
m_xform.zscale (props.get_zdata ().matrix_value ());
2557 const NDArray vn = props.get_vertexnormals ().array_value ();
2559 bool has_vertex_normals = (vn_dims(0) == zr && vn_dims(1) == zc
2560 && vn_dims(2) == 3);
2561 const NDArray fn = props.get_facenormals ().array_value ();
2563 bool has_face_normals = (fn_dims(0) == zr - 1 && fn_dims(1) == zc - 1
2564 && fn_dims(2) == 3);
2569 int fc_mode = (props.facecolor_is_rgb () ? 0 :
2570 (props.facecolor_is (
"flat") ? 1 :
2571 (props.facecolor_is (
"interp") ? 2 :
2572 (props.facecolor_is (
"texturemap") ? 3 : -1))));
2573 int fl_mode = (props.facelighting_is (
"none") ? 0 :
2574 (props.facelighting_is (
"flat") ?
2575 (has_face_normals ? 1 : 0) :
2576 (has_vertex_normals ? 2 : 0)));
2577 int fa_mode = (props.facealpha_is_double () ? 0 :
2578 (props.facealpha_is (
"flat") ? 1 : 2));
2579 int ec_mode = (props.edgecolor_is_rgb () ? 0 :
2580 (props.edgecolor_is (
"flat") ? 1 :
2581 (props.edgecolor_is (
"interp") ? 2 : -1)));
2582 int el_mode = (props.edgelighting_is (
"none") ? 0 :
2583 (props.edgelighting_is (
"flat") ?
2584 (has_face_normals ? 1 : 0) :
2585 (has_vertex_normals ? 2 : 0)));
2586 int ea_mode = (props.edgealpha_is_double () ? 0 :
2587 (props.edgealpha_is (
"flat") ? 1 : 2));
2588 int bfl_mode = (props.backfacelighting_is (
"lit") ? 0 :
2589 (props.backfacelighting_is (
"reverselit") ? 1 : 2));
2590 bool do_lighting = props.get_do_lighting ();
2593 : props.get_facecolor_rgb ());
2594 Matrix ecolor = props.get_edgecolor_rgb ();
2597 float as = props.get_ambientstrength ();
2598 float ds = props.get_diffusestrength ();
2599 float ss = props.get_specularstrength ();
2600 float se = props.get_specularexponent () * 5;
2601 float scr = props.get_specularcolorreflectance ();
2602 float cb[4] = { 0.0, 0.0, 0.0, 1.0 };
2607 bool x_mat = (
x.rows () == z.
rows ());
2610 i1 = i2 = j1 = j2 = 0;
2612 if ((fc_mode > 0 && fc_mode < 3) || ec_mode > 0)
2613 c = props.get_color_data ().array_value ();
2617 for (
int i = 0; i < zr; i++)
2622 for (
int j = 0; j < zc; j++)
2627 clip(i, j) = is_nan_or_inf (
x(i1, j), y(i, j1), z(i, j));
2631 if (fa_mode > 0 || ea_mode > 0)
2637 if (fl_mode > 0 || el_mode > 0)
2643 tex = opengl_texture::create (
m_glfcns, props.get_color_data ());
2645 if (draw_all || ! props.facecolor_is (
"none"))
2649 fa = props.get_facealpha_double ();
2656 for (
int i = 0; i < 3; i++)
2657 cb[i] = as * fcolor(i);
2660 for (
int i = 0; i < 3; i++)
2661 cb[i] = ds * fcolor(i);
2664 for (
int i = 0; i < 3; i++)
2665 cb[i] = ss * (scr + (1-scr) * fcolor(i));
2670 if ((fl_mode > 0) && do_lighting)
2673 ? GL_SMOOTH : GL_FLAT);
2678 for (
int i = 1; i < zc; i++)
2686 for (
int j = 1; j < zr; j++)
2689 if (clip(j-1, i-1) || clip(j, i-1)
2690 || clip(j-1, i) || clip(j, i))
2693 if (fc_mode ==
FLAT)
2696 if (! math::isfinite (c(j-1, i-1)))
2699 else if (fc_mode ==
INTERP)
2702 if (! (math::isfinite (c(j-1, i-1))
2703 && math::isfinite (c(j, i-1))
2704 && math::isfinite (c(j-1, i))
2705 && math::isfinite (c(j, i))))
2719 tex.tex_coord (
double (i-1) / (zc-1),
2720 double (j-1) / (zr-1));
2721 else if (fc_mode > 0)
2724 for (
int k = 0; k < 3; k++)
2725 cb[k] = c(j-1, i-1, k);
2730 for (
int k = 0; k < 3; k++)
2734 for (
int k = 0; k < 3; k++)
2735 cb[k] = ds * c(j-1, i-1, k);
2738 for (
int k = 0; k < 3; k++)
2739 cb[k] = ss * (scr + (1-scr) * c(j-1, i-1, k));
2744 set_normal (bfl_mode, (fl_mode ==
GOURAUD ? vn : fn),
2751 tex.tex_coord (
double (i) / (zc-1),
2752 double (j-1) / (zr-1));
2753 else if (fc_mode ==
INTERP)
2755 for (
int k = 0; k < 3; k++)
2756 cb[k] = c(j-1, i, k);
2761 for (
int k = 0; k < 3; k++)
2765 for (
int k = 0; k < 3; k++)
2766 cb[k] = ds * c(j-1, i, k);
2769 for (
int k = 0; k < 3; k++)
2770 cb[k] = ss * (scr + (1-scr) * c(j-1, i, k));
2776 set_normal (bfl_mode, vn, j-1, i);
2782 tex.tex_coord (
double (i) / (zc-1),
double (j) / (zr-1));
2783 else if (fc_mode ==
INTERP)
2785 for (
int k = 0; k < 3; k++)
2791 for (
int k = 0; k < 3; k++)
2795 for (
int k = 0; k < 3; k++)
2796 cb[k] = ds * c(j, i, k);
2799 for (
int k = 0; k < 3; k++)
2800 cb[k] = ss * (scr + (1-scr) * c(j, i, k));
2805 set_normal (bfl_mode, vn, j, i);
2811 tex.tex_coord (
double (i-1) / (zc-1),
2812 double (j) / (zr-1));
2813 else if (fc_mode ==
INTERP)
2815 for (
int k = 0; k < 3; k++)
2816 cb[k] = c(j, i-1, k);
2821 for (
int k = 0; k < 3; k++)
2825 for (
int k = 0; k < 3; k++)
2826 cb[k] = ds * c(j, i-1, k);
2829 for (
int k = 0; k < 3; k++)
2830 cb[k] = ss * (scr + (1-scr) * c(j, i-1, k));
2835 set_normal (bfl_mode, vn, j, i-1);
2847 if ((fl_mode > 0) && do_lighting)
2856 if (! props.edgecolor_is (
"none") && ! props.linestyle_is (
"none"))
2858 if (props.get_edgealpha_double () == 1)
2866 for (
int i = 0; i < 3; i++)
2867 cb[i] = as * ecolor(i);
2870 for (
int i = 0; i < 3; i++)
2871 cb[i] = ds * ecolor(i);
2874 for (
int i = 0; i < 3; i++)
2875 cb[i] = ss * (scr + (1-scr) * ecolor(i));
2880 if ((el_mode > 0) && do_lighting)
2883 ? GL_SMOOTH : GL_FLAT);
2886 props.get_linewidth ());
2893 if (props.meshstyle_is (
"both") || props.meshstyle_is (
"column"))
2895 for (
int i = 0; i < zc; i++)
2903 for (
int j = 1; j < zr; j++)
2905 if (clip(j-1, i) || clip(j, i))
2908 if (ec_mode ==
FLAT)
2911 if (! math::isfinite (c(j-1, i)))
2914 else if (ec_mode ==
INTERP)
2917 if (! (math::isfinite (c(j-1, i))
2918 && math::isfinite (c(j, i))))
2933 for (
int k = 0; k < 3; k++)
2934 cb[k] = c(j-1, i, k);
2939 for (
int k = 0; k < 3; k++)
2944 for (
int k = 0; k < 3; k++)
2945 cb[k] = ds * c(j-1, i, k);
2949 for (
int k = 0; k < 3; k++)
2950 cb[k] = ss * (scr + (1-scr) * c(j-1, i, k));
2958 set_normal (bfl_mode, vn, j-1, i);
2960 set_normal (bfl_mode, fn, j-1, std::min (i, zc-2));
2968 for (
int k = 0; k < 3; k++)
2974 for (
int k = 0; k < 3; k++)
2979 for (
int k = 0; k < 3; k++)
2980 cb[k] = ds * c(j, i, k);
2984 for (
int k = 0; k < 3; k++)
2985 cb[k] = ss * (scr + (1-scr) * c(j, i, k));
2991 set_normal (bfl_mode, vn, j, i);
3002 if (props.meshstyle_is (
"both") || props.meshstyle_is (
"row"))
3004 for (
int j = 0; j < zr; j++)
3012 for (
int i = 1; i < zc; i++)
3014 if (clip(j, i-1) || clip(j, i))
3017 if (ec_mode ==
FLAT)
3020 if (! math::isfinite (c(j, i-1)))
3023 else if (ec_mode ==
INTERP)
3026 if (! (math::isfinite (c(j, i-1))
3027 && math::isfinite (c(j, i))))
3042 for (
int k = 0; k < 3; k++)
3043 cb[k] = c(j, i-1, k);
3048 for (
int k = 0; k < 3; k++)
3053 for (
int k = 0; k < 3; k++)
3054 cb[k] = ds * c(j, i-1, k);
3058 for (
int k = 0; k < 3; k++)
3059 cb[k] = ss * (scr + (1-scr) * c(j, i-1, k));
3067 set_normal (bfl_mode, vn, j, i-1);
3069 set_normal (bfl_mode, fn, std::min (j, zr-2), i-1);
3077 for (
int k = 0; k < 3; k++)
3083 for (
int k = 0; k < 3; k++)
3088 for (
int k = 0; k < 3; k++)
3089 cb[k] = ds * c(j, i, k);
3093 for (
int k = 0; k < 3; k++)
3094 cb[k] = ss * (scr + (1-scr) * c(j, i, k));
3100 set_normal (bfl_mode, vn, j, i);
3112 if ((el_mode > 0) && do_lighting)
3121 if (! props.marker_is (
"none")
3122 && ! (props.markeredgecolor_is (
"none")
3123 && props.markerfacecolor_is (
"none")))
3129 bool do_edge = draw_all || ! props.markeredgecolor_is (
"none");
3130 bool do_face = draw_all || ! props.markerfacecolor_is (
"none");
3133 props.get_markeredgecolor_rgb ());
3135 props.get_markerfacecolor_rgb ());
3138 if (mecolor.
isempty () && props.markeredgecolor_is (
"auto"))
3140 mecolor = props.get_edgecolor_rgb ();
3141 do_edge = ! props.edgecolor_is (
"none");
3144 if (mfcolor.
isempty () && props.markerfacecolor_is (
"auto"))
3146 mfcolor = props.get_facecolor_rgb ();
3147 do_face = ! props.facecolor_is (
"none");
3151 c = props.get_color_data ().array_value ();
3153 init_marker (props.get_marker (), props.get_markersize (),
3154 props.get_linewidth ());
3156 uint8_t clip_mask = (props.is_clipping () ? 0x7F : 0x40);
3157 uint8_t clip_ok = 0x40;
3159 for (
int i = 0; i < zc; i++)
3164 for (
int j = 0; j < zr; j++)
3169 if ((clip_code (
x(j1, i), y(j, i1), z(j, i)) & clip_mask)
3173 if ((do_edge && mecolor.
isempty ())
3174 || (do_face && mfcolor.
isempty ()))
3176 if (! math::isfinite (c(j, i)))
3179 for (
int k = 0; k < 3; k++)
3197 octave_unused_parameter (props);
3202 error_unexpected (
"opengl_renderer::draw_surface");
3212#if defined (HAVE_OPENGL)
3216 if (props.has_bad_data (msg))
3218 warning (
"opengl_renderer: %s. Not rendering.", msg.c_str ());
3222 bool draw_all = m_selecting && props.pickableparts_is (
"all");
3223 const Matrix f = props.get_faces ().matrix_value ();
3224 const Matrix v =
m_xform.scale (props.get_vertices ().matrix_value ());
3231 int fcmax =
f.columns ();
3233 bool has_z = (v.
columns () > 2);
3234 bool has_facecolor =
false;
3235 bool has_facealpha =
false;
3237 int fc_mode = ((props.facecolor_is (
"none")
3238 || props.facecolor_is_rgb () || draw_all) ? 0 :
3239 (props.facecolor_is (
"flat") ? 1 : 2));
3240 int fl_mode = (props.facelighting_is (
"none") ? 0 :
3241 (props.facelighting_is (
"flat") ? 1 : 2));
3242 int fa_mode = (props.facealpha_is_double () ? 0 :
3243 (props.facealpha_is (
"flat") ? 1 : 2));
3244 int ec_mode = ((props.edgecolor_is (
"none")
3245 || props.edgecolor_is_rgb ()) ? 0 :
3246 (props.edgecolor_is (
"flat") ? 1 : 2));
3247 int el_mode = (props.edgelighting_is (
"none") ? 0 :
3248 (props.edgelighting_is (
"flat") ? 1 : 2));
3249 int ea_mode = (props.edgealpha_is_double () ? 0 :
3250 (props.edgealpha_is (
"flat") ? 1 : 2));
3251 int bfl_mode = (props.backfacelighting_is (
"lit") ? 0 :
3252 (props.backfacelighting_is (
"reverselit") ? 1 : 2));
3253 bool do_lighting = props.get_do_lighting ();
3255 Matrix fcolor = props.get_facecolor_rgb ();
3256 Matrix ecolor = props.get_edgecolor_rgb ();
3258 float as = props.get_ambientstrength ();
3259 float ds = props.get_diffusestrength ();
3260 float ss = props.get_specularstrength ();
3261 float se = props.get_specularexponent () * 5;
3262 float scr = props.get_specularcolorreflectance ();
3264 const Matrix vn = props.get_vertexnormals ().matrix_value ();
3265 bool has_vertex_normals = (vn.
rows () == nv);
3266 const Matrix fn = props.get_facenormals ().matrix_value ();
3267 bool has_face_normals = (fn.
rows () == nf);
3272 for (
int i = 0; i < nv; i++)
3273 clip(i) = is_nan_or_inf (v(i, 0), v(i, 1), v(i, 2));
3275 for (
int i = 0; i < nv; i++)
3276 clip(i) = is_nan_or_inf (v(i, 0), v(i, 1), 0);
3281 for (
int i = 0; i < nf; i++)
3286 for (
int j = 0; j < fcmax && ! math::isnan (
f(i, j)); j++, count++)
3287 fclip = (fclip || clip(
int (
f(i, j) - 1)));
3293 if (draw_all || fc_mode > 0 || ec_mode > 0)
3298 c = props.get_color_data ().matrix_value ();
3304 if (draw_all || fc_mode > 0)
3310 if (draw_all || ec_mode > 0)
3319 has_facecolor = ((c.
numel () > 0) && (c.
rows () ==
f.rows ()));
3322 if (fa_mode > 0 || ea_mode > 0)
3326 has_facealpha = ((a.
numel () > 0) && (a.
rows () ==
f.rows ()));
3330 fa = props.get_facealpha_double ();
3333 std::vector<vertex_data> vdata (
f.numel ());
3335 for (
int i = 0; i < nf; i++)
3336 for (
int j = 0; j < count_f(i); j++)
3338 int idx =
int (
f(i, j) - 1);
3346 vv(0) = v(idx, 0); vv(1) = v(idx, 1);
3349 if (((fl_mode ==
FLAT) || (el_mode ==
FLAT)) && has_face_normals)
3353 dir = ((fn(i, 0) * m_view_vector(0)
3354 + fn(i, 1) * m_view_vector(1)
3355 + fn(i, 2) * m_view_vector(2) < 0)
3356 ? ((bfl_mode > 1) ? 0.0 : -1.0) : 1.0);
3357 fnn(0) = dir * fn(i, 0);
3358 fnn(1) = dir * fn(i, 1);
3359 fnn(2) = dir * fn(i, 2);
3361 if ((fl_mode ==
GOURAUD || el_mode ==
GOURAUD) && has_vertex_normals)
3365 dir = ((vn(idx, 0) * m_view_vector(0)
3366 + vn(idx, 1) * m_view_vector(1)
3367 + vn(idx, 2) * m_view_vector(2) < 0)
3368 ? ((bfl_mode > 1) ? 0.0 : -1.0) : 1.0);
3369 vnn(0) = dir * vn(idx, 0);
3370 vnn(1) = dir * vn(idx, 1);
3371 vnn(2) = dir * vn(idx, 2);
3377 cc(0) = c(i, 0), cc(1) = c(i, 1), cc(2) = c(i, 2);
3379 cc(0) = c(idx, 0), cc(1) = c(idx, 1), cc(2) = c(idx, 2);
3383 else if (a.
numel () > 0)
3392 = vertex_data (vv, cc, vnn, fnn, aa, as, ds, ss, se, scr);
3395 if (fl_mode > 0 || el_mode > 0)
3398 if (draw_all || ! props.facecolor_is (
"none"))
3408 float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
3410 for (
int i = 0; i < 3; i++)
3411 cb[i] = as * fcolor(i);
3414 for (
int i = 0; i < 3; i++)
3415 cb[i] = ds * fcolor(i);
3418 for (
int i = 0; i < 3; i++)
3419 cb[i] = ss * (scr + (1-scr) * fcolor(i));
3424 if ((fl_mode > 0) && do_lighting)
3431 patch_tessellator tess (
this, fc_mode, fl_mode,
true, 1.0);
3433 std::vector<octave_idx_type>::const_iterator it;
3436 for (
int i = 0; i < nf; i++)
3441 bool is_non_planar =
false;
3442 if (props.m_coplanar_last_idx.size () > 0
3443 && props.m_coplanar_last_idx[i].size () > 1)
3445 is_non_planar =
true;
3446 it = props.m_coplanar_last_idx[i].end ();
3456 if (it == props.m_coplanar_last_idx[i].begin ())
3466 i_end = count_f(i) - 1;
3470 tess.begin_polygon (
true);
3471 tess.begin_contour ();
3474 for (
int j = i_end; j > i_start; j--)
3476 vertex_data::vertex_data_rep *vv
3477 = vdata[i+j*fr].get_rep ();
3479 tess.add_vertex (vv->m_coords.rwdata (), vv);
3484 vertex_data::vertex_data_rep *vv = vdata[i].get_rep ();
3486 if (fc_mode ==
FLAT)
3489 Matrix col = vv->m_color;
3491 if (col.
numel () == 3)
3496 float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
3498 for (
int k = 0; k < 3; k++)
3499 cb[k] = (vv->m_ambient * col(k));
3503 for (
int k = 0; k < 3; k++)
3504 cb[k] = (vv->m_diffuse * col(k));
3508 for (
int k = 0; k < 3; k++)
3509 cb[k] = vv->m_specular *
3510 (vv->m_specular_color_refl
3511 + (1-vv->m_specular_color_refl) *
3519 tess.add_vertex (vv->m_coords.rwdata (), vv);
3522 tess.end_contour ();
3523 tess.end_polygon ();
3525 while (i_start > 0);
3528 if ((fl_mode > 0) && do_lighting)
3538 || (! props.edgecolor_is (
"none") && ! props.linestyle_is (
"none")))
3541 if (props.get_edgealpha_double () == 1)
3549 float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
3553 for (
int i = 0; i < 3; i++)
3554 cb[i] = (as * ecolor(i));
3559 if ((el_mode > 0) && do_lighting)
3562 double linewidth = props.get_linewidth ();
3573 patch_tessellator tess (
this, ec_mode, el_mode,
false);
3575 for (
int i = 0; i < nf; i++)
3577 bool is_non_planar =
false;
3578 if (props.m_coplanar_last_idx.size () > 0
3579 && props.m_coplanar_last_idx[i].size () > 1)
3580 is_non_planar =
true;
3581 if (clip_f(i) || is_non_planar)
3589 ? GL_SMOOTH : GL_FLAT);
3592 for (
int j = count_f(i)-1; j >= 0; j--)
3594 if (! clip(
int (
f(i, j) - 1)))
3596 vertex_data::vertex_data_rep *vv
3597 = vdata[i+j*fr].get_rep ();
3598 const Matrix m = vv->m_coords;
3606 Matrix col = vv->m_color;
3608 if (col.
numel () == 3)
3621 int j = count_f(i)-1;
3622 if (flag && ! clip(
int (
f(i, j) - 1)))
3624 vertex_data::vertex_data_rep *vv
3625 = vdata[i+j*fr].get_rep ();
3626 const Matrix m = vv->m_coords;
3629 Matrix col = vv->m_color;
3631 if (col.
numel () == 3)
3642 tess.begin_polygon (
false);
3643 tess.begin_contour ();
3645 for (
int j = count_f(i)-1; j >= 0; j--)
3647 vertex_data::vertex_data_rep *vv
3648 = vdata[i+j*fr].get_rep ();
3649 tess.add_vertex (vv->m_coords.rwdata (), vv);
3652 tess.end_contour ();
3653 tess.end_polygon ();
3660 if ((el_mode > 0) && do_lighting)
3669 if (! props.marker_is (
"none")
3670 && ! (props.markeredgecolor_is (
"none")
3671 && props.markerfacecolor_is (
"none")))
3673 bool do_edge = draw_all || ! props.markeredgecolor_is (
"none");
3674 bool do_face = draw_all || ! props.markerfacecolor_is (
"none");
3677 props.get_markeredgecolor_rgb ());
3679 props.get_markerfacecolor_rgb ());
3681 bool has_markerfacecolor = draw_all ||
false;
3683 if ((mecolor.
isempty () && ! props.markeredgecolor_is (
"none"))
3684 || (mfcolor.
isempty () && ! props.markerfacecolor_is (
"none")))
3686 Matrix mc = props.get_color_data ().matrix_value ();
3688 if (mc.
rows () == 1)
3691 if (mfcolor.
isempty () && ! props.markerfacecolor_is (
"none"))
3694 if (mecolor.
isempty () && ! props.markeredgecolor_is (
"none"))
3700 c = props.get_color_data ().matrix_value ();
3701 has_markerfacecolor = ((c.
numel () > 0)
3702 && (c.
rows () ==
f.rows ()));
3706 init_marker (props.get_marker (), props.get_markersize (),
3707 props.get_linewidth ());
3709 uint8_t clip_mask = (props.is_clipping () ? 0x7F : 0x40);
3710 uint8_t clip_ok = 0x40;
3712 for (
int i = 0; i < nf; i++)
3713 for (
int j = 0; j < count_f(i); j++)
3715 int idx =
int (
f(i, j) - 1);
3717 if ((clip_code (v(idx, 0), v(idx, 1), (has_z ? v(idx, 2) : 0))
3718 & clip_mask) != clip_ok)
3725 if (has_markerfacecolor)
3726 cc(0) = c(i, 0), cc(1) = c(i, 1), cc(2) = c(i, 2);
3728 cc(0) = c(idx, 0), cc(1) = c(idx, 1), cc(2) = c(idx, 2);
3736 draw_marker (v(idx, 0), v(idx, 1), (has_z ? v(idx, 2) : 0), lc, fc);
3744 octave_unused_parameter (props);
3749 error_unexpected (
"opengl_renderer::draw_patch");
3757#if defined (HAVE_OPENGL)
3761 if (props.has_bad_data (msg))
3763 warning (
"opengl_renderer: %s. Not rendering.", msg.c_str ());
3767 bool draw_all = m_selecting;
3769 if (draw_all || (! props.marker_is (
"none")
3770 && ! (props.markeredgecolor_is (
"none")
3771 && props.markerfacecolor_is (
"none"))))
3773 bool do_edge = draw_all || ! props.markeredgecolor_is (
"none");
3774 bool do_face = draw_all || ! props.markerfacecolor_is (
"none");
3776 const Matrix x = props.get_xdata ().matrix_value ();
3777 const Matrix y = props.get_ydata ().matrix_value ();
3778 const Matrix z = props.get_zdata ().matrix_value ();
3779 const Matrix c = props.get_color_data ().matrix_value ();
3780 const Matrix s = props.get_sizedata ().matrix_value ();
3787 props.get_markeredgecolor_rgb ());
3789 props.get_markerfacecolor_rgb ());
3790 const double mea = props.get_markeredgealpha ();
3791 const double mfa = props.get_markerfacealpha ();
3793 if (props.markerfacecolor_is (
"auto"))
3796 graphics_object go = gh_mgr.
get_object (props.get___myhandle__ ());
3797 graphics_object ax = go.get_ancestor (
"axes");
3798 const axes::properties& ax_props
3799 =
dynamic_cast<const axes::properties&
> (ax.get_properties ());
3801 mfcolor = ax_props.get_color ().matrix_value ();
3804 init_marker (props.get_marker (), std::sqrt (s(0)),
3805 props.get_linewidth ());
3807 uint8_t clip_mask = (props.is_clipping () ? 0x7F : 0x40);
3808 uint8_t clip_ok = 0x40;
3824 for (
int i = 0; i < np; i++)
3826 if ((clip_code (
x(i), y(i), (has_z ? z(i) : 0.0)) & clip_mask)
3845 draw_marker (
x(i), y(i), (has_z ? z(i) : 0.0), lc, fc, mea, mfa);
3853 octave_unused_parameter (props);
3858 error_unexpected (
"opengl_renderer::draw_scatter");
3866#if defined (HAVE_OPENGL)
3872 float pos[4] = { 0, 0, 0, 0 };
3873 Matrix lpos = props.get_position ().matrix_value ();
3874 for (
int i = 0; i < 3; i++)
3876 if (props.style_is (
"local"))
3881 float col[4] = { 1, 1, 1, 1 };
3882 Matrix lcolor = props.get_color ().matrix_value ();
3883 for (
int i = 0; i < 3; i++)
3890 octave_unused_parameter (props);
3895 error_unexpected (
"opengl_renderer::draw_light");
3903 draw (props.get_children ());
3907opengl_renderer::set_ortho_coordinates ()
3909#if defined (HAVE_OPENGL)
3926 error_unexpected (
"opengl_renderer::set_ortho_coordinates");
3932opengl_renderer::restore_previous_coordinates ()
3934#if defined (HAVE_OPENGL)
3947 error_unexpected (
"opengl_renderer::restore_previous_coordinates");
3955#if defined (HAVE_OPENGL)
3957 if (props.get_string ().isempty () || props.color_is (
"none"))
3963 if (! props.is_clipping ()
3964 || (clip_code (pos(0), pos(1), pos.
numel () > 2 ? pos(2) : 0.0) == 0x40))
3972 render_text (props.get_pixels (), props.get_extent_matrix (),
3973 pos(0), pos(1), pos(2), props.get_rotation ());
3980 octave_unused_parameter (props);
3985 error_unexpected (
"opengl_renderer::draw_text");
3994#if defined (HAVE_OPENGL)
3996 Matrix bgcol = props.get_backgroundcolor_rgb ();
3997 Matrix ecol = props.get_edgecolor_rgb ();
4002 Matrix pos = props.get_data_position ();
4007 set_ortho_coordinates ();
4014 double rotation = props.get_rotation ();
4018 double m = points_to_pixels (props.get_margin ());
4019 const Matrix bbox = props.get_extent_matrix ();
4048 set_linestyle (props.get_linestyle (),
false, props.get_linewidth ());
4062 restore_previous_coordinates ();
4066 octave_unused_parameter (props);
4071 error_unexpected (
"opengl_renderer::draw_text_background");
4079#if defined (HAVE_OPENGL)
4082 Matrix x = props.get_xdata ().matrix_value ();
4083 Matrix y = props.get_ydata ().matrix_value ();
4085 draw_texture_image (cdata,
x, y);
4089 octave_unused_parameter (props);
4094 error_unexpected (
"opengl_renderer::draw_image");
4103#if defined (HAVE_OPENGL)
4108 double x0, x1, y0, y1;
4112 dx = (
x(1) -
x(0)) / (w - 1);
4119 dy = (y(1) - y(0)) / (h - 1);
4125 if (dv.
ndims () == 3 && (dv(2) == 3 || dv(2) == 4))
4127 opengl_texture tex = opengl_texture::create (
m_glfcns, cdata);
4128 if (tex.is_valid ())
4136 tex.tex_coord (0.0, 0.0);
4142 tex.tex_coord (1.0, 0.0);
4148 tex.tex_coord (1.0, 1.0);
4154 tex.tex_coord (0.0, 1.0);
4165 warning (
"opengl_renderer: invalid image size (expected MxNx3 or MxN)");
4169 octave_unused_parameter (cdata);
4170 octave_unused_parameter (
x);
4171 octave_unused_parameter (y);
4172 octave_unused_parameter (ortho);
4177 error_unexpected (
"opengl_renderer::draw_texture_image");
4189 for (
int i =
len-1; i >= 0; i--)
4191 graphics_object obj = gh_mgr.
get_object (hlist(i));
4194 draw (obj, toplevel);
4201#if defined (HAVE_OPENGL)
4207 octave_unused_parameter (w);
4208 octave_unused_parameter (h);
4213 error_unexpected (
"opengl_renderer::set_viewport");
4221 Matrix retval (1, 4, 0.0);
4223#if defined (HAVE_OPENGL)
4224#if defined (HAVE_FRAMEWORK_OPENGL)
4232 for (
int i = 0; i < 4; i++)
4240 error_unexpected (
"opengl_renderer::get_viewport_scaled");
4250#if defined (HAVE_OPENGL)
4259 octave_unused_parameter (c);
4264 error_unexpected (
"opengl_renderer::set_color");
4272 bool do_anti_alias = props.get (
"fontsmoothing").string_value () ==
"on";
4274 m_txt_renderer.
set_font (props.get (
"fontname").string_value (),
4275 props.get (
"fontweight").string_value (),
4276 props.get (
"fontangle").string_value (),
4277 props.get (
"__fontsize_points__").double_value ()
4284#if defined (HAVE_OPENGL)
4300 octave_unused_parameter (on);
4301 octave_unused_parameter (offset);
4306 error_unexpected (
"opengl_renderer::set_polygon_offset");
4314#if defined (HAVE_OPENGL)
4320 octave_unused_parameter (w);
4325 error_unexpected (
"opengl_renderer::set_linewidth");
4334#if defined (HAVE_OPENGL)
4336 int factor = math::round (points_to_pixels (linewidth) *
m_devpixratio);
4340 uint16_t pattern = 0xFFFF;
4372 if (solid && ! use_stipple)
4379 octave_unused_parameter (s);
4380 octave_unused_parameter (use_stipple);
4381 octave_unused_parameter (linewidth);
4386 error_unexpected (
"opengl_renderer::set_linestyle");
4393 double z1,
double z2)
4395#if defined (HAVE_OPENGL)
4397 double dx = (x2-x1);
4398 double dy = (y2-y1);
4399 double dz = (z2-z1);
4401 x1 -= 0.001*dx; x2 += 0.001*dx;
4402 y1 -= 0.001*dy; y2 += 0.001*dy;
4403 z1 -= 0.001*dz; z2 += 0.001*dz;
4407 p(0) = -1; p(3) = x2;
4409 p(0) = 1; p(3) = -x1;
4411 p(0) = 0; p(1) = -1; p(3) = y2;
4413 p(1) = 1; p(3) = -y1;
4415 p(1) = 0; p(2) = -1; p(3) = z2;
4417 p(2) = 1; p(3) = -z1;
4426 octave_unused_parameter (x1);
4427 octave_unused_parameter (x2);
4428 octave_unused_parameter (y1);
4429 octave_unused_parameter (y2);
4430 octave_unused_parameter (z1);
4431 octave_unused_parameter (z2);
4436 error_unexpected (
"opengl_renderer::set_clipbox");
4444#if defined (HAVE_OPENGL)
4448 if (enable != has_clipping)
4451 for (
int i = 0; i < 6; i++)
4454 for (
int i = 0; i < 6; i++)
4460 octave_unused_parameter (enable);
4465 error_unexpected (
"opengl_renderer::set_clipping");
4473#if defined (HAVE_OPENGL)
4486 m_marker_id = make_marker_list (m, size,
false);
4487 m_filled_marker_id = make_marker_list (m, size,
true);
4491 octave_unused_parameter (m);
4492 octave_unused_parameter (size);
4493 octave_unused_parameter (width);
4498 error_unexpected (
"opengl_renderer::init_marker");
4506#if defined (HAVE_OPENGL)
4508 m_marker_id = make_marker_list (m, size,
false);
4509 m_filled_marker_id = make_marker_list (m, size,
true);
4513 octave_unused_parameter (m);
4514 octave_unused_parameter (size);
4519 error_unexpected (
"opengl_renderer::change_marker");
4527#if defined (HAVE_OPENGL)
4543 error_unexpected (
"opengl_renderer::end_marker");
4551 const double la,
const double fa)
4553#if defined (HAVE_OPENGL)
4560 if (m_filled_marker_id > 0 && fc.
numel () > 0)
4565 if (lc.
numel () > 0)
4576 else if (m_marker_id > 0 && lc.
numel () > 0)
4584 octave_unused_parameter (
x);
4585 octave_unused_parameter (y);
4586 octave_unused_parameter (z);
4587 octave_unused_parameter (lc);
4588 octave_unused_parameter (fc);
4589 octave_unused_parameter (la);
4590 octave_unused_parameter (fa);
4595 error_unexpected (
"opengl_renderer::draw_marker");
4601opengl_renderer::init_maxlights ()
4603#if defined (HAVE_OPENGL)
4606 if (m_max_lights == 0)
4610 m_max_lights = max_lights;
4618 error_unexpected (
"opengl_renderer::init_maxlights");
4624opengl_renderer::get_string (
unsigned int id)
const
4626#if defined (HAVE_OPENGL)
4632 std::ostringstream buf;
4636 return std::string (buf.str ());
4640 octave_unused_parameter (
id);
4645 error_unexpected (
"opengl_renderer::get_string");
4646 return std::string ();
4652opengl_renderer::set_normal (
int bfl_mode,
const NDArray& n,
int j,
int i)
4654#if defined (HAVE_OPENGL)
4656 double x = n(j, i, 0);
4657 double y = n(j, i, 1);
4658 double z = n(j, i, 2);
4660 double d = sqrt (
x*
x + y*y + z*z);
4665 dir = ((
x*m_view_vector(0) + y*m_view_vector(1) + z*m_view_vector(2) < 0)
4666 ? ((bfl_mode > 1) ? 0.0 : -1.0) : 1.0);
4672 octave_unused_parameter (bfl_mode);
4673 octave_unused_parameter (n);
4674 octave_unused_parameter (j);
4675 octave_unused_parameter (i);
4680 error_unexpected (
"opengl_renderer::set_normal");
4686opengl_renderer::points_to_pixels (
const double val)
const
4692 static const double pix_per_pts =
4693 gh_mgr.
get_object (0).get (
"screenpixelsperinch").double_value () / 72.0;
4695 double retval = val;
4698 retval *= pix_per_pts;
4704opengl_renderer::make_marker_list (
const std::string& marker,
double size,
4707#if defined (HAVE_OPENGL)
4711 if (filled && (c ==
'+' || c ==
'x' || c ==
'*' || c ==
'.'
4712 || c ==
'|' || c ==
'_'))
4718 double sz = points_to_pixels (size);
4721 const double sqrt2d4 = 0.35355339059327;
4722 double tt = sz*sqrt2d4;
4773 if (sz > 0 && sz < 3)
4776 int div =
static_cast<int> (M_PI * sz / 12);
4779 div = std::max (div, 3);
4780 double ang_step = M_PI / div;
4783 for (
double ang = 0; ang < 2*M_PI; ang += ang_step)
4798 int div =
static_cast<int> (M_PI * sz / 4);
4801 div = std::max (div, 5);
4802 double ang_step = M_PI / div;
4805 for (
double ang = 0; ang < 2*M_PI; ang += ang_step)
4849 dr = 1.0 - sin (M_PI/10)/sin (3*M_PI/10)*1.02;
4852 for (
int i = 0; i < 2*5; i++)
4854 ang = (-0.5 +
double (i+1) / 5) * M_PI;
4855 r = 1.0 - (dr * fmod (
double (i+1), 2.0));
4864 dr = 1.0 - 0.5/sin (M_PI/3)*1.02;
4867 for (
int i = 0; i < 2*6; i++)
4869 ang = (0.5 +
double (i+1) / 6.0) * M_PI;
4870 r = 1.0 - (dr * fmod (
double (i+1), 2.0));
4877 warning (
"opengl_renderer: unsupported marker '%s'", marker.c_str ());
4887 octave_unused_parameter (marker);
4888 octave_unused_parameter (size);
4889 octave_unused_parameter (filled);
4894 error_unexpected (
"opengl_renderer::make_marker_list");
4903 int halign,
int valign,
double rotation)
4905 m_txt_renderer.
text_to_pixels (txt, pixels, bbox, halign, valign,
4906 rotation, m_interpreter);
4911 std::list<text_renderer::string>& lst,
4913 int halign,
int valign,
double rotation)
4916 rotation, m_interpreter);
4921 double x,
double y,
double z,
4922 int halign,
int valign,
double rotation)
4924#if defined (HAVE_OPENGL)
4931 if (m_txt_renderer.
ok ())
4943 octave_unused_parameter (txt);
4944 octave_unused_parameter (
x);
4945 octave_unused_parameter (y);
4946 octave_unused_parameter (z);
4947 octave_unused_parameter (halign);
4948 octave_unused_parameter (valign);
4949 octave_unused_parameter (rotation);
4954 error_unexpected (
"opengl_renderer::render_text");
4961 double x,
double y,
double z,
double rotation)
4963#if defined (HAVE_OPENGL)
4976 set_ortho_coordinates ();
4988 draw_texture_image (pixels.
permute (perm),
4989 xdata, ydata,
true);
4991 restore_previous_coordinates ();
5000 octave_unused_parameter (pixels);
5001 octave_unused_parameter (bbox);
5002 octave_unused_parameter (
x);
5003 octave_unused_parameter (y);
5004 octave_unused_parameter (z);
5005 octave_unused_parameter (rotation);
5010 error_unexpected (
"opengl_renderer::render_text");
5015OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
octave_idx_type rows() const
octave_idx_type columns() const
bool isempty() const
Size of the specified dimension.
const T * data() const
Size of the specified dimension.
T * rwdata()
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
MArray< T > permute(const Array< octave_idx_type > &vec, bool inv=false) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Vector representing the dimensions (size) of an Array.
octave_idx_type ndims() const
Number of dimensions.
graphics_object get_object(double val) const
uint16NDArray uint16_array_value() const
bool is_single_type() const
bool is_uint8_type() const
bool is_uint16_type() const
NDArray array_value(bool frc_str_conv=false) const
bool is_double_type() const
uint8NDArray uint8_array_value() const
FloatNDArray float_array_value(bool frc_str_conv=false) const
virtual GLboolean glIsEnabled(GLenum cap)
virtual void glHint(GLenum target, GLenum mode)
virtual void glGetIntegerv(GLenum pname, GLint *data)
virtual void glBegin(GLenum mode)
virtual void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
virtual void glClipPlane(GLenum plane, const GLdouble *equation)
virtual void glMatrixMode(GLenum mode)
virtual void glBindTexture(GLenum target, GLuint texture)
virtual void glVertex2d(GLdouble x, GLdouble y)
virtual void glNewList(GLuint list, GLenum mode)
virtual void glPopMatrix()
virtual void glVertex3d(GLdouble x, GLdouble y, GLdouble z)
virtual void glLineStipple(GLint factor, GLushort pattern)
virtual void glLoadIdentity()
virtual void glPolygonOffset(GLfloat factor, GLfloat units)
virtual void glLineWidth(GLfloat width)
virtual void glColor3fv(const GLfloat *v)
virtual void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
virtual void glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
virtual const GLubyte * glGetString(GLenum name)
virtual void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
virtual void glGenTextures(GLsizei n, GLuint *textures)
virtual void glDisable(GLenum cap)
virtual void glCallList(GLuint list)
virtual void glDepthFunc(GLenum fcn)
virtual void glClear(GLbitfield mask)
virtual void glNormal3dv(const GLdouble *v)
virtual void glColor3f(GLfloat red, GLfloat green, GLfloat blue)
virtual void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
virtual void glVertex3dv(const GLdouble *v)
virtual void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
virtual void glAlphaFunc(GLenum fcn, GLclampf ref)
virtual void glMaterialf(GLenum face, GLenum pname, GLfloat param)
virtual void glPolygonMode(GLenum face, GLenum mode)
virtual void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
virtual void glColor3dv(const GLdouble *v)
virtual GLuint glGenLists(GLsizei range)
virtual void glDeleteLists(GLuint list, GLsizei range)
virtual void glColor4fv(const GLfloat *v)
virtual void glTexParameteri(GLenum target, GLenum pname, GLint param)
virtual void glPopAttrib()
virtual void glEnable(GLenum cap)
virtual void glGetBooleanv(GLenum pname, GLboolean *data)
virtual void glBlendFunc(GLenum sfactor, GLenum dfactor)
virtual void glShadeModel(GLenum mode)
virtual void glEdgeFlag(GLboolean flag)
virtual void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)
virtual void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
virtual void glPushAttrib(GLbitfield mask)
virtual void glMultMatrixd(const GLdouble *m)
virtual void glPixelStorei(GLenum pname, GLint param)
virtual void glPushMatrix()
virtual void glScaled(GLdouble x, GLdouble y, GLdouble z)
virtual void glLightfv(GLenum light, GLenum pname, const GLfloat *params)
virtual GLenum glGetError()
virtual void glTranslated(GLdouble x, GLdouble y, GLdouble z)
virtual void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
virtual uint8NDArray get_pixels(int width, int height)
virtual void draw_patch(const patch::properties &props)
opengl_functions & m_glfcns
virtual void init_marker(const std::string &m, double size, float width)
virtual void set_linestyle(const std::string &s, bool stipple=false, double linewidth=0.5)
virtual void set_clipping(bool on)
virtual void text_to_pixels(const std::string &txt, uint8NDArray &pixels, Matrix &bbox, int halign=0, int valign=0, double rotation=0.0)
virtual void set_linewidth(float w)
virtual void draw_scatter(const scatter::properties &props)
virtual Matrix get_viewport_scaled() const
virtual void draw_line(const line::properties &props)
virtual void draw_uibuttongroup(const uibuttongroup::properties &props, const graphics_object &go)
opengl_renderer(opengl_functions &glfcns)
virtual void draw_text_background(const text::properties &props, bool do_rotate=false)
virtual Matrix render_text(const std::string &txt, double x, double y, double z, int halign, int valign, double rotation=0.0)
virtual void draw_image(const image::properties &props)
virtual void render_grid(const double linewidth, const std::string &gridstyle, const Matrix &gridcolor, const double gridalpha, const Matrix &ticks, double lim1, double lim2, double p1, double p1N, double p2, double p2N, int xyz, bool is_3D)
virtual void draw_marker(double x, double y, double z, const Matrix &lc, const Matrix &fc, const double la=1.0, const double fa=1.0)
virtual void init_gl_context(bool enhanced, const Matrix &backgroundColor)
virtual void draw(const graphics_object &go, bool toplevel=true)
virtual void draw_hggroup(const hggroup::properties &props)
virtual void draw_axes(const axes::properties &props)
virtual void change_marker(const std::string &m, double size)
virtual void set_polygon_offset(bool on, float offset=0.0f)
virtual void draw_surface(const surface::properties &props)
virtual void draw_uipanel(const uipanel::properties &props, const graphics_object &go)
virtual void draw_zoom_rect(int x1, int y1, int x2, int y2)
virtual void set_interpreter(const caseless_str &interp)
virtual void render_ticktexts(const Matrix &ticks, const string_vector &ticklabels, double lim1, double lim2, double p1, double p2, int xyz, int ha, int va, int &wmax, int &hmax)
virtual void draw_light(const light::properties &props)
virtual void draw_zoom_box(int width, int height, int x1, int y1, int x2, int y2, const Matrix &overlaycolor, double overlayalpha, const Matrix &bordercolor, double borderalpha, double borderwidth)
virtual void end_marker()
virtual void set_viewport(int w, int h)
virtual graphics_xform get_transform() const
virtual void draw_text(const text::properties &props)
virtual void set_font(const base_properties &props)
virtual void set_linecap(const std::string &)
virtual void draw_figure(const figure::properties &props)
virtual void text_to_strlist(const std::string &txt, std::list< text_renderer::string > &lst, Matrix &bbox, int halign=0, int valign=0, double rotation=0.0)
virtual void render_tickmarks(const Matrix &ticks, double lim1, double lim2, double p1, double p1N, double p2, double p2N, double dx, double dy, double dz, int xyz, bool doubleside, bool tickdir_both)
virtual void set_clipbox(double x1, double x2, double y1, double y2, double z1, double z2)
virtual void setup_opengl_transformation(const axes::properties &props)
virtual void set_linejoin(const std::string &)
virtual void set_color(const Matrix &c)
octave_idx_type numel() const
void text_to_strlist(const std::string &txt, std::list< string > &lst, Matrix &box, int halign, int valign, double rotation=0.0, const caseless_str &interpreter="tex")
void text_to_pixels(const std::string &txt, uint8NDArray &pxls, Matrix &bbox, int halign, int valign, double rotation=0.0, const caseless_str &interpreter="tex", bool handle_rotation=true)
void set_anti_aliasing(bool val)
void set_color(const Matrix &c)
void set_font(const std::string &name, const std::string &weight, const std::string &angle, double size)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
gh_manager & __get_gh_manager__()
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
std::complex< double > w(std::complex< double > z, double relerr=0)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)