# HG changeset patch # User John W. Eaton # Date 1456434904 18000 # Node ID e4fc19d8c6c397b7bdbb86d29dcb51c1b4eb9ddc # Parent 043ec02115b83d8c05b32a2c1b43007c7a3fdb51 remove HAVE_OPENGL from public header file * gl-render.h: Don't check HAVE_OPENGL here. * gl-render.cc (opengl_renderer::opengl_renderer): Throw error if OpenGL is not available or if the GLsizei is not what we expect. Surround OpenGL-specific code in individual functions with preprocessor conditional. * gl-render.h, gl-render.cc (opengel_renderer::draw_pixels): Define individual functions for separate data types. * gl2ps-print.cc (gl2ps_renderer::draw_pixels): Likewise. diff -r 043ec02115b8 -r e4fc19d8c6c3 libinterp/corefcn/gl-render.cc --- a/libinterp/corefcn/gl-render.cc Thu Feb 25 21:04:14 2016 +0100 +++ b/libinterp/corefcn/gl-render.cc Thu Feb 25 16:15:04 2016 -0500 @@ -24,8 +24,6 @@ # include "config.h" #endif -#if defined (HAVE_OPENGL) - #include #ifdef HAVE_WINDOWS_H @@ -42,6 +40,8 @@ #include "oct-opengl.h" #include "text-renderer.h" +#if defined (HAVE_OPENGL) + #define LIGHT_MODE GL_FRONT_AND_BACK // Use symbolic names for axes @@ -567,6 +567,42 @@ std::list tmp_vdata; }; +#else + +class +opengl_renderer::patch_tesselator +{ + // Dummy class. +}; + +#endif + +opengl_renderer::opengl_renderer (void) + : toolkit (), xform (), xmin (), xmax (), ymin (), ymax (), + zmin (), zmax (), xZ1 (), xZ2 (), marker_id (), filled_marker_id (), + camera_pos (), camera_dir (), interpreter ("none"), txt_renderer () +{ + // This constructor will fail if we don't have OpenGL or if the data + // types we assumed in our public interface aren't compatible with the + // OpenGL types. + +#if defined (HAVE_OPENGL) + + // Ensure that we can't request an image larger than OpenGL can handle. + // FIXME: should we check signed vs. unsigned? + + static bool ok = (sizeof (int) <= sizeof (GLsizei)); + + if (! ok) + error ("the size of GLsizei is smaller than the size of int"); + +#else + + err_disabled_feature ("opengl_renderer", "OpenGL"); + +#endif +} + void opengl_renderer::draw (const graphics_object& go, bool toplevel) { @@ -643,6 +679,8 @@ void opengl_renderer::init_gl_context (bool enhanced, const Matrix& c) { +#if defined (HAVE_OPENGL) + // Initialize OpenGL context glEnable (GL_DEPTH_TEST); @@ -679,6 +717,13 @@ glClearColor (c(0), c(1), c(2), 1); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -687,6 +732,8 @@ double p1, double p1N, double p2, double p2N, int xyz, bool is_3D) { +#if defined (HAVE_OPENGL) + set_linestyle (gridstyle, true); glBegin (GL_LINES); for (int i = 0; i < ticks.numel (); i++) @@ -725,6 +772,13 @@ } glEnd (); set_linestyle ("-", true); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -735,6 +789,8 @@ double dx, double dy, double dz, int xyz, bool mirror) { +#if defined (HAVE_OPENGL) + glBegin (GL_LINES); for (int i = 0; i < ticks.numel (); i++) @@ -777,6 +833,13 @@ } glEnd (); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -787,6 +850,8 @@ int xyz, int ha, int va, int& wmax, int& hmax) { +#if defined (HAVE_OPENGL) + int nticks = ticks.numel (); int nlabels = ticklabels.numel (); @@ -824,17 +889,35 @@ hmax = std::max (hmax, static_cast (b(3))); } } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::finish (void) { +#if defined (HAVE_OPENGL) + glFinish (); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::setup_opengl_transformation (const axes::properties& props) { +#if defined (HAVE_OPENGL) + // setup OpenGL transformation Matrix x_zlim = props.get_transform_zlim (); @@ -868,11 +951,20 @@ // store axes transformation data xform = props.get_transform (); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_axes_planes (const axes::properties& props) { +#if defined (HAVE_OPENGL) + Matrix axe_color = props.get_color_rgb (); if (axe_color.is_empty () || ! props.is_visible ()) return; @@ -915,11 +1007,20 @@ glEnd (); set_polygon_offset (false); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_axes_boxes (const axes::properties& props) { +#if defined (HAVE_OPENGL) + if (! props.is_visible ()) return; @@ -1026,6 +1127,13 @@ } glEnd (); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -1391,6 +1499,8 @@ void opengl_renderer::draw_axes_children (const axes::properties& props) { +#if defined (HAVE_OPENGL) + // Children Matrix children = props.get_all_children (); @@ -1453,11 +1563,20 @@ // FIXME: finalize rendering (transparency processing) // FIXME: draw zoom box, if needed + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_axes (const axes::properties& props) { +#if defined (HAVE_OPENGL) + static double floatmax = std::numeric_limits::max (); double x_min = props.get_x_min (); @@ -1503,11 +1622,20 @@ glEnable (GL_LINE_SMOOTH); draw_axes_children (props); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_line (const line::properties& props) { +#if defined (HAVE_OPENGL) + Matrix x = xform.xscale (props.get_xdata ().matrix_value ()); Matrix y = xform.yscale (props.get_ydata ().matrix_value ()); Matrix z = xform.zscale (props.get_zdata ().matrix_value ()); @@ -1627,11 +1755,20 @@ } set_clipping (props.is_clipping ()); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_surface (const surface::properties& props) { +#if defined (HAVE_OPENGL) + const Matrix x = xform.xscale (props.get_xdata ().matrix_value ()); const Matrix y = xform.yscale (props.get_ydata ().matrix_value ()); const Matrix z = xform.zscale (props.get_zdata ().matrix_value ()); @@ -2224,6 +2361,13 @@ end_marker (); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } // FIXME: global optimization (rendering, data structures...), @@ -2231,6 +2375,8 @@ void opengl_renderer::draw_patch (const patch::properties &props) { +#if defined (HAVE_OPENGL) + // Do not render if the patch has incoherent data std::string msg; if (props.has_bad_data (msg)) @@ -2658,6 +2804,13 @@ end_marker (); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -2669,6 +2822,8 @@ void opengl_renderer::draw_text (const text::properties& props) { +#if defined (HAVE_OPENGL) + if (props.get_string ().is_empty ()) return; @@ -2690,11 +2845,19 @@ if (! blend) glDisable (GL_BLEND); +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_image (const image::properties& props) { +#if defined (HAVE_OPENGL) + octave_value cdata = props.get_color_data (); dim_vector dv (cdata.dims ()); int h = dv(0); @@ -2810,7 +2973,7 @@ } } - draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a); + draw_pixels (j1-j0, i1-i0, a); } else if (cdata.is_single_type ()) @@ -2829,7 +2992,7 @@ } } - draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a); + draw_pixels (j1-j0, i1-i0, a); } else if (cdata.is_uint8_type ()) @@ -2848,7 +3011,7 @@ } } - draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a); + draw_pixels (j1-j0, i1-i0, a); } else if (cdata.is_uint16_type ()) @@ -2867,7 +3030,7 @@ } } - draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_SHORT, a); + draw_pixels (j1-j0, i1-i0, a); } else @@ -2877,27 +3040,90 @@ warning ("opengl_renderer: invalid image size (expected MxNx3 or MxN)"); glPixelZoom (1, 1); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_viewport (int w, int h) { +#if defined (HAVE_OPENGL) + glViewport (0, 0, w, h); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif +} + +void +opengl_renderer::draw_pixels (int width, int height, const float *data) +{ +#if defined (HAVE_OPENGL) + + glDrawPixels (width, height, GL_RGB, GL_FLOAT, data); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void -opengl_renderer::draw_pixels (GLsizei width, GLsizei height, GLenum format, - GLenum type, const GLvoid *data) +opengl_renderer::draw_pixels (int width, int height, const uint8_t *data) { - glDrawPixels (width, height, format, type, data); +#if defined (HAVE_OPENGL) + + glDrawPixels (width, height, GL_RGB, GL_UNSIGNED_BYTE, data); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif +} + +void +opengl_renderer::draw_pixels (int width, int height, const uint16_t *data) +{ +#if defined (HAVE_OPENGL) + + glDrawPixels (width, height, GL_RGB, GL_UNSIGNED_SHORT, data); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_color (const Matrix& c) { +#if defined (HAVE_OPENGL) + glColor3dv (c.data ()); txt_renderer.set_color (c); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -2912,6 +3138,8 @@ void opengl_renderer::set_polygon_offset (bool on, float offset) { +#if defined (HAVE_OPENGL) + if (on) { glEnable (GL_POLYGON_OFFSET_FILL); @@ -2923,17 +3151,35 @@ glDisable (GL_POLYGON_OFFSET_FILL); glDisable (GL_POLYGON_OFFSET_LINE); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_linewidth (float w) { +#if defined (HAVE_OPENGL) + glLineWidth (w); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_linestyle (const std::string& s, bool use_stipple) { +#if defined (HAVE_OPENGL) + bool solid = false; if (s == "-") @@ -2954,12 +3200,21 @@ glDisable (GL_LINE_STIPPLE); else glEnable (GL_LINE_STIPPLE); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_clipbox (double x1, double x2, double y1, double y2, double z1, double z2) { +#if defined (HAVE_OPENGL) + double dx = (x2-x1); double dy = (y2-y1); double dz = (z2-z1); @@ -2986,11 +3241,20 @@ xmin = x1; xmax = x2; ymin = y1; ymax = y2; zmin = z1; zmax = z2; + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::set_clipping (bool enable) { +#if defined (HAVE_OPENGL) + bool has_clipping = (glIsEnabled (GL_CLIP_PLANE0) == GL_TRUE); if (enable != has_clipping) @@ -3002,11 +3266,20 @@ for (int i = 0; i < 6; i++) glDisable (GL_CLIP_PLANE0+i); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::init_marker (const std::string& m, double size, float width) { +#if defined (HAVE_OPENGL) + #if defined (HAVE_FRAMEWORK_OPENGL) GLint vw[4]; #else @@ -3027,11 +3300,20 @@ marker_id = make_marker_list (m, size, false); filled_marker_id = make_marker_list (m, size, true); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::end_marker (void) { +#if defined (HAVE_OPENGL) + glDeleteLists (marker_id, 1); glDeleteLists (filled_marker_id, 1); @@ -3040,12 +3322,21 @@ glMatrixMode (GL_PROJECTION); glPopMatrix (); set_linewidth (0.5f); + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void opengl_renderer::draw_marker (double x, double y, double z, const Matrix& lc, const Matrix& fc) { +#if defined (HAVE_OPENGL) + ColumnVector tmp = xform.transform (x, y, z, false); glLoadIdentity (); @@ -3072,12 +3363,21 @@ glColor3dv (lc.data ()); glCallList (marker_id); } + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } unsigned int opengl_renderer::make_marker_list (const std::string& marker, double size, bool filled) const { +#if defined (HAVE_OPENGL) + char c = marker[0]; if (filled && (c == '+' || c == 'x' || c == '*' || c == '.')) @@ -3226,6 +3526,13 @@ glEndList (); return ID; + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } void @@ -3253,6 +3560,8 @@ double x, double y, double z, int halign, int valign, double rotation) { +#if defined (HAVE_OPENGL) + Matrix bbox (1, 4, 0.0); if (txt.empty ()) @@ -3278,6 +3587,11 @@ } return bbox; + +#else + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); +#endif } - -#endif diff -r 043ec02115b8 -r e4fc19d8c6c3 libinterp/corefcn/gl-render.h --- a/libinterp/corefcn/gl-render.h Thu Feb 25 21:04:14 2016 +0100 +++ b/libinterp/corefcn/gl-render.h Thu Feb 25 16:15:04 2016 -0500 @@ -26,21 +26,15 @@ #include "octave-config.h" #include "graphics.h" -#include "oct-opengl.h" #include "text-renderer.h" -#if defined (HAVE_OPENGL) - class OCTINTERP_API opengl_renderer { public: - opengl_renderer (void) - : toolkit (), xform (), xmin (), xmax (), ymin (), ymax (), - zmin (), zmax (), xZ1 (), xZ2 (), marker_id (), filled_marker_id (), - camera_pos (), camera_dir (), interpreter ("none"), txt_renderer () - { } + + opengl_renderer (void); virtual ~opengl_renderer (void) { } @@ -113,8 +107,9 @@ double x, double y, double z, int halign, int valign, double rotation = 0.0); - virtual void draw_pixels (GLsizei w, GLsizei h, GLenum format, - GLenum type, const GLvoid *data); + virtual void draw_pixels (int w, int h, const float *data); + virtual void draw_pixels (int w, int h, const uint8_t *data); + virtual void draw_pixels (int w, int h, const uint16_t *data); virtual void render_grid (const std::string& gridstyle, const Matrix& ticks, double lim1, double lim2, @@ -201,5 +196,3 @@ }; #endif - -#endif diff -r 043ec02115b8 -r e4fc19d8c6c3 libinterp/corefcn/gl2ps-print.cc --- a/libinterp/corefcn/gl2ps-print.cc Thu Feb 25 21:04:14 2016 +0100 +++ b/libinterp/corefcn/gl2ps-print.cc Thu Feb 25 16:15:04 2016 -0500 @@ -30,6 +30,9 @@ #ifdef HAVE_GL2PS_H #include + +#include + #include #include @@ -96,8 +99,10 @@ } void draw_text (const text::properties& props); - void draw_pixels (GLsizei w, GLsizei h, GLenum format, - GLenum type, const GLvoid *data); + + void draw_pixels (int w, int h, const float *data); + void draw_pixels (int w, int h, const uint8_t *data); + void draw_pixels (int w, int h, const uint16_t *data); void set_linestyle (const std::string& s, bool use_stipple = false) { @@ -663,31 +668,40 @@ fontname = select_font (fn, isbold, isitalic); } -template -static void -draw_pixels (GLsizei w, GLsizei h, GLenum format, const T *data, float maxval) +void +gl2ps_renderer::draw_pixels (int w, int h, const float *data) { - OCTAVE_LOCAL_BUFFER (GLfloat, a, 3*w*h); - - // Convert to GL_FLOAT as it is the only type gl2ps accepts. - for (int i = 0; i < 3*w*h; i++) - a[i] = data[i] / maxval; - - gl2psDrawPixels (w, h, 0, 0, format, GL_FLOAT, a); + gl2psDrawPixels (w, h, 0, 0, GL_RGB, GL_FLOAT, data); } void -gl2ps_renderer::draw_pixels (GLsizei w, GLsizei h, GLenum format, - GLenum type, const GLvoid *data) +gl2ps_renderer::draw_pixels (int w, int h, const uint8_t *data) { // gl2psDrawPixels only supports the GL_FLOAT type. - // Other formats, such as uint8, must be converted first. - if (type == GL_UNSIGNED_BYTE) - ::draw_pixels (w, h, format, static_cast (data), 255.0f); - else if (type == GL_UNSIGNED_SHORT) - ::draw_pixels (w, h, format, static_cast (data), 65535.0f); - else - gl2psDrawPixels (w, h, 0, 0, format, type, data); + + OCTAVE_LOCAL_BUFFER (float, tmp_data, 3*w*h); + + static const float maxval = std::numeric_limits::max (); + + for (int i = 0; i < 3*w*h; i++) + tmp_data[i] = data[i] / maxval; + + draw_pixels (w, h, tmp_data); +} + +void +gl2ps_renderer::draw_pixels (int w, int h, const uint16_t *data) +{ + // gl2psDrawPixels only supports the GL_FLOAT type. + + OCTAVE_LOCAL_BUFFER (float, tmp_data, 3*w*h); + + static const float maxval = std::numeric_limits::max (); + + for (int i = 0; i < 3*w*h; i++) + tmp_data[i] = data[i] / maxval; + + draw_pixels (w, h, tmp_data); } void