1 #ifndef vgui_utils_h_ 2 #define vgui_utils_h_ 3 //: 4 // \file 5 // \author fsm 6 // \brief Useful static functions for vgui. 7 // 8 // \verbatim 9 // Modifications 10 // 991020 AWF Added inversion of translation+scale. 11 // This is necessary because zoomers demand exact equality 12 // when checking if they are 2D transformations. 13 // \endverbatim 14 15 #include <vector> 16 #include "vgui_gl.h" 17 #include "vgui/vgui_adaptor.h" 18 #ifdef _MSC_VER 19 # include <vcl_msvc_warnings.h> 20 #endif 21 #include <vil1/vil1_rgb.h> 22 #include <vil1/vil1_memory_image_of.h> 23 #include <vil/vil_image_view.h> 24 25 //: Useful static functions for vgui. 26 class vgui_utils 27 { 28 public: 29 //: Get a memory image (vil1) corresponding to the OpenGL area 30 static vil1_memory_image_of<vil1_rgb<unsigned char> > colour_buffer_to_image(); 31 32 //: Get an image view corresponding to the OpenGL area 33 static vil_image_view<vxl_byte> colour_buffer_to_view(); 34 35 //: Dump the OpenGL area to the given image filename. 36 static void dump_colour_buffer(char const *file); 37 38 //: Copy front colour buffer to back colour buffer. 39 static void copy_front_to_back(); 40 41 //: Copy back colour buffer to front colour buffer. 42 static void copy_back_to_front(); 43 44 //: Begin software overlay. 45 static void begin_sw_overlay(); 46 47 //: End software overlay. 48 static void end_sw_overlay(); 49 50 // Selection utilities 51 static GLuint* enter_pick_mode(float x, float y, float w, float h=0); 52 static unsigned leave_pick_mode(); 53 static void process_hits(int num_hits, GLuint* ptr, std::vector<std::vector<unsigned> >& hits); 54 55 //: Returns the number of bits per pixel. 56 static int bits_per_pixel(GLenum format, GLenum type); 57 58 /** 59 * Gets the viewport (GL_VIEWPORT), and corrects for physical to logical 60 * scaling, so that the values are always in units of logical pixels, cross 61 * platform. 62 * 63 * @param view_port A GLint/GLfloat/GLdouble[4] array where the viewport is 64 * stored, in logical pixels 65 * @param scale The scale factor used. Defaults to 0, meaning auto determine 66 * using vgui_adaptor::current. If this is not correct, the 67 * scale factor can manually be set 68 */ 69 template <class T> static void get_glViewport(T *data, double scale=0){_glGet<T, 4>(GL_VIEWPORT, data, scale);}; 70 71 /** 72 * Gets the Scissor ROI (GL_SCISSOR_BOX), and corrects for physical to logical 73 * scaling, so that the values are always in units of logical pixels, cross 74 * platform. 75 * 76 * @param view_port A GLint/GLfloat/GLdouble[4] array where the viewport is 77 * stored, in logical pixels 78 * @param scale The scale factor used. Defaults to 0, meaning auto determine 79 * using vgui_adaptor::current. If this is not correct, the 80 * scale factor can manually be set 81 */ 82 template <class T> static void get_glScissor(T *data, double scale=0){_glGet<T, 4>(GL_SCISSOR_BOX, data, scale);}; 83 84 //: Set the gl viewport in logical pixels 85 static void set_glViewport(GLint x, GLint y, 86 GLsizei width, GLsizei height, 87 double scale=0); 88 static void set_glScissor(GLint x, GLint y, 89 GLsizei width, GLsizei height, 90 double scale=0); 91 92 static void set_glLineWidth(GLfloat width, double scale=0); 93 static void set_glPixelZoom(GLfloat xfactor, GLfloat yfactor, double scale=0); 94 static void set_glPointSize(GLfloat size, double scale=0); 95 static void draw_glBitmap(GLsizei width, GLsizei height, 96 GLfloat xorig, GLfloat yorig, 97 GLfloat xmove, GLfloat ymove, 98 const GLubyte * bitmap, 99 double scale=0); 100 101 private: 102 static vil1_memory_image_of<vil1_rgb<GLubyte> > get_image(double scale=0); 103 static vil_image_view<GLubyte> get_view(double scale=0); 104 static void do_copy(double scale=0); 105 106 /** 107 * Helper function that sets the DPI scale variable if it is unknown (0) 108 * 109 * @param s If s is non-zero, it is left alone, else it retrieves the scale 110 * from the current vgui adaptor and sets s to it. 111 */ get_gl_scale_default(double & s)112 static inline void get_gl_scale_default(double &s){ if (s == 0) s = vgui_adaptor::current->get_scale_factor(); } 113 114 115 /* For GL_VIEWPORT and GL_SCISSOR_BOX, which are all in physical instead of 116 logical pixels. The only other target I see that might need to be added to 117 this in the future is GL_MAX_VIEWPORT_DIMS. number_scaled assumed only the 118 first n need to be scaled. If it gets to be more complicated, replace with 119 a bit mask or something, but I don't think there's a need for that */ 120 template <class T, int number_scaled> static inline void _glGet(GLenum target, T *data, double scale=0) 121 { 122 get_gl_scale_default(scale); 123 124 _glRawGet(target, data); 125 126 for(ptrdiff_t x=0; x<number_scaled; x++) 127 data[x]/=scale; 128 } 129 // Clean up with constexpr in c++17 _glRawGet(GLenum target,GLint * data)130 static inline void _glRawGet(GLenum target, GLint* data){glGetIntegerv(target, data);}; _glRawGet(GLenum target,GLfloat * data)131 static inline void _glRawGet(GLenum target, GLfloat* data){glGetFloatv(target, data);}; _glRawGet(GLenum target,GLdouble * data)132 static inline void _glRawGet(GLenum target, GLdouble* data){glGetDoublev(target, data);}; 133 134 }; 135 136 #endif // vgui_utils_h_ 137