GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
gl-select.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2011-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "gl-select.h"
31 
32 namespace octave
33 {
34 
35  void
37  {
38  GLdouble p_matrix[16];
39 
40  m_glfcns.glGetDoublev (GL_PROJECTION_MATRIX, p_matrix);
41  m_glfcns.glMatrixMode (GL_PROJECTION);
43 
44  // The following block is equivalent to gluPickMatrix, but we avoid
45  // using glu functions so that we can call OpenGL functions through
46  // the QOpenGLFunctions class so that the OpenGL implementation may
47  // be selected dynamically.
48 
49  Matrix viewport = get_viewport_scaled ();
50 
51  if (size > 0)
52  {
53  m_glfcns.glTranslatef ((viewport(2) - 2 * (xp - viewport(0))) / size,
54  (viewport(3) - 2 * (yp - viewport(1))) / size, 0);
55 
56  m_glfcns.glScalef (viewport(2) / size, viewport(3) / size, 1.0);
57  }
58 
59  m_glfcns.glMultMatrixd (p_matrix);
60  m_glfcns.glMatrixMode (GL_MODELVIEW);
61  }
62 
63  void
65  {
68  }
69 
70  void
71  opengl_selector::init_marker (const std::string& m, double sz, float width)
72  {
73  opengl_renderer::init_marker (m, sz, width);
75  }
76 
77 # define BUFFER_SIZE 128
78 
80  opengl_selector::select (const graphics_object& ax, int x, int y, int flags)
81  {
82  m_glfcns.glEnable (GL_DEPTH_TEST);
83  m_glfcns.glDepthFunc (GL_LEQUAL);
84 
85  xp = x;
86  yp = y;
87 
88  GLuint select_buffer[BUFFER_SIZE];
89 
90  m_glfcns.glSelectBuffer (BUFFER_SIZE, select_buffer);
91  m_glfcns.glRenderMode (GL_SELECT);
93 
94  object_map.clear ();
95 
96  draw (ax);
97 
98  int hits = m_glfcns.glRenderMode (GL_RENDER);
99  graphics_object obj;
100 
101  if (hits > 0)
102  {
103  GLuint current_minZ = 0xffffffff;
104  GLuint current_name = 0xffffffff;
105 
106  for (int i = 0, j = 0; i < hits && j < BUFFER_SIZE-3; i++)
107  {
108  GLuint n = select_buffer[j++],
109  minZ = select_buffer[j++];
110 
111  j++; // skip maxZ
112  if (((flags & select_last) == 0 && (minZ <= current_minZ))
113  || ((flags & select_last) != 0 && (minZ >= current_minZ)))
114  {
115  bool candidate = true;
116  GLuint name =
117  select_buffer[std::min (j + n, GLuint (BUFFER_SIZE)) - 1];
118 
119  if ((flags & select_ignore_hittest) == 0)
120  {
122 
123  if (! go.get_properties ().is_hittest ())
124  candidate = false;
125  }
126 
127  if (candidate)
128  {
129  current_minZ = minZ;
130  current_name = name;
131  }
132 
133  j += n;
134  }
135  else
136  j += n;
137  }
138 
139  if (current_name != 0xffffffff)
140  obj = object_map[current_name];
141  }
142  else if (hits < 0)
143  warning ("opengl_selector::select: selection buffer overflow");
144 
145  object_map.clear ();
146 
147  return obj;
148  }
149 
150  void
151  opengl_selector::draw (const graphics_object& go, bool toplevel)
152  {
153  GLuint name = object_map.size ();
154 
155  object_map[name] = go;
157  set_selecting (true);
158  opengl_renderer::draw (go, toplevel);
159  set_selecting (false);
160  m_glfcns.glPopName ();
161  }
162 
163  void
164  opengl_selector::fake_text (double x, double y, double z, const Matrix& bbox,
165  bool use_scale)
166  {
167  ColumnVector xpos, xp1, xp2;
168 
169  xpos = get_transform ().transform (x, y, z, use_scale);
170 
171  xp1 = xp2 = xpos;
172  xp1(0) += bbox(0);
173  xp1(1) -= bbox(1);
174  xp2(0) += (bbox(0) + bbox(2));
175  xp2(1) -= (bbox(1) + bbox(3));
176 
177  ColumnVector p1, p2, p3, p4;
178 
179  p1 = get_transform ().untransform (xp1(0), xp1(1), xp1(2), false);
180  p2 = get_transform ().untransform (xp2(0), xp1(1), xp1(2), false);
181  p3 = get_transform ().untransform (xp2(0), xp2(1), xp1(2), false);
182  p4 = get_transform ().untransform (xp1(0), xp2(1), xp1(2), false);
183 
184  m_glfcns.glBegin (GL_QUADS);
185  m_glfcns.glVertex3dv (p1.data ());
186  m_glfcns.glVertex3dv (p2.data ());
187  m_glfcns.glVertex3dv (p3.data ());
188  m_glfcns.glVertex3dv (p4.data ());
189  m_glfcns.glEnd ();
190  }
191 
192  void
194  {
195  if (props.get_string ().isempty ())
196  return;
197 
198  Matrix pos = props.get_data_position ();
199  const Matrix bbox = props.get_extent_matrix ();
200 
201  fake_text (pos(0), pos(1), pos.numel () > 2 ? pos(2) : 0.0, bbox);
202  }
203 
204  Matrix
205  opengl_selector::render_text (const std::string& txt,
206  double x, double y, double z,
207  int halign, int valign, double rotation)
208  {
209  uint8NDArray pixels;
210  Matrix bbox (1, 4, 0.0);
211 
212  // FIXME: probably more efficient to only compute bbox instead
213  // of doing full text rendering...
214  text_to_pixels (txt, pixels, bbox, halign, valign, rotation);
215  fake_text (x, y, z, bbox, false);
216 
217  return bbox;
218  }
219 
220  void
222  {
223  Matrix xd = props.get_xdata ().matrix_value ();
224  octave_idx_type nc = props.get_cdata ().columns ();
225  double x_pix_size = (nc == 1 ? 1 : (xd(1) - xd(0)) / (nc - 1));
226 
227  Matrix yd = props.get_ydata ().matrix_value ();
228  octave_idx_type nr = props.get_cdata ().rows ();
229  double y_pix_size = (nr == 1 ? 1 : (yd(1) - yd(0)) / (nr - 1));
230 
231  ColumnVector p1(3, 0.0), p2(3, 0.0), p3(3, 0.0), p4(3, 0.0);
232  p1(0) = xd(0) - x_pix_size/2;
233  p1(1) = yd(0) - y_pix_size/2;
234 
235  p2(0) = xd(1) + x_pix_size/2;
236  p2(1) = yd(0) - y_pix_size/2;
237 
238  p3(0) = xd(1) + x_pix_size/2;
239  p3(1) = yd(1) + y_pix_size/2;
240 
241  p4(0) = xd(0) - x_pix_size/2;
242  p4(1) = yd(1) + y_pix_size/2;
243 
244  m_glfcns.glBegin (GL_QUADS);
245  m_glfcns.glVertex3dv (p1.data ());
246  m_glfcns.glVertex3dv (p2.data ());
247  m_glfcns.glVertex3dv (p3.data ());
248  m_glfcns.glVertex3dv (p4.data ());
249  m_glfcns.glEnd ();
250  }
251 
252 }
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:581
Definition: dMatrix.h:42
base_properties & get_properties(void)
Definition: graphics.in.h:2829
ColumnVector untransform(double x, double y, double z, bool use_scale=true) const
Definition: graphics.cc:7391
ColumnVector transform(double x, double y, double z, bool use_scale=true) const
Definition: graphics.cc:7378
virtual void glGetDoublev(GLenum pname, GLdouble *data)
Definition: oct-opengl.h:219
virtual void glScalef(GLfloat x, GLfloat y, GLfloat z)
Definition: oct-opengl.h:396
virtual void glMultMatrixd(const GLdouble *m)
Definition: oct-opengl.h:294
virtual void glEnd(void)
Definition: oct-opengl.h:194
virtual void glBegin(GLenum mode)
Definition: oct-opengl.h:78
virtual void glSelectBuffer(GLsizei size, GLuint *buffer)
Definition: oct-opengl.h:401
virtual void glDepthFunc(GLenum func)
Definition: oct-opengl.h:163
virtual GLint glRenderMode(GLenum mode)
Definition: oct-opengl.h:381
virtual void glEnable(GLenum cap)
Definition: oct-opengl.h:184
virtual void glInitNames(void)
Definition: oct-opengl.h:249
virtual void glLoadIdentity(void)
Definition: oct-opengl.h:274
virtual void glPopName(void)
Definition: oct-opengl.h:350
virtual void glMatrixMode(GLenum mode)
Definition: oct-opengl.h:289
virtual void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
Definition: oct-opengl.h:434
virtual void glPushName(GLuint name)
Definition: oct-opengl.h:365
virtual void glVertex3dv(const GLdouble *v)
Definition: oct-opengl.h:449
opengl_functions & m_glfcns
Definition: gl-render.h:206
virtual void draw(const graphics_object &go, bool toplevel=true)
Definition: gl-render.cc:717
virtual void init_marker(const std::string &m, double size, float width)
Definition: gl-render.cc:4245
virtual graphics_xform get_transform(void) const
Definition: gl-render.h:66
virtual void text_to_pixels(const std::string &txt, uint8NDArray &pixels, Matrix &bbox, int halign=0, int valign=0, double rotation=0.0)
Definition: gl-render.cc:4637
virtual void set_selecting(bool on)
Definition: gl-render.h:112
virtual void setup_opengl_transformation(const axes::properties &props)
Definition: gl-render.cc:1272
virtual Matrix get_viewport_scaled(void) const
Definition: gl-render.cc:3993
virtual void init_marker(const std::string &m, double size, float width)
Definition: gl-select.cc:71
graphics_object select(const graphics_object &ax, int x, int y, int flags=0)
Definition: gl-select.cc:80
virtual void draw_image(const image::properties &props)
Definition: gl-select.cc:221
virtual Matrix render_text(const std::string &txt, double x, double y, double z, int halign, int valign, double rotation=0.0)
Definition: gl-select.cc:205
void apply_pick_matrix(void)
Definition: gl-select.cc:36
virtual void draw(const graphics_object &go, bool toplevel=true)
Definition: gl-select.cc:151
virtual void setup_opengl_transformation(const axes::properties &props)
Definition: gl-select.cc:64
virtual void draw_text(const text::properties &props)
Definition: gl-select.cc:193
std::map< GLuint, graphics_object > object_map
Definition: gl-select.h:85
void fake_text(double x, double y, double z, const Matrix &bbox, bool use_scale=true)
Definition: gl-select.cc:164
void warning(const char *fmt,...)
Definition: error.cc:1050
#define BUFFER_SIZE
Definition: gl-select.cc:77
QString name
F77_RET_T const F77_DBLE * x
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
@ select_last
Definition: gl-select.h:41
@ select_ignore_hittest
Definition: gl-select.h:40