1 // This is core/vgui/internals/vgui_rasterpos.cxx
2 //:
3 // \file
4 // \author fsm
5 
6 #include "vgui_rasterpos.h"
7 #include "vnl/vnl_vector_fixed.h"
8 #include "vnl/vnl_matrix_fixed.h"
9 #include "vgui/vgui_matrix_state.h"
10 
11 // Purpose : a RasterPos() routine which sets the raster position,
12 // even if GL thinks it is invalid.
13 void
vgui_rasterpos4dv(double const X[4])14 vgui_rasterpos4dv(double const X[4])
15 {
16   // This class will restore the matrix state on exit of this
17   // function.
18   vgui_matrix_state matrix_state;
19 
20   GLint vp[4]; // x,y, w,h
21 
22   vnl_matrix_fixed<double, 4, 4> T = vgui_matrix_state::total_transformation();
23   vnl_vector_fixed<double, 4> tmp = T * vnl_vector_fixed<double, 4>(X);
24   double rx = tmp[0] / tmp[3];
25   double ry = tmp[1] / tmp[3];
26 
27   glMatrixMode(GL_PROJECTION);
28   glLoadIdentity();
29 
30   glMatrixMode(GL_MODELVIEW);
31   glLoadIdentity();
32 
33   //          To set a valid raster position outside the viewport, first
34   //          set a valid raster position inside the viewport, then call
35   //          glBitmap with NULL as the bitmap parameter and with xmove
36   //          and ymove set to the offsets of the new raster position.
37   //          This technique is useful when panning an image around the
38   //          viewport.
39   // (from http://www.opengl.org/developers/faqs/technical/clipping.htm#0070)
40   glRasterPos2f(0, 0);
41   // This needs to be in physical pixel for glBitmap
42   // Don't use vgui_utils::get_glViewport here!
43   glGetIntegerv(GL_VIEWPORT, vp);
44   // Since vp is in physical pixels, this bitmap command works as intended on
45   // multiple DPIs, and does not need any further conversions
46   // Don't need to use vgui_utils::draw_glBitmap here, since there is no actual
47   // drawing
48   glBitmap(0, 0, 0, 0, float(rx * vp[2] / 2), float(ry * vp[3] / 2), nullptr);
49 }
50 
51 
52 void
vgui_rasterpos2f(float x,float y)53 vgui_rasterpos2f(float x, float y)
54 {
55   double X[4] = { x, y, 0, 1 };
56   vgui_rasterpos4dv(X);
57 }
58 
59 
60 void
vgui_rasterpos2i(int x,int y)61 vgui_rasterpos2i(int x, int y)
62 {
63   double X[4] = { double(x), double(y), 0.0, 1.0 };
64   vgui_rasterpos4dv(X);
65 }
66 
67 
68 bool
vgui_rasterpos_valid()69 vgui_rasterpos_valid()
70 {
71   GLboolean params;
72   glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &params);
73   return params != GL_FALSE;
74 }
75