27 #if defined (HAVE_OPENGL)
38 #define LIGHT_MODE GL_FRONT_AND_BACK
80 : id (),
w (), h (), tw (), th (), tx (), ty (),
81 valid (false), count (1)
84 texture_rep (GLuint id_arg,
int w_arg,
int h_arg,
int tw_arg,
int th_arg)
85 : id (id_arg),
w (w_arg), h (h_arg), tw (tw_arg), th (th_arg),
92 glDeleteTextures (1, &
id);
95 void bind (
int mode)
const
96 {
if (valid) glBindTexture (mode,
id); }
98 void tex_coord (
double q,
double r)
const
99 {
if (valid) glTexCoord2d (q*tx, r*ty); }
112 opengl_texture (texture_rep *_rep) : rep (_rep) { }
115 opengl_texture (
void) : rep (new texture_rep ()) { }
117 opengl_texture (
const opengl_texture& tx)
123 ~opengl_texture (
void)
125 if (--rep->count == 0)
129 opengl_texture& operator = (
const opengl_texture& tx)
131 if (--rep->count == 0)
140 static opengl_texture create (
const octave_value& data);
142 void bind (
int mode = GL_TEXTURE_2D)
const
143 { rep->bind (mode); }
145 void tex_coord (
double q,
double r)
const
146 { rep->tex_coord (q, r); }
148 bool is_valid (
void)
const
149 {
return rep->valid; }
153 next_power_of_2 (
int n)
166 opengl_texture retval;
171 if (dv.length () == 3 && dv(2) == 3)
176 h = dv(0), w = dv(1);
180 tw = next_power_of_2 (w);
181 th = next_power_of_2 (h);
183 glGenTextures (1, &
id);
184 glBindTexture (GL_TEXTURE_2D,
id);
192 for (
int i = 0; i < h; i++)
194 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
196 a[idx] = xdata(i,j,0);
197 a[idx+1] = xdata(i,j,1);
198 a[idx+2] = xdata(i,j,2);
202 glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0, GL_RGB, GL_FLOAT, a);
210 for (
int i = 0; i < h; i++)
212 for (
int j = 0, idx = i*tw*3; j <
w; j++, idx += 3)
214 a[idx] = xdata(i,j,0);
215 a[idx+1] = xdata(i,j,1);
216 a[idx+2] = xdata(i,j,2);
220 glTexImage2D (GL_TEXTURE_2D, 0, 3, tw, th, 0,
221 GL_RGB, GL_UNSIGNED_BYTE, a);
226 warning (
"opengl_texture::create: invalid texture data type (expected double or uint8)");
231 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
232 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
234 if (glGetError () != GL_NO_ERROR)
235 warning (
"opengl_texture::create: OpenGL error while generating texture data");
237 retval = opengl_texture (
new texture_rep (
id, w, h, tw, th));
241 warning (
"opengl_texture::create: invalid texture data size");
250 #if defined (HAVE_FRAMEWORK_OPENGL) && defined (HAVE_GLUTESSCALLBACK_THREEDOTS)
251 typedef GLvoid (CALLBACK *fcn) (...);
253 typedef void (CALLBACK *fcn) (void);
258 opengl_tesselator (
void) : glu_tess (0), fill () { init (); }
260 virtual ~opengl_tesselator (
void)
261 {
if (glu_tess) gluDeleteTess (glu_tess); }
263 void begin_polygon (
bool filled =
true)
265 gluTessProperty (glu_tess, GLU_TESS_BOUNDARY_ONLY,
266 (filled ? GL_FALSE : GL_TRUE));
268 gluTessBeginPolygon (glu_tess,
this);
271 void end_polygon (
void)
const
272 { gluTessEndPolygon (glu_tess); }
274 void begin_contour (
void)
const
275 { gluTessBeginContour (glu_tess); }
278 { gluTessEndContour (glu_tess); }
280 void add_vertex (
double *
loc,
void *data)
const
281 { gluTessVertex (glu_tess, loc, data); }
284 virtual void begin (GLenum ) { }
286 virtual void end (
void) { }
288 virtual void vertex (
void * ) { }
290 virtual void combine (GLdouble [3] ,
void * [4] ,
291 GLfloat [4] ,
void ** ) { }
293 virtual void edge_flag (GLboolean ) { }
295 virtual void error (GLenum err)
296 {
::error (
"OpenGL tesselation error (%d)", err); }
298 virtual void init (
void)
300 glu_tess = gluNewTess ();
302 gluTessCallback (glu_tess, GLU_TESS_BEGIN_DATA,
303 reinterpret_cast<fcn> (tess_begin));
304 gluTessCallback (glu_tess, GLU_TESS_END_DATA,
305 reinterpret_cast<fcn> (tess_end));
306 gluTessCallback (glu_tess, GLU_TESS_VERTEX_DATA,
307 reinterpret_cast<fcn> (tess_vertex));
308 gluTessCallback (glu_tess, GLU_TESS_COMBINE_DATA,
309 reinterpret_cast<fcn> (tess_combine));
310 gluTessCallback (glu_tess, GLU_TESS_EDGE_FLAG_DATA,
311 reinterpret_cast<fcn> (tess_edge_flag));
312 gluTessCallback (glu_tess, GLU_TESS_ERROR_DATA,
313 reinterpret_cast<fcn> (tess_error));
316 bool is_filled (
void)
const {
return fill; }
319 static void CALLBACK tess_begin (GLenum
type,
void *t)
320 {
reinterpret_cast<opengl_tesselator *
> (t)->begin (type); }
322 static void CALLBACK tess_end (
void *t)
323 {
reinterpret_cast<opengl_tesselator *
> (t)->end (); }
325 static void CALLBACK tess_vertex (
void *v,
void *t)
326 {
reinterpret_cast<opengl_tesselator *
> (t)->vertex (v); }
328 static void CALLBACK tess_combine (GLdouble c[3],
void *v[4], GLfloat w[4],
330 {
reinterpret_cast<opengl_tesselator *
> (t)->combine (c, v, w, out); }
332 static void CALLBACK tess_edge_flag (GLboolean flag,
void *t)
333 {
reinterpret_cast<opengl_tesselator *
> (t)->edge_flag (flag); }
335 static void CALLBACK tess_error (GLenum err,
void *t)
336 {
reinterpret_cast<opengl_tesselator *
> (t)->
error (err); }
342 opengl_tesselator (
const opengl_tesselator&);
344 opengl_tesselator operator = (
const opengl_tesselator&);
346 GLUtesselator *glu_tess;
354 class vertex_data_rep
369 vertex_data_rep (
void)
370 : coords (), color (), normal (), alpha (),
371 ambient (), diffuse (), specular (), specular_exp (),count (1) { }
374 double a,
float as,
float ds,
float ss,
float se)
375 : coords (c), color (col), normal (n), alpha (a),
376 ambient (as), diffuse (ds), specular (ss), specular_exp (se),
381 vertex_data_rep *rep;
383 vertex_data_rep *nil_rep (
void)
const
385 static vertex_data_rep *nr =
new vertex_data_rep ();
391 vertex_data (
void) : rep (nil_rep ())
394 vertex_data (
const vertex_data& v) : rep (v.rep)
398 double a,
float as,
float ds,
float ss,
float se)
399 : rep (new vertex_data_rep (c, col, n, a, as, ds, ss, se))
402 vertex_data (vertex_data_rep *new_rep)
407 if (--rep->count == 0)
411 vertex_data& operator = (
const vertex_data& v)
413 if (--rep->count == 0)
422 vertex_data_rep *get_rep (
void)
const {
return rep; }
426 opengl_renderer::patch_tesselator :
public opengl_tesselator
429 patch_tesselator (
opengl_renderer *r,
int cmode,
int lmode,
float idx = 0.0)
430 : opengl_tesselator (), renderer (r),
431 color_mode (cmode), light_mode (lmode), index (idx),
432 first (true), tmp_vdata ()
436 void begin (GLenum type)
441 if (color_mode == INTERP || light_mode == GOURAUD)
442 glShadeModel (GL_SMOOTH);
444 glShadeModel (GL_FLAT);
447 renderer->set_polygon_offset (
true, index);
456 renderer->set_polygon_offset (
false);
459 void vertex (
void *data)
461 vertex_data::vertex_data_rep *v
462 =
reinterpret_cast<vertex_data::vertex_data_rep *
> (data);
468 if (color_mode == INTERP || (color_mode == FLAT && ! is_filled ()))
472 if (col.
numel () == 3)
474 glColor3dv (col.
data ());
477 float buf[4] = { 0, 0, 0, 1 };
479 for (
int k = 0; k < 3; k++)
480 buf[k] = (v->ambient * col(k));
481 glMaterialfv (LIGHT_MODE, GL_AMBIENT, buf);
483 for (
int k = 0; k < 3; k++)
484 buf[k] = (v->diffuse * col(k));
485 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, buf);
490 if (light_mode > 0 && (first || light_mode == GOURAUD))
491 glNormal3dv (v->normal.data ());
493 glVertex3dv (v->coords.data ());
498 void combine (GLdouble xyz[3],
void *data[4], GLfloat w[4],
void **out_data)
502 vertex_data::vertex_data_rep *v[4];
505 for (
int i = 0; i < 4; i++)
507 v[i] =
reinterpret_cast<vertex_data::vertex_data_rep *
> (data[i]);
509 if (vmax == 4 && ! v[i])
522 if (v[0]->color.numel ())
525 for (
int ic = 0; ic < 3; ic++)
526 for (
int iv = 0; iv < vmax; iv++)
527 cc(ic) += (w[iv] * v[iv]->color (ic));
530 if (v[0]->normal.numel () > 0)
532 for (
int in = 0; in < 3; in++)
533 for (
int iv = 0; iv < vmax; iv++)
534 nn(in) += (w[iv] * v[iv]->normal (in));
537 for (
int iv = 0; iv < vmax; iv++)
538 aa += (w[iv] * v[iv]->alpha);
540 vertex_data new_v (vv, cc,
nn, aa, v[0]->ambient, v[0]->diffuse,
541 v[0]->specular, v[0]->specular_exp);
542 tmp_vdata.push_back (new_v);
544 *out_data = new_v.get_rep ();
551 patch_tesselator (
const patch_tesselator&);
553 patch_tesselator& operator = (
const patch_tesselator&);
560 std::list<vertex_data> tmp_vdata;
574 if (go.
isa (
"figure"))
575 draw_figure (dynamic_cast<const figure::properties&> (props));
576 else if (go.
isa (
"axes"))
577 draw_axes (dynamic_cast<const axes::properties&> (props));
578 else if (go.
isa (
"line"))
579 draw_line (dynamic_cast<const line::properties&> (props));
580 else if (go.
isa (
"surface"))
581 draw_surface (dynamic_cast<const surface::properties&> (props));
582 else if (go.
isa (
"patch"))
583 draw_patch (dynamic_cast<const patch::properties&> (props));
584 else if (go.
isa (
"hggroup"))
585 draw_hggroup (dynamic_cast<const hggroup::properties&> (props));
586 else if (go.
isa (
"text"))
587 draw_text (dynamic_cast<const text::properties&> (props));
588 else if (go.
isa (
"image"))
589 draw_image (dynamic_cast<const image::properties&> (props));
590 else if (go.
isa (
"uimenu") || go.
isa (
"uicontrol")
591 || go.
isa (
"uicontextmenu") || go.
isa (
"uitoolbar")
592 || go.
isa (
"uipushtool") || go.
isa (
"uitoggletool"))
594 else if (go.
isa (
"uipanel"))
597 draw_uipanel (dynamic_cast<const uipanel::properties&> (props), go);
601 warning (
"opengl_renderer: cannot render object of type '%s'",
637 opengl_renderer::init_gl_context (
bool enhanced,
const Matrix& c)
641 glEnable (GL_DEPTH_TEST);
642 glDepthFunc (GL_LEQUAL);
643 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
644 glAlphaFunc (GL_GREATER, 0.0
f);
645 glEnable (GL_NORMALIZE);
650 glEnable (GL_MULTISAMPLE);
651 GLint iMultiSample, iNumSamples;
652 glGetIntegerv (GL_SAMPLE_BUFFERS, &iMultiSample);
653 glGetIntegerv (GL_SAMPLES, &iNumSamples);
654 if (iMultiSample != GL_TRUE || iNumSamples == 0)
657 glDisable (GL_MULTISAMPLE);
658 glEnable (GL_LINE_SMOOTH);
659 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
664 glDisable (GL_BLEND);
665 glDisable (GL_LINE_SMOOTH);
672 glClearColor (c(0), c(1), c(2), 1);
673 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
678 opengl_renderer::render_grid (
const std::string& gridstyle,
679 const Matrix& ticks,
double lim1,
double lim2,
680 double p1,
double p1N,
double p2,
double p2N,
683 set_linestyle (gridstyle,
true);
685 for (
int i = 0; i < ticks.
numel (); i++)
687 double val = ticks(i);
688 if (lim1 <= val && val <= lim2)
692 glVertex3d (val, p1N, p2);
693 glVertex3d (val, p1, p2);
696 glVertex3d (val, p1, p2N);
697 glVertex3d (val, p1, p2);
700 else if (xyz == Y_AXIS)
702 glVertex3d (p1N, val, p2);
703 glVertex3d (p1, val, p2);
706 glVertex3d (p1, val, p2N);
707 glVertex3d (p1, val, p2);
710 else if (xyz == Z_AXIS)
712 glVertex3d (p1N, p2, val);
713 glVertex3d (p1, p2, val);
714 glVertex3d (p1, p2N, val);
715 glVertex3d (p1, p2, val);
720 set_linestyle (
"-",
true);
724 opengl_renderer::render_tickmarks (
const Matrix& ticks,
725 double lim1,
double lim2,
726 double p1,
double p1N,
727 double p2,
double p2N,
728 double dx,
double dy,
double dz,
729 int xyz,
bool mirror)
733 for (
int i = 0; i < ticks.
numel (); i++)
735 double val = ticks(i);
737 if (lim1 <= val && val <= lim2)
741 glVertex3d (val, p1, p2);
742 glVertex3d (val, p1+dy, p2+dz);
745 glVertex3d (val, p1N, p2N);
746 glVertex3d (val, p1N-dy, p2N-dz);
749 else if (xyz == Y_AXIS)
751 glVertex3d (p1, val, p2);
752 glVertex3d (p1+dx, val, p2+dz);
755 glVertex3d (p1N, val, p2N);
756 glVertex3d (p1N-dx, val, p2N-dz);
759 else if (xyz == Z_AXIS)
761 glVertex3d (p1, p2, val);
762 glVertex3d (p1+dx, p2+dy, val);
765 glVertex3d (p1N, p2N, val);
766 glVertex3d (p1N-dx, p2N-dy, val);
776 opengl_renderer::render_ticktexts (
const Matrix& ticks,
778 double lim1,
double lim2,
779 double p1,
double p2,
780 int xyz,
int ha,
int va,
781 int& wmax,
int& hmax)
783 int nticks = ticks.
numel ();
784 int nlabels = ticklabels.
numel ();
789 for (
int i = 0; i < nticks; i++)
791 double val = ticks(i);
793 if (lim1 <= val && val <= lim2)
797 std::string label (ticklabels(i % nlabels));
798 label.erase (0, label.find_first_not_of (
" "));
799 label = label.substr (0, label.find_last_not_of (
" ")+1);
805 b = render_text (label, val, p1, p2, ha, va);
807 else if (xyz == Y_AXIS)
809 b = render_text (label, p1, val, p2, ha, va);
811 else if (xyz == Z_AXIS)
813 b = render_text (label, p1, p2, val, ha, va);
816 wmax =
std::max (wmax, static_cast<int> (b(2)));
817 hmax =
std::max (hmax, static_cast<int> (b(3)));
823 opengl_renderer::setup_opengl_transformation (
const axes::properties& props)
829 xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2;
830 xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2;
835 #if defined (HAVE_FRAMEWORK_OPENGL)
841 glGetIntegerv (GL_VIEWPORT, vw);
843 glMatrixMode (GL_MODELVIEW);
846 glMultMatrixd (x_mat1.
data ());
847 glMatrixMode (GL_PROJECTION);
849 glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
850 glMultMatrixd (x_mat2.
data ());
851 glMatrixMode (GL_MODELVIEW);
853 glClear (GL_DEPTH_BUFFER_BIT);
876 set_color (axe_color);
877 set_polygon_offset (
true, 2.5);
884 glVertex3d (xPlane, yPlaneN, zPlaneN);
885 glVertex3d (xPlane, yPlane, zPlaneN);
886 glVertex3d (xPlane, yPlane, zPlane);
887 glVertex3d (xPlane, yPlaneN, zPlane);
890 glVertex3d (xPlaneN, yPlane, zPlaneN);
891 glVertex3d (xPlane, yPlane, zPlaneN);
892 glVertex3d (xPlane, yPlane, zPlane);
893 glVertex3d (xPlaneN, yPlane, zPlane);
897 glVertex3d (xPlaneN, yPlaneN, zPlane);
898 glVertex3d (xPlane, yPlaneN, zPlane);
899 glVertex3d (xPlane, yPlane, zPlane);
900 glVertex3d (xPlaneN, yPlane, zPlane);
904 set_polygon_offset (
false);
933 set_linestyle (
"-",
true);
939 std::swap (zpTick, zpTickN);
943 glVertex3d (xPlaneN, ypTick, zpTick);
944 glVertex3d (xPlane, ypTick, zpTick);
948 glVertex3d (xPlaneN, ypTickN, zpTick);
949 glVertex3d (xPlane, ypTickN, zpTick);
952 glVertex3d (xPlaneN, ypTickN, zpTickN);
953 glVertex3d (xPlane, ypTickN, zpTickN);
954 glVertex3d (xPlaneN, ypTick, zpTickN);
955 glVertex3d (xPlane, ypTick, zpTickN);
961 glVertex3d (xpTick, yPlaneN, zpTick);
962 glVertex3d (xpTick, yPlane, zpTick);
964 if (props.
is_box () && ! plotyy)
966 glVertex3d (xpTickN, yPlaneN, zpTick);
967 glVertex3d (xpTickN, yPlane, zpTick);
971 glVertex3d (xpTickN, yPlaneN, zpTickN);
972 glVertex3d (xpTickN, yPlane, zpTickN);
973 glVertex3d (xpTick, yPlaneN, zpTickN);
974 glVertex3d (xpTick, yPlane, zpTickN);
985 glVertex3d (xPlaneN, yPlane, zPlaneN);
986 glVertex3d (xPlaneN, yPlane, zPlane);
990 glVertex3d (xPlane, yPlaneN, zPlaneN);
991 glVertex3d (xPlane, yPlaneN, zPlane);
996 glVertex3d (xPlane, yPlane, zPlaneN);
997 glVertex3d (xPlane, yPlane, zPlane);
1001 glVertex3d (xPlane, yPlaneN, zPlaneN);
1002 glVertex3d (xPlane, yPlaneN, zPlane);
1006 glVertex3d (xPlaneN, yPlane, zPlaneN);
1007 glVertex3d (xPlaneN, yPlane, zPlane);
1010 glVertex3d (xPlaneN, yPlaneN, zPlaneN);
1011 glVertex3d (xPlaneN, yPlaneN, zPlane);
1032 double fy = props.
get_fy ();
1033 double fz = props.
get_fz ();
1049 bool do_xgrid = (props.
is_xgrid () && (gridstyle !=
"none"));
1051 && (minorgridstyle !=
"none"));
1058 bool tick_along_z = nearhoriz ||
xisinf (fy);
1065 render_grid (gridstyle, xticks, x_min, x_max,
1066 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane,
1072 render_tickmarks (xticks, x_min, x_max, ypTick, ypTick,
1073 zpTick, zpTickN, 0., 0.,
1074 signum (zpTick-zpTickN)*fz*xticklen,
1079 render_tickmarks (xticks, x_min, x_max, ypTick, ypTickN,
1081 signum (ypTick-ypTickN)*fy*xticklen,
1086 if (xticklabels.
numel () > 0)
1088 int halign = (xstate ==
AXE_HORZ_DIR ? 1 : (xyzSym ? 0 : 2));
1089 int valign = (xstate ==
AXE_VERT_DIR ? 1 : (x2Dtop ? 0 : 2));
1092 render_ticktexts (xticks, xticklabels, x_min, x_max, ypTick,
1093 zpTick+
signum (zpTick-zpTickN)*fz*xtickoffset,
1094 0, halign, valign, wmax, hmax);
1096 render_ticktexts (xticks, xticklabels, x_min, x_max,
1097 ypTick+
signum (ypTick-ypTickN)*fy*xtickoffset,
1098 zpTick, 0, halign, valign, wmax, hmax);
1103 render_grid (minorgridstyle, xmticks, x_min, x_max,
1104 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane,
1111 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTick,
1112 zpTick, zpTickN, 0., 0.,
1113 signum (zpTick-zpTickN)*fz*xticklen/2,
1116 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTickN,
1118 signum (ypTick-ypTickN)*fy*xticklen/2,
1142 double fx = props.
get_fx ();
1143 double fz = props.
get_fz ();
1159 bool do_ygrid = (props.
is_ygrid () && (gridstyle !=
"none"));
1161 && (minorgridstyle !=
"none"));
1168 bool tick_along_z = nearhoriz ||
xisinf (fx);
1176 render_grid (gridstyle, yticks, y_min, y_max,
1177 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane,
1182 render_tickmarks (yticks, y_min, y_max, xpTick, xpTick,
1183 zpTick, zpTickN, 0., 0.,
1184 signum (zpTick-zpTickN)*fz*yticklen,
1187 render_tickmarks (yticks, y_min, y_max, xpTick, xpTickN,
1189 signum (xPlaneN-xPlane)*fx*yticklen,
1193 if (yticklabels.
numel () > 0)
1196 ? 1 : (!xyzSym || y2Dright ? 0 : 2));
1200 render_ticktexts (yticks, yticklabels, y_min, y_max, xpTick,
1201 zpTick+
signum (zpTick-zpTickN)*fz*ytickoffset,
1202 1, halign, valign, wmax, hmax);
1204 render_ticktexts (yticks, yticklabels, y_min, y_max,
1205 xpTick+
signum (xpTick-xpTickN)*fx*ytickoffset,
1206 zpTick, 1, halign, valign, wmax, hmax);
1211 render_grid (minorgridstyle, ymticks, y_min, y_max,
1212 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane,
1219 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTick,
1220 zpTick, zpTickN, 0., 0.,
1221 signum (zpTick-zpTickN)*fz*yticklen/2,
1224 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTickN,
1226 signum (xpTick-xpTickN)*fx*yticklen/2,
1247 double fx = props.
get_fx ();
1248 double fy = props.
get_fy ();
1260 bool do_zgrid = (props.
is_zgrid () && (gridstyle !=
"none"));
1262 && (minorgridstyle !=
"none"));
1275 render_grid (gridstyle, zticks, z_min, z_max,
1276 xPlane, xPlaneN, yPlane, yPlaneN, 2,
true);
1282 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane,
1284 signum (xPlaneN-xPlane)*fx*zticklen,
1287 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlaneN,
1289 signum (yPlane-yPlaneN)*fy*zticklen,
1295 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane,
1296 yPlaneN, yPlane, 0.,
1297 signum (yPlaneN-yPlane)*fy*zticklen,
1300 render_tickmarks (zticks, z_min, z_max, xPlane, xPlane,
1302 signum (xPlane-xPlaneN)*fx*zticklen,
1307 if (zticklabels.
numel () > 0)
1310 int valign = (zstate ==
AXE_VERT_DIR ? 1 : (zSign ? 3 : 2));
1315 render_ticktexts (zticks, zticklabels, z_min, z_max,
1316 xPlaneN+
signum (xPlaneN-xPlane)*fx*ztickoffset,
1317 yPlane, 2, halign, valign, wmax, hmax);
1319 render_ticktexts (zticks, zticklabels, z_min, z_max, xPlaneN,
1320 yPlane+
signum (yPlane-yPlaneN)*fy*ztickoffset,
1321 2, halign, valign, wmax, hmax);
1326 render_ticktexts (zticks, zticklabels, z_min, z_max, xPlane,
1327 yPlaneN+
signum (yPlaneN-yPlane)*fy*ztickoffset,
1328 2, halign, valign, wmax, hmax);
1330 render_ticktexts (zticks, zticklabels, z_min, z_max,
1331 xPlane+
signum (xPlane-xPlaneN)*fx*ztickoffset,
1332 yPlaneN, 2, halign, valign, wmax, hmax);
1338 render_grid (minorgridstyle, zmticks, z_min, z_max,
1339 xPlane, xPlaneN, yPlane, yPlaneN, 2,
true);
1347 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlane,
1349 signum (xPlaneN-xPlane)*fx*zticklen/2,
1352 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlaneN,
1354 signum (yPlane-yPlaneN)*fy*zticklen/2,
1360 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane,
1361 yPlaneN, yPlane, 0.,
1362 signum (yPlaneN-yPlane)*fy*zticklen/2,
1365 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane,
1367 signum (xPlane-xPlaneN)*fx*zticklen/2,
1384 std::list<graphics_object> obj_list;
1385 std::list<graphics_object>::iterator it;
1398 if (go.
isa (
"light"))
1401 obj_list.push_back (go);
1407 it = obj_list.begin ();
1408 while (it != obj_list.end ())
1419 it = obj_list.erase (it);
1427 glDisable (GL_DEPTH_TEST);
1429 for (it = obj_list.begin (); it != obj_list.end (); it++)
1437 glEnable (GL_DEPTH_TEST);
1439 set_clipping (
false);
1457 if (x_max > floatmax || y_max > floatmax || z_max > floatmax
1458 || x_min < -floatmax || y_min < -floatmax || z_min < -floatmax)
1460 warning (
"opengl_renderer: data values greater than float capacity. (1) Scale data, or (2) Use gnuplot");
1464 setup_opengl_transformation (props);
1467 GLboolean antialias;
1468 glGetBooleanv (GL_LINE_SMOOTH, &antialias);
1469 if (antialias == GL_TRUE)
1470 glDisable (GL_LINE_SMOOTH);
1474 draw_axes_planes (props);
1475 draw_axes_boxes (props);
1479 draw_axes_x_grid (props);
1480 draw_axes_y_grid (props);
1481 draw_axes_z_grid (props);
1483 set_linestyle (
"-");
1485 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
1488 if (antialias == GL_TRUE)
1489 glEnable (GL_LINE_SMOOTH);
1491 draw_axes_children (props);
1501 bool has_z = (z.
numel () > 0);
1507 std::vector<octave_uint8> clip (n);
1510 for (
int i = 0; i < n; i++)
1511 clip[i] = (clip_code (
x(i), y(i), z(i)) & clip_mask);
1514 double z_mid = (zmin+zmax)/2;
1516 for (
int i = 0; i < n; i++)
1517 clip[i] = (clip_code (
x(i), y(i), z_mid) & clip_mask);
1530 for (
int i = 1; i < n; i++)
1532 if ((clip[i-1] & clip[i]) == clip_ok)
1537 glBegin (GL_LINE_STRIP);
1538 glVertex3d (
x(i-1), y(i-1), z(i-1));
1540 glVertex3d (
x(i), y(i), z(i));
1556 for (
int i = 1; i < n; i++)
1558 if ((clip[i-1] & clip[i]) == clip_ok)
1563 glBegin (GL_LINE_STRIP);
1564 glVertex2d (
x(i-1), y(i-1));
1566 glVertex2d (
x(i), y(i));
1579 set_linewidth (0.5);
1580 set_linestyle (
"-");
1583 set_clipping (
false);
1604 for (
int i = 0; i < n; i++)
1606 if (clip[i] == clip_ok)
1607 draw_marker (
x(i), y(i),
1635 warning (
"opengl_renderer: phong light model not supported");
1653 Matrix fcolor = (fc_mode == TEXTURE ?
Matrix (1, 3, 1.0)
1654 : props.get_facecolor_rgb ());
1661 float cb[4] = { 0.0, 0.0, 0.0, 1.0 };
1667 bool x_mat = (x.
rows () == z.
rows ());
1670 i1 = i2 = j1 = j2 = 0;
1672 if ((fc_mode > 0 && fc_mode < 3) || ec_mode > 0)
1677 for (
int i = 0; i < zr; i++)
1682 for (
int j = 0; j < zc; j++)
1691 if (fa_mode > 0 || ea_mode > 0)
1697 if (fl_mode > 0 || el_mode > 0)
1699 float buf[4] = { ss, ss, ss, 1 };
1701 glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
1702 glMaterialf (LIGHT_MODE, GL_SHININESS, se);
1707 if (fc_mode == TEXTURE)
1714 if (fc_mode == UNIFORM || fc_mode == TEXTURE)
1716 glColor3dv (fcolor.
data ());
1719 for (
int i = 0; i < 3; i++)
1720 cb[i] = as * fcolor(i);
1721 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1723 for (
int i = 0; i < 3; i++)
1724 cb[i] = ds * fcolor(i);
1725 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1730 glEnable (GL_LIGHTING);
1731 glShadeModel ((fc_mode == INTERP || fl_mode == GOURAUD) ? GL_SMOOTH
1733 set_polygon_offset (
true, 1);
1734 if (fc_mode == TEXTURE)
1735 glEnable (GL_TEXTURE_2D);
1737 for (
int i = 1; i < zc; i++)
1745 for (
int j = 1; j < zr; j++)
1748 if (clip(j-1, i-1) || clip(j, i-1)
1749 || clip(j-1, i) || clip(j, i))
1752 if (fc_mode == FLAT)
1758 else if (fc_mode == INTERP)
1775 if (fc_mode == TEXTURE)
1776 tex.tex_coord (
double (i-1) / (zc-1),
1777 double (j-1) / (zr-1));
1778 else if (fc_mode > 0)
1781 for (
int k = 0; k < 3; k++)
1782 cb[k] = c(j-1, i-1, k);
1787 for (
int k = 0; k < 3; k++)
1789 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1791 for (
int k = 0; k < 3; k++)
1792 cb[k] = ds * c(j-1, i-1, k);
1793 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1798 d = sqrt (n(j-1,i-1,0) * n(j-1,i-1,0)
1799 + n(j-1,i-1,1) * n(j-1,i-1,1)
1800 + n(j-1,i-1,2) * n(j-1,i-1,2));
1801 glNormal3d (n(j-1,i-1,0)/d,
1805 glVertex3d (
x(j1,i-1), y(j-1,i1), z(j-1,i-1));
1808 if (fc_mode == TEXTURE)
1809 tex.tex_coord (
double (i) / (zc-1),
double (j-1) / (zr-1));
1810 else if (fc_mode == INTERP)
1812 for (
int k = 0; k < 3; k++)
1813 cb[k] = c(j-1, i, k);
1818 for (
int k = 0; k < 3; k++)
1820 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1822 for (
int k = 0; k < 3; k++)
1823 cb[k] = ds * c(j-1, i, k);
1824 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1828 if (fl_mode == GOURAUD)
1830 d = sqrt (n(j-1,i,0) * n(j-1,i,0)
1831 + n(j-1,i,1) * n(j-1,i,1)
1832 + n(j-1,i,2) * n(j-1,i,2));
1833 glNormal3d (n(j-1,i,0)/d, n(j-1,i,1)/d, n(j-1,i,2)/d);
1836 glVertex3d (
x(j1,i), y(j-1,i2), z(j-1,i));
1839 if (fc_mode == TEXTURE)
1840 tex.tex_coord (
double (i) / (zc-1),
double (j) / (zr-1));
1841 else if (fc_mode == INTERP)
1843 for (
int k = 0; k < 3; k++)
1849 for (
int k = 0; k < 3; k++)
1851 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1853 for (
int k = 0; k < 3; k++)
1854 cb[k] = ds * c(j, i, k);
1855 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1858 if (fl_mode == GOURAUD)
1860 d = sqrt (n(j,i,0) * n(j,i,0)
1861 + n(j,i,1) * n(j,i,1)
1862 + n(j,i,2) * n(j,i,2));
1863 glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
1865 glVertex3d (
x(j2,i), y(j,i2), z(j,i));
1868 if (fc_mode == TEXTURE)
1869 tex.tex_coord (
double (i-1) / (zc-1),
double (j) / (zr-1));
1870 else if (fc_mode == INTERP)
1872 for (
int k = 0; k < 3; k++)
1873 cb[k] = c(j, i-1, k);
1878 for (
int k = 0; k < 3; k++)
1880 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1882 for (
int k = 0; k < 3; k++)
1883 cb[k] = ds * c(j, i-1, k);
1884 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1887 if (fl_mode == GOURAUD)
1889 d = sqrt (n(j,i-1,0) * n(j,i-1,0)
1890 + n(j,i-1,1) * n(j,i-1,1)
1891 + n(j,i-1,2) * n(j,i-1,2));
1892 glNormal3d (n(j,i-1,0)/d, n(j,i-1,1)/d, n(j,i-1,2)/d);
1894 glVertex3d (
x(j2,i-1), y(j,i1), z(j,i-1));
1900 set_polygon_offset (
false);
1901 if (fc_mode == TEXTURE)
1902 glDisable (GL_TEXTURE_2D);
1905 glDisable (GL_LIGHTING);
1917 if (ec_mode == UNIFORM)
1919 glColor3dv (ecolor.
data ());
1922 for (
int i = 0; i < 3; i++)
1923 cb[i] = as * ecolor(i);
1924 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1926 for (
int i = 0; i < 3; i++)
1927 cb[i] = ds * ecolor(i);
1928 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1933 glEnable (GL_LIGHTING);
1934 glShadeModel ((ec_mode == INTERP || el_mode == GOURAUD) ? GL_SMOOTH
1944 for (
int i = 0; i < zc; i++)
1952 for (
int j = 1; j < zr; j++)
1954 if (clip(j-1,i) || clip(j,i))
1957 if (ec_mode == FLAT)
1963 else if (ec_mode == INTERP)
1981 for (
int k = 0; k < 3; k++)
1982 cb[k] = c(j-1, i, k);
1987 for (
int k = 0; k < 3; k++)
1989 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
1991 for (
int k = 0; k < 3; k++)
1992 cb[k] = ds * c(j-1, i, k);
1993 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
1998 d = sqrt (n(j-1,i,0) * n(j-1,i,0)
1999 + n(j-1,i,1) * n(j-1,i,1)
2000 + n(j-1,i,2) * n(j-1,i,2));
2001 glNormal3d (n(j-1,i,0)/d, n(j-1,i,1)/d, n(j-1,i,2)/d);
2003 glVertex3d (
x(j1,i), y(j-1,i2), z(j-1,i));
2006 if (ec_mode == INTERP)
2008 for (
int k = 0; k < 3; k++)
2014 for (
int k = 0; k < 3; k++)
2016 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2018 for (
int k = 0; k < 3; k++)
2019 cb[k] = ds * c(j, i, k);
2020 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2023 if (el_mode == GOURAUD)
2025 d = sqrt (n(j,i,0) * n(j,i,0)
2026 + n(j,i,1) * n(j,i,1)
2027 + n(j,i,2) * n(j,i,2));
2028 glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
2030 glVertex3d (
x(j2,i), y(j,i2), z(j,i));
2041 for (
int j = 0; j < zr; j++)
2049 for (
int i = 1; i < zc; i++)
2051 if (clip(j,i-1) || clip(j,i))
2054 if (ec_mode == FLAT)
2060 else if (ec_mode == INTERP)
2078 for (
int k = 0; k < 3; k++)
2079 cb[k] = c(j, i-1, k);
2084 for (
int k = 0; k < 3; k++)
2086 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2088 for (
int k = 0; k < 3; k++)
2089 cb[k] = ds * c(j, i-1, k);
2090 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2095 d = sqrt (n(j,i-1,0) * n(j,i-1,0)
2096 + n(j,i-1,1) * n(j,i-1,1)
2097 + n(j,i-1,2) * n(j,i-1,2));
2098 glNormal3d (n(j,i-1,0)/d, n(j,i-1,1)/d, n(j,i-1,2)/d);
2100 glVertex3d (
x(j2,i-1), y(j,i1), z(j,i-1));
2103 if (ec_mode == INTERP)
2105 for (
int k = 0; k < 3; k++)
2111 for (
int k = 0; k < 3; k++)
2113 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2115 for (
int k = 0; k < 3; k++)
2116 cb[k] = ds * c(j, i, k);
2117 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2120 if (el_mode == GOURAUD)
2122 d = sqrt (n(j,i,0) * n(j,i,0)
2123 + n(j,i,1) * n(j,i,1)
2124 + n(j,i,2) * n(j,i,2));
2125 glNormal3d (n(j,i,0)/d, n(j,i,1)/d, n(j,i,2)/d);
2127 glVertex3d (
x(j2,i), y(j,i2), z(j,i));
2134 set_linestyle (
"-");
2135 set_linewidth (0.5);
2138 glDisable (GL_LIGHTING);
2159 Matrix cc (1, 3, 0.0);
2173 if ((mecolor.
numel () == 0 || mfcolor.
numel () == 0)
2180 for (
int i = 0; i < zc; i++)
2185 for (
int j = 0; j < zr; j++)
2193 if ((do_edge && mecolor.
numel () == 0)
2194 || (do_face && mfcolor.
numel () == 0))
2199 for (
int k = 0; k < 3; k++)
2203 Matrix lc = (do_edge ? (mecolor.
numel () == 0 ? cc : mecolor)
2205 Matrix fc = (do_face ? (mfcolor.
numel () == 0 ? cc : mfcolor)
2208 draw_marker (
x(j1,i), y(j,i1), z(j,i), lc, fc);
2225 warning (
"opengl_renderer: %s. Not rendering.", msg.c_str ());
2239 bool has_z = (v.
columns () > 2);
2240 bool has_facecolor =
false;
2241 bool has_facealpha =
false;
2269 for (
int i = 0; i < nv; i++)
2272 for (
int i = 0; i < nv; i++)
2278 for (
int i = 0; i < nf; i++)
2283 for (
int j = 0; j < fcmax && !
xisnan (
f(i,j)); j++, count++)
2284 fclip = (fclip || clip(
int (
f(i,j) - 1)));
2290 if (fc_mode > 0 || ec_mode > 0)
2313 has_facecolor = ((c.
numel () > 0) && (c.
rows () == f.
rows ()));
2316 if (fa_mode > 0 || ea_mode > 0)
2320 has_facealpha = ((a.
numel () > 0) && (a.
rows () == f.
rows ()));
2324 std::vector<vertex_data> vdata (f.
numel ());
2326 for (
int i = 0; i < nf; i++)
2327 for (
int j = 0; j < count_f(i); j++)
2329 int idx =
int (
f(i,j) - 1);
2331 Matrix vv (1, 3, 0.0);
2333 Matrix
nn (1, 3, 0.0);
2336 vv(0) = v(idx,0); vv(1) = v(idx,1);
2345 cc(0) = c(i,0), cc(1) = c(i,1), cc(2) = c(i,2);
2347 cc(0) = c(idx,0), cc(1) = c(idx,1), cc(2) = c(idx,2);
2357 vdata[i+j*fr] = vertex_data (vv, cc,
nn, aa, as, ds, ss, se);
2360 if (fl_mode > 0 || el_mode > 0)
2362 float buf[4] = { ss, ss, ss, 1 };
2364 glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
2365 glMaterialf (LIGHT_MODE, GL_SHININESS, se);
2373 if (fc_mode == UNIFORM)
2375 glColor3dv (fcolor.
data ());
2378 float cb[4] = { 0, 0, 0, 1 };
2380 for (
int i = 0; i < 3; i++)
2381 cb[i] = (as * fcolor(i));
2382 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2384 for (
int i = 0; i < 3; i++)
2385 cb[i] = ds * fcolor(i);
2386 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2391 glEnable (GL_LIGHTING);
2397 patch_tesselator tess (
this, fc_mode, fl_mode, 1.0);
2399 for (
int i = 0; i < nf; i++)
2404 tess.begin_polygon (
true);
2405 tess.begin_contour ();
2408 for (
int j = count_f(i)-1; j > 0; j--)
2410 vertex_data::vertex_data_rep *vv = vdata[i+j*fr].get_rep ();
2412 tess.add_vertex (vv->coords.fortran_vec (), vv);
2417 vertex_data::vertex_data_rep *vv = vdata[i].get_rep ();
2419 if (fc_mode == FLAT)
2422 Matrix col = vv->color;
2424 if (col.
numel () == 3)
2426 glColor3dv (col.
data ());
2429 float cb[4] = { 0, 0, 0, 1 };
2431 for (
int k = 0; k < 3; k++)
2432 cb[k] = (vv->ambient * col(k));
2433 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2435 for (
int k = 0; k < 3; k++)
2436 cb[k] = (vv->diffuse * col(k));
2437 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2442 tess.add_vertex (vv->coords.fortran_vec (), vv);
2445 tess.end_contour ();
2446 tess.end_polygon ();
2450 glDisable (GL_LIGHTING);
2463 if (ec_mode == UNIFORM)
2465 glColor3dv (ecolor.
data ());
2468 float cb[4] = { 0, 0, 0, 1 };
2470 for (
int i = 0; i < 3; i++)
2471 cb[i] = (as * ecolor(i));
2472 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
2474 for (
int i = 0; i < 3; i++)
2475 cb[i] = ds * ecolor(i);
2476 glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
2481 glEnable (GL_LIGHTING);
2491 patch_tesselator tess (
this, ec_mode, el_mode);
2493 for (
int i = 0; i < nf; i++)
2500 glShadeModel ((ec_mode == INTERP || el_mode == GOURAUD)
2501 ? GL_SMOOTH : GL_FLAT);
2504 for (
int j = count_f(i)-1; j >= 0; j--)
2506 if (! clip(
int (
f(i,j) - 1)))
2508 vertex_data::vertex_data_rep *vv
2509 = vdata[i+j*fr].get_rep ();
2510 const Matrix m = vv->coords;
2514 glBegin (GL_LINE_STRIP);
2516 if (ec_mode != UNIFORM)
2518 Matrix col = vv->color;
2520 if (col.
numel () == 3)
2521 glColor3dv (col.
data ());
2523 glVertex3d (m(0), m(1), m(2));
2533 int j = count_f(i)-1;
2534 if (flag && ! clip(
int (
f(i,j) - 1)))
2536 vertex_data::vertex_data_rep *vv
2537 = vdata[i+j*fr].get_rep ();
2538 const Matrix m = vv->coords;
2539 if (ec_mode != UNIFORM)
2541 Matrix col = vv->color;
2543 if (col.
numel () == 3)
2544 glColor3dv (col.
data ());
2546 glVertex3d (m(0), m(1), m(2));
2554 tess.begin_polygon (
false);
2555 tess.begin_contour ();
2557 for (
int j = count_f(i)-1; j >= 0; j--)
2559 vertex_data::vertex_data_rep *vv
2560 = vdata[i+j*fr].get_rep ();
2561 tess.add_vertex (vv->coords.fortran_vec (), vv);
2564 tess.end_contour ();
2565 tess.end_polygon ();
2569 set_linestyle (
"-");
2570 set_linewidth (0.5);
2573 glDisable (GL_LIGHTING);
2591 bool has_markerfacecolor =
false;
2598 if (mc.
rows () == 1)
2602 if (mfcolor.
numel () == 0
2606 if (mecolor.
numel () == 0
2612 if (c.
numel () == 0)
2614 has_markerfacecolor = ((c.
numel () > 0)
2623 for (
int i = 0; i < nf; i++)
2624 for (
int j = 0; j < count_f(i); j++)
2626 int idx =
int (
f(i,j) - 1);
2635 if (has_markerfacecolor)
2636 cc(0) = c(i,0), cc(1) = c(i,1), cc(2) = c(i,2);
2638 cc(0) = c(idx,0), cc(1) = c(idx,1), cc(2) = c(idx,2);
2641 Matrix lc = (do_edge ? (mecolor.
numel () == 0 ? cc : mecolor)
2643 Matrix fc = (do_face ? (mfcolor.
numel () == 0 ? cc : mfcolor)
2646 draw_marker (v(idx,0), v(idx,1), (has_z ? v(idx,2) : 0), lc, fc);
2671 bool blend = glIsEnabled (GL_BLEND);
2673 glEnable (GL_BLEND);
2674 glEnable (GL_ALPHA_TEST);
2675 glRasterPos3d (pos(0), pos(1), pos.
numel () > 2 ? pos(2) : 0.0);
2676 glBitmap (0, 0, 0, 0, bbox(0), bbox(1), 0);
2677 glDrawPixels (bbox(2), bbox(3),
2679 glDisable (GL_ALPHA_TEST);
2681 glDisable (GL_BLEND);
2700 if (w > 1 &&
x(1) ==
x(0))
2701 x(1) =
x(1) + (w-1);
2703 if (h > 1 && y(1) == y(0))
2704 y(1) = y(1) + (h-1);
2711 warning (
"opengl_renderer: image X,Y data too large to draw");
2716 float pix_dx, pix_dy;
2718 float nor_dx, nor_dy;
2722 pix_dx = (p1(0) - p0(0))/(w-1);
2723 nor_dx = (
x(1) -
x(0))/(w-1);
2728 pix_dx = p1w(0) - p0(0);
2734 pix_dy = (p1(1) - p0(1))/(h-1);
2735 nor_dy = (y(1) - y(0))/(h-1);
2740 pix_dy = p1h(1) - p0(1);
2751 float im_xmin =
x(0) - nor_dx/2;
2752 float im_xmax =
x(1) + nor_dx/2;
2753 float im_ymin = y(0) - nor_dy/2;
2754 float im_ymax = y(1) + nor_dy/2;
2758 j0 += (
xmin - im_xmin)/nor_dx + 1;
2760 j1 -= (im_xmax -
xmax)/nor_dx ;
2763 i0 += (ymin - im_ymin)/nor_dy + 1;
2765 i1 -= (im_ymax - ymax)/nor_dy;
2770 glGetFloatv (GL_VIEWPORT, vp);
2775 if (i0 >= i1 || j0 >= j1)
2778 glPixelZoom (pix_dx, -pix_dy);
2779 glRasterPos3d (im_xmin + nor_dx*j0, im_ymin + nor_dy*i0, 0);
2782 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
2785 if (dv.length () == 3 && dv(2) == 3)
2793 for (
int i = i0; i < i1; i++)
2795 for (
int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
2797 a[idx] = xcdata(i,j,0);
2798 a[idx+1] = xcdata(i,j,1);
2799 a[idx+2] = xcdata(i,j,2);
2803 draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
2812 for (
int i = i0; i < i1; i++)
2814 for (
int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
2816 a[idx] = xcdata(i,j,0);
2817 a[idx+1] = xcdata(i,j,1);
2818 a[idx+2] = xcdata(i,j,2);
2822 draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
2831 for (
int i = i0; i < i1; i++)
2833 for (
int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
2835 a[idx] = xcdata(i,j,0);
2836 a[idx+1] = xcdata(i,j,1);
2837 a[idx+2] = xcdata(i,j,2);
2841 draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a);
2850 for (
int i = i0; i < i1; i++)
2852 for (
int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
2854 a[idx] = xcdata(i,j,0);
2855 a[idx+1] = xcdata(i,j,1);
2856 a[idx+2] = xcdata(i,j,2);
2860 draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_SHORT, a);
2864 warning (
"opengl_renderer: invalid image data type (expected double, single, uint8, or uint16)");
2867 warning (
"opengl_renderer: invalid image size (expected MxNx3 or MxN)");
2873 opengl_renderer::set_viewport (
int w,
int h)
2875 glViewport (0, 0, w, h);
2879 opengl_renderer::draw_pixels (GLsizei width, GLsizei height, GLenum format,
2880 GLenum type,
const GLvoid *data)
2882 glDrawPixels (width, height, format, type, data);
2886 opengl_renderer::set_color (
const Matrix& c)
2888 glColor3dv (c.
data ());
2890 text_renderer.set_color (c);
2906 opengl_renderer::set_polygon_offset (
bool on,
float offset)
2910 glEnable (GL_POLYGON_OFFSET_FILL);
2911 glEnable (GL_POLYGON_OFFSET_LINE);
2912 glPolygonOffset (offset, offset);
2916 glDisable (GL_POLYGON_OFFSET_FILL);
2917 glDisable (GL_POLYGON_OFFSET_LINE);
2922 opengl_renderer::set_linewidth (
float w)
2928 opengl_renderer::set_linestyle (
const std::string& s,
bool use_stipple)
2934 glLineStipple (1, static_cast<unsigned short> (0xFFFF));
2938 glLineStipple (1, static_cast<unsigned short> (0x8888));
2940 glLineStipple (1, static_cast<unsigned short> (0xF0F0));
2942 glLineStipple (1, static_cast<unsigned short> (0x020F));
2944 glLineStipple (1, static_cast<unsigned short> (0x0000));
2946 if (solid && ! use_stipple)
2947 glDisable (GL_LINE_STIPPLE);
2949 glEnable (GL_LINE_STIPPLE);
2953 opengl_renderer::set_clipbox (
double x1,
double x2,
double y1,
double y2,
2954 double z1,
double z2)
2956 double dx = (x2-x1);
2957 double dy = (y2-y1);
2958 double dz = (z2-z1);
2960 x1 -= 0.001*dx; x2 += 0.001*dx;
2961 y1 -= 0.001*dy; y2 += 0.001*dy;
2962 z1 -= 0.001*dz; z2 += 0.001*dz;
2966 p(0) = -1; p(3) = x2;
2967 glClipPlane (GL_CLIP_PLANE0, p.data ());
2968 p(0) = 1; p(3) = -x1;
2969 glClipPlane (GL_CLIP_PLANE1, p.data ());
2970 p(0) = 0; p(1) = -1; p(3) = y2;
2971 glClipPlane (GL_CLIP_PLANE2, p.data ());
2972 p(1) = 1; p(3) = -y1;
2973 glClipPlane (GL_CLIP_PLANE3, p.data ());
2974 p(1) = 0; p(2) = -1; p(3) = z2;
2975 glClipPlane (GL_CLIP_PLANE4, p.data ());
2976 p(2) = 1; p(3) = -z1;
2977 glClipPlane (GL_CLIP_PLANE5, p.data ());
2980 ymin = y1; ymax = y2;
2981 zmin = z1; zmax = z2;
2985 opengl_renderer::set_clipping (
bool enable)
2987 bool has_clipping = (glIsEnabled (GL_CLIP_PLANE0) == GL_TRUE);
2989 if (enable != has_clipping)
2992 for (
int i = 0; i < 6; i++)
2993 glEnable (GL_CLIP_PLANE0+i);
2995 for (
int i = 0; i < 6; i++)
2996 glDisable (GL_CLIP_PLANE0+i);
3001 opengl_renderer::init_marker (
const std::string& m,
double size,
float width)
3003 #if defined (HAVE_FRAMEWORK_OPENGL)
3009 glGetIntegerv (GL_VIEWPORT, vw);
3011 glMatrixMode (GL_PROJECTION);
3014 glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
3015 glMatrixMode (GL_MODELVIEW);
3018 set_clipping (
false);
3019 set_linewidth (width);
3021 marker_id = make_marker_list (m, size,
false);
3022 filled_marker_id = make_marker_list (m, size,
true);
3026 opengl_renderer::end_marker (
void)
3028 glDeleteLists (marker_id, 1);
3029 glDeleteLists (filled_marker_id, 1);
3031 glMatrixMode (GL_MODELVIEW);
3033 glMatrixMode (GL_PROJECTION);
3035 set_linewidth (0.5f);
3039 opengl_renderer::draw_marker (
double x,
double y,
double z,
3040 const Matrix& lc,
const Matrix& fc)
3045 glTranslated (tmp(0), tmp(1), -tmp(2));
3047 if (filled_marker_id > 0 && fc.
numel () > 0)
3049 glColor3dv (fc.
data ());
3050 set_polygon_offset (
true, -1.0);
3051 glCallList (filled_marker_id);
3052 if (lc.
numel () > 0)
3054 glColor3dv (lc.
data ());
3055 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
3056 glEdgeFlag (GL_TRUE);
3057 set_polygon_offset (
true, -2.0);
3058 glCallList (filled_marker_id);
3059 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
3061 set_polygon_offset (
false);
3063 else if (marker_id > 0 && lc.
numel () > 0)
3065 glColor3dv (lc.
data ());
3066 glCallList (marker_id);
3071 opengl_renderer::make_marker_list (
const std::string& marker,
double size,
3076 if (filled && (c ==
'+' || c ==
'x' || c ==
'*' || c ==
'.'))
3079 unsigned int ID = glGenLists (1);
3080 double sz = size * toolkit.get_screen_resolution () / 72.0;
3083 const double sqrt2d4 = 0.35355339059327;
3084 double tt = sz*sqrt2d4;
3086 glNewList (ID, GL_COMPILE);
3092 glVertex2d (-sz/2, 0);
3093 glVertex2d (sz/2, 0);
3094 glVertex2d (0, -sz/2);
3095 glVertex2d (0, sz/2);
3100 glVertex2d (-sz/2, -sz/2);
3101 glVertex2d (sz/2, sz/2);
3102 glVertex2d (-sz/2, sz/2);
3103 glVertex2d (sz/2, -sz/2);
3108 glVertex2d (-sz/2, 0);
3109 glVertex2d (sz/2, 0);
3110 glVertex2d (0, -sz/2);
3111 glVertex2d (0, sz/2);
3112 glVertex2d (-tt, -tt);
3113 glVertex2d (+tt, +tt);
3114 glVertex2d (-tt, +tt);
3115 glVertex2d (+tt, -tt);
3120 double ang_step = M_PI / 5;
3122 glBegin (GL_POLYGON);
3123 for (
double ang = 0; ang < (2*M_PI); ang += ang_step)
3124 glVertex2d (sz*cos (ang)/3, sz*sin (ang)/3);
3129 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3130 glVertex2d (-sz/2, -sz/2);
3131 glVertex2d (-sz/2, sz/2);
3132 glVertex2d (sz/2, sz/2);
3133 glVertex2d (sz/2, -sz/2);
3138 double ang_step = M_PI / 5;
3140 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3141 for (
double ang = 0; ang < (2*M_PI); ang += ang_step)
3142 glVertex2d (sz*cos (ang)/2, sz*sin (ang)/2);
3147 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3148 glVertex2d (0, -sz/2);
3149 glVertex2d (sz/2, 0);
3150 glVertex2d (0, sz/2);
3151 glVertex2d (-sz/2, 0);
3155 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3156 glVertex2d (0, sz/2);
3157 glVertex2d (sz/2, -sz/2);
3158 glVertex2d (-sz/2, -sz/2);
3162 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3163 glVertex2d (0, -sz/2);
3164 glVertex2d (-sz/2, sz/2);
3165 glVertex2d (sz/2, sz/2);
3169 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3170 glVertex2d (sz/2, 0);
3171 glVertex2d (-sz/2, sz/2);
3172 glVertex2d (-sz/2, -sz/2);
3176 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3177 glVertex2d (-sz/2, 0);
3178 glVertex2d (sz/2, -sz/2);
3179 glVertex2d (sz/2, sz/2);
3186 double dr = 1.0 - sin (M_PI/10)/sin (3*M_PI/10)*1.02;
3188 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3189 for (
int i = 0; i < 2*5; i++)
3191 ang = (-0.5 +
double(i+1)/5) * M_PI;
3192 r = 1.0 - (dr * fmod (
double(i+1), 2.0));
3193 glVertex2d (sz*r*cos (ang)/2, sz*r*sin (ang)/2);
3202 double dr = 1.0 - 0.5/sin (M_PI/3)*1.02;
3204 glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
3205 for (
int i = 0; i < 2*6; i++)
3207 ang = (0.5 +
double(i+1)/6.0) * M_PI;
3208 r = 1.0 - (dr * fmod (
double(i+1), 2.0));
3209 glVertex2d (sz*r*cos (ang)/2, sz*r*sin (ang)/2);
3215 warning (
"opengl_renderer: unsupported marker '%s'", marker.c_str ());
3225 opengl_renderer::text_to_pixels (
const std::string& txt,
3228 int halign,
int valign,
double rotation)
3231 text_renderer.text_to_pixels (txt, pixels, bbox,
3232 halign, valign, rotation,
"none");
3237 opengl_renderer::render_text (
const std::string& txt,
3238 double x,
double y,
double z,
3239 int halign,
int valign,
double rotation)
3243 return Matrix (1, 4, 0.0);
3247 text_to_pixels (txt, pixels, bbox, halign, valign, rotation);
3249 bool blend = glIsEnabled (GL_BLEND);
3251 glEnable (GL_BLEND);
3252 glEnable (GL_ALPHA_TEST);
3253 glRasterPos3d (x, y, z);
3254 glBitmap(0, 0, 0, 0, bbox(0), bbox(1), 0);
3255 glDrawPixels (bbox(2), bbox(3),
3256 GL_RGBA, GL_UNSIGNED_BYTE, pixels.
data ());
3257 glDisable (GL_ALPHA_TEST);
3259 glDisable (GL_BLEND);
3263 warning (
"opengl_renderer: cannot render text, FreeType library not available");
3264 return Matrix (1, 4, 0.0);
uint8NDArray uint8_array_value(void) const
std::string get_linestyle(void) const
std::string get_marker(void) const
bool facealpha_is_double(void) const
octave_value get_xticklabel(void) const
bool is_empty(void) const
double get_zPlaneN(void) const
Matrix get_markeredgecolor_rgb(void) const
Matrix get_opengl_matrix_1(void) const
octave_value get_color_data(void) const
Matrix get_markeredgecolor_rgb(void) const
Matrix get_facecolor_rgb(void) const
int get_zstate(void) const
double get_edgealpha_double(void) const
bool is_visible(void) const
Matrix get_backgroundcolor_rgb(void) const
double get_x_max(void) const
Matrix get_data_position(void) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
bool edgealpha_is(const std::string &v) const
graphics_handle get_xlabel(void) const
bool isa(const std::string &go_name) const
bool is_uint16_type(void) const
graphics_handle get_zlabel(void) const
bool linestyle_is(const std::string &v) const
octave_idx_type numel(void) const
Number of elements in the array.
bool get_nearhoriz(void) const
static octave_idx_type nn
Matrix get_color_rgb(void) const
octave_value get_zdata(void) const
std::string get_minorgridlinestyle(void) const
double get_z_max(void) const
octave_value get_faces(void) const
double get_fy(void) const
Complex xmax(const Complex &x, const Complex &y)
bool markerfacecolor_is(const std::string &v) const
virtual std::string graphics_object_name(void) const
bool edgelighting_is(const std::string &v) const
void error(const char *fmt,...)
std::string get_gridlinestyle(void) const
double get_linewidth(void) const
double get_diffusestrength(void) const
double get_ambientstrength(void) const
Complex xmin(const Complex &x, const Complex &y)
octave_value get_xdata(void) const
octave_value get_ymtick(void) const
bool has_property(const caseless_str &pname) const
double get_markersize(void) const
bool facecolor_is(const std::string &v) const
bool markeredgecolor_is(const std::string &v) const
octave_value get_ytick(void) const
std::string get_marker(void) const
bool edgecolor_is(const std::string &v) const
octave_value get_xmtick(void) const
double get_xticklen(void) const
double get_facealpha_double(void) const
bool is_zminortick(void) const
Matrix get_edgecolor_rgb(void) const
bool markerfacecolor_is(const std::string &v) const
Matrix get_markerfacecolor_rgb(void) const
octave_idx_type rows(void) const
octave_value get(bool all=false) const
F77_RET_T const double const double double * d
double get_xpTickN(void) const
string_vector all_strings(bool pad=false) const
graphics_xform get_transform(void) const
octave_value get_xdata(void) const
octave_value get_ydata(void) const
double get_edgealpha_double(void) const
double get_specularexponent(void) const
double get_diffusestrength(void) const
bool marker_is(const std::string &v) const
bool edgealpha_is_double(void) const
bool edgecolor_is(const std::string &v) const
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
double get_zpTickN(void) const
bool get_xyzSym(void) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
F77_RET_T const double const double * f
double get_specularstrength(void) const
Matrix get_markerfacecolor_rgb(void) const
Matrix get_children(void) const
Matrix get_ycolor_rgb(void) const
octave_value get_zticklabel(void) const
std::string string_value(bool force=false) const
double get_markersize(void) const
int get_ystate(void) const
std::complex< double > w(std::complex< double > z, double relerr=0)
double get_fx(void) const
Matrix get_extent_matrix(void) const
Matrix get_zcolor_rgb(void) const
double get_yPlane(void) const
octave_value get_zmtick(void) const
octave_value get_ydata(void) const
double get_ypTickN(void) const
bool facealpha_is(const std::string &v) const
bool facealpha_is(const std::string &v) const
bool is_double_type(void) const
octave_value get_vertexnormals(void) const
const T * data(void) const
bool get_y2Dright(void) const
Matrix get_edgecolor_rgb(void) const
bool edgecolor_is_rgb(void) const
double get_specularstrength(void) const
bool markeredgecolor_is(const std::string &v) const
std::string get_linestyle(void) const
double get_y_max(void) const
base_properties & get_properties(void)
double get_ytickoffset(void) const
Matrix get_color_rgb(void) const
double get_xPlaneN(void) const
std::string get_marker(void) const
bool get_layer2Dtop(void) const
size_t size(T const (&)[z])
bool marker_is(const std::string &v) const
graphics_object get_ancestor(const std::string &type) const
dim_vector dims(void) const
Matrix matrix_value(bool frc_str_conv=false) const
double get_linewidth(void) const
Matrix get_xcolor_rgb(void) const
octave_value get_vertices(void) const
bool is_clipping(void) const
static void end_contour(void)
double get_xPlane(void) const
bool get_zSign(void) const
octave_value get_string(void) const
bool edgealpha_is(const std::string &v) const
double get_yPlaneN(void) const
bool is_zminorgrid(void) const
bool edgealpha_is_double(void) const
static bool is_nan_or_inf(const octave_value &val)
double get_ypTick(void) const
void warning(const char *fmt,...)
bool get_xySym(void) const
bool valid_object(void) const
Handles the reference counting for all the derived classes.
bool facecolor_is_rgb(void) const
charNDArray max(char d, const charNDArray &m)
octave_idx_type length(void) const
Number of elements in the array.
octave_value get_ydata(void) const
bool is_empty(void) const
double get_facealpha_double(void) const
Matrix get_opengl_matrix_2(void) const
NDArray array_value(bool frc_str_conv=false) const
virtual octave_value get(const caseless_str &pname) const
bool edgelighting_is(const std::string &v) const
double get_xtickoffset(void) const
double get_fz(void) const
bool is_ygrid(void) const
double get_yticklen(void) const
double get_markersize(void) const
bool is_uint8_type(void) const
virtual graphics_toolkit get_toolkit(void) const
int get_xstate(void) const
double get_z_min(void) const
bool is_yminorgrid(void) const
Matrix get_all_children(void) const
double get_specularexponent(void) const
bool is_xminortick(void) const
double get_x_min(void) const
double get_y_min(void) const
double get_xpTick(void) const
bool facealpha_is_double(void) const
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
static graphics_object get_object(double val)
bool is_xminorgrid(void) const
bool get_is2D(void) const
double get_zpTick(void) const
double get_linewidth(void) const
double get_ambientstrength(void) const
Matrix get_markeredgecolor_rgb(void) const
octave_value get_ztick(void) const
octave_value get_color_data(void) const
double get_zticklen(void) const
octave_value get_vertexnormals(void) const
bool facecolor_is(const std::string &v) const
octave_value get_color_data(void) const
octave_value get_xdata(void) const
bool is_single_type(void) const
bool marker_is(const std::string &v) const
Matrix get_markerfacecolor_rgb(void) const
double double_value(bool frc_str_conv=false) const
bool edgecolor_is_rgb(void) const
bool markerfacecolor_is(const std::string &v) const
double get_linewidth(void) const
bool facelighting_is(const std::string &v) const
Matrix get_transform_zlim(void) const
bool is_yminortick(void) const
bool markeredgecolor_is(const std::string &v) const
bool meshstyle_is(const std::string &v) const
const uint8NDArray & get_pixels(void) const
uint16NDArray uint16_array_value(void) const
bool is_zgrid(void) const
octave_idx_type columns(void) const
double get_ztickoffset(void) const
octave_value get_zdata(void) const
bool has_bad_data(std::string &msg) const
void xform(ColumnVector &v, const Matrix &m)
bool facecolor_is_rgb(void) const
double get_zPlane(void) const
bool facelighting_is(const std::string &v) const
std::string get_linestyle(void) const
graphics_handle get_ylabel(void) const
F77_RET_T const double * x
charNDArray min(char d, const charNDArray &m)
bool get_x2Dtop(void) const
Matrix get_facecolor_rgb(void) const
octave_value get_yticklabel(void) const
octave_value get_xtick(void) const
bool is_xgrid(void) const