GNU Octave  8.1.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-2023 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 
33 
34 void
36 {
37  GLdouble p_matrix[16];
38 
39  m_glfcns.glGetDoublev (GL_PROJECTION_MATRIX, p_matrix);
40  m_glfcns.glMatrixMode (GL_PROJECTION);
42 
43  // The following block is equivalent to gluPickMatrix, but we avoid
44  // using glu functions so that we can call OpenGL functions through
45  // the QOpenGLFunctions class so that the OpenGL implementation may
46  // be selected dynamically.
47 
48  Matrix viewport = get_viewport_scaled ();
49 
50  if (size > 0)
51  {
52  m_glfcns.glTranslatef ((viewport(2) - 2 * (xp - viewport(0))) / size,
53  (viewport(3) - 2 * (yp - viewport(1))) / size, 0);
54 
55  m_glfcns.glScalef (viewport(2) / size, viewport(3) / size, 1.0);
56  }
57 
58  m_glfcns.glMultMatrixd (p_matrix);
59  m_glfcns.glMatrixMode (GL_MODELVIEW);
60 }
61 
62 void
64 {
67 }
68 
69 void
70 opengl_selector::init_marker (const std::string& m, double sz, float width)
71 {
72  opengl_renderer::init_marker (m, sz, width);
74 }
75 
76 # define BUFFER_SIZE 128
77 
78 graphics_object
79 opengl_selector::select (const graphics_object& ax, int x, int y, int flags)
80 {
81  m_glfcns.glEnable (GL_DEPTH_TEST);
82  m_glfcns.glDepthFunc (GL_LEQUAL);
83 
84  xp = x;
85  yp = y;
86 
87  GLuint select_buffer[BUFFER_SIZE];
88 
89  m_glfcns.glSelectBuffer (BUFFER_SIZE, select_buffer);
90  m_glfcns.glRenderMode (GL_SELECT);
92 
93  object_map.clear ();
94 
95  draw (ax);
96 
97  int hits = m_glfcns.glRenderMode (GL_RENDER);
98  graphics_object obj;
99 
100  if (hits > 0)
101  {
102  GLuint current_minZ = 0xffffffff;
103  GLuint current_name = 0xffffffff;
104 
105  for (int i = 0, j = 0; i < hits && j < BUFFER_SIZE-3; i++)
106  {
107  GLuint n = select_buffer[j++],
108  minZ = select_buffer[j++];
109 
110  j++; // skip maxZ
111  if (((flags & select_last) == 0 && (minZ <= current_minZ))
112  || ((flags & select_last) != 0 && (minZ >= current_minZ)))
113  {
114  bool candidate = true;
115  GLuint name =
116  select_buffer[std::min (j + n, GLuint (BUFFER_SIZE)) - 1];
117 
118  if ((flags & select_ignore_hittest) == 0)
119  {
120  graphics_object go = object_map[name];
121 
122  if (! go.get_properties ().is_hittest ())
123  candidate = false;
124  }
125 
126  if (candidate)
127  {
128  current_minZ = minZ;
129  current_name = name;
130  }
131 
132  j += n;
133  }
134  else
135  j += n;
136  }
137 
138  if (current_name != 0xffffffff)
139  obj = object_map[current_name];
140  }
141  else if (hits < 0)
142  warning ("opengl_selector::select: selection buffer overflow");
143 
144  object_map.clear ();
145 
146  return obj;
147 }
148 
149 void
150 opengl_selector::draw (const graphics_object& go, bool toplevel)
151 {
152  GLuint name = object_map.size ();
153 
154  object_map[name] = go;
155  m_glfcns.glPushName (name);
156  set_selecting (true);
157  opengl_renderer::draw (go, toplevel);
158  set_selecting (false);
159  m_glfcns.glPopName ();
160 }
161 
162 void
163 opengl_selector::fake_text (double x, double y, double z, const Matrix& bbox,
164  bool use_scale)
165 {
166  ColumnVector xpos, xp1, xp2;
167 
168  xpos = get_transform ().transform (x, y, z, use_scale);
169 
170  xp1 = xp2 = xpos;
171  xp1(0) += bbox(0);
172  xp1(1) -= bbox(1);
173  xp2(0) += (bbox(0) + bbox(2));
174  xp2(1) -= (bbox(1) + bbox(3));
175 
176  ColumnVector p1, p2, p3, p4;
177 
178  p1 = get_transform ().untransform (xp1(0), xp1(1), xp1(2), false);
179  p2 = get_transform ().untransform (xp2(0), xp1(1), xp1(2), false);
180  p3 = get_transform ().untransform (xp2(0), xp2(1), xp1(2), false);
181  p4 = get_transform ().untransform (xp1(0), xp2(1), xp1(2), false);
182 
183  m_glfcns.glBegin (GL_QUADS);
184  m_glfcns.glVertex3dv (p1.data ());
185  m_glfcns.glVertex3dv (p2.data ());
186  m_glfcns.glVertex3dv (p3.data ());
187  m_glfcns.glVertex3dv (p4.data ());
188  m_glfcns.glEnd ();
189 }
190 
191 void
193 {
194  if (props.get_string ().isempty ())
195  return;
196 
197  Matrix pos = props.get_data_position ();
198  const Matrix bbox = props.get_extent_matrix ();
199 
200  fake_text (pos(0), pos(1), pos.numel () > 2 ? pos(2) : 0.0, bbox);
201 }
202 
203 Matrix
204 opengl_selector::render_text (const std::string& txt,
205  double x, double y, double z,
206  int halign, int valign, double rotation)
207 {
208  uint8NDArray pixels;
209  Matrix bbox (1, 4, 0.0);
210 
211  // FIXME: probably more efficient to only compute bbox instead
212  // of doing full text rendering...
213  text_to_pixels (txt, pixels, bbox, halign, valign, rotation);
214  fake_text (x, y, z, bbox, false);
215 
216  return bbox;
217 }
218 
219 void
221 {
222  Matrix xd = props.get_xdata ().matrix_value ();
223  octave_idx_type nc = props.get_cdata ().columns ();
224  double x_pix_size = (nc == 1 ? 1 : (xd(1) - xd(0)) / (nc - 1));
225 
226  Matrix yd = props.get_ydata ().matrix_value ();
227  octave_idx_type nr = props.get_cdata ().rows ();
228  double y_pix_size = (nr == 1 ? 1 : (yd(1) - yd(0)) / (nr - 1));
229 
230  ColumnVector p1(3, 0.0), p2(3, 0.0), p3(3, 0.0), p4(3, 0.0);
231  p1(0) = xd(0) - x_pix_size/2;
232  p1(1) = yd(0) - y_pix_size/2;
233 
234  p2(0) = xd(1) + x_pix_size/2;
235  p2(1) = yd(0) - y_pix_size/2;
236 
237  p3(0) = xd(1) + x_pix_size/2;
238  p3(1) = yd(1) + y_pix_size/2;
239 
240  p4(0) = xd(0) - x_pix_size/2;
241  p4(1) = yd(1) + y_pix_size/2;
242 
243  m_glfcns.glBegin (GL_QUADS);
244  m_glfcns.glVertex3dv (p1.data ());
245  m_glfcns.glVertex3dv (p2.data ());
246  m_glfcns.glVertex3dv (p3.data ());
247  m_glfcns.glVertex3dv (p4.data ());
248  m_glfcns.glEnd ();
249 }
250 
OCTAVE_END_NAMESPACE(octave)
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
OCTARRAY_OVERRIDABLE_FUNC_API const T * data(void) const
Size of the specified dimension.
Definition: Array.h:663
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:414
Definition: dMatrix.h:42
virtual void glPushName(GLuint name)
Definition: oct-opengl.h:365
virtual void glInitNames(void)
Definition: oct-opengl.h:249
virtual void glBegin(GLenum mode)
Definition: oct-opengl.h:78
virtual void glMatrixMode(GLenum mode)
Definition: oct-opengl.h:289
virtual void glSelectBuffer(GLsizei size, GLuint *buffer)
Definition: oct-opengl.h:401
virtual void glScalef(GLfloat x, GLfloat y, GLfloat z)
Definition: oct-opengl.h:396
virtual GLint glRenderMode(GLenum mode)
Definition: oct-opengl.h:381
virtual void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
Definition: oct-opengl.h:434
virtual void glDepthFunc(GLenum fcn)
Definition: oct-opengl.h:163
virtual void glVertex3dv(const GLdouble *v)
Definition: oct-opengl.h:449
virtual void glLoadIdentity(void)
Definition: oct-opengl.h:274
virtual void glEnable(GLenum cap)
Definition: oct-opengl.h:184
virtual void glEnd(void)
Definition: oct-opengl.h:194
virtual void glGetDoublev(GLenum pname, GLdouble *data)
Definition: oct-opengl.h:219
virtual void glMultMatrixd(const GLdouble *m)
Definition: oct-opengl.h:294
virtual void glPopName(void)
Definition: oct-opengl.h:350
virtual graphics_xform get_transform(void) const
Definition: gl-render.h:66
opengl_functions & m_glfcns
Definition: gl-render.h:166
virtual void init_marker(const std::string &m, double size, float width)
Definition: gl-render.cc:4446
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:4875
virtual void draw(const graphics_object &go, bool toplevel=true)
Definition: gl-render.cc:714
virtual void set_selecting(bool on)
Definition: gl-render.h:114
virtual Matrix get_viewport_scaled(void) const
Definition: gl-render.cc:4194
virtual void setup_opengl_transformation(const axes::properties &props)
Definition: gl-render.cc:1272
virtual void draw_image(const image::properties &props)
Definition: gl-select.cc:220
virtual void draw(const graphics_object &go, bool toplevel=true)
Definition: gl-select.cc:150
virtual void setup_opengl_transformation(const axes::properties &props)
Definition: gl-select.cc:63
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:204
graphics_object select(const graphics_object &ax, int x, int y, int flags=0)
Definition: gl-select.cc:79
std::map< GLuint, graphics_object > object_map
Definition: gl-select.h:84
void apply_pick_matrix(void)
Definition: gl-select.cc:35
virtual void draw_text(const text::properties &props)
Definition: gl-select.cc:192
virtual void init_marker(const std::string &m, double size, float width)
Definition: gl-select.cc:70
void fake_text(double x, double y, double z, const Matrix &bbox, bool use_scale=true)
Definition: gl-select.cc:163
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
Definition: error.cc:1054
#define BUFFER_SIZE
Definition: gl-select.cc:76
@ select_ignore_hittest
Definition: gl-select.h:39
@ select_last
Definition: gl-select.h:40
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
T::properties & properties(graphics_object obj)