GNU Octave 7.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-2022 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
32namespace 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
79 graphics_object
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 {
121 graphics_object go = object_map[name];
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);
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:411
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:616
Definition: dMatrix.h:42
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:165
virtual void draw(const graphics_object &go, bool toplevel=true)
Definition: gl-render.cc:714
virtual void init_marker(const std::string &m, double size, float width)
Definition: gl-render.cc:4450
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:4879
virtual void set_selecting(bool on)
Definition: gl-render.h:114
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:4198
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:1055
#define BUFFER_SIZE
Definition: gl-select.cc:77
QString name
F77_RET_T const F77_DBLE * x
T::properties & properties(graphics_object obj)
@ select_last
Definition: gl-select.h:41
@ select_ignore_hittest
Definition: gl-select.h:40