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, ¶ms);
73 return params != GL_FALSE;
74 }
75