1 | // This file is part of Eigen, a lightweight C++ template library
|
---|
2 | // for linear algebra.
|
---|
3 | //
|
---|
4 | // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
---|
5 | //
|
---|
6 | // This Source Code Form is subject to the terms of the Mozilla
|
---|
7 | // Public License v. 2.0. If a copy of the MPL was not distributed
|
---|
8 | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
---|
9 |
|
---|
10 | #include <main.h>
|
---|
11 | #include <iostream>
|
---|
12 | #include <GL/glew.h>
|
---|
13 | #include <Eigen/OpenGLSupport>
|
---|
14 | #include <GL/glut.h>
|
---|
15 | using namespace Eigen;
|
---|
16 |
|
---|
17 |
|
---|
18 |
|
---|
19 |
|
---|
20 | #define VERIFY_MATRIX(CODE,REF) { \
|
---|
21 | glLoadIdentity(); \
|
---|
22 | CODE; \
|
---|
23 | Matrix<float,4,4,ColMajor> m; m.setZero(); \
|
---|
24 | glGet(GL_MODELVIEW_MATRIX, m); \
|
---|
25 | if(!(REF).cast<float>().isApprox(m)) { \
|
---|
26 | std::cerr << "Expected:\n" << ((REF).cast<float>()) << "\n" << "got\n" << m << "\n\n"; \
|
---|
27 | } \
|
---|
28 | VERIFY_IS_APPROX((REF).cast<float>(), m); \
|
---|
29 | }
|
---|
30 |
|
---|
31 | #define VERIFY_UNIFORM(SUFFIX,NAME,TYPE) { \
|
---|
32 | TYPE value; value.setRandom(); \
|
---|
33 | TYPE data; \
|
---|
34 | int loc = glGetUniformLocation(prg_id, #NAME); \
|
---|
35 | VERIFY((loc!=-1) && "uniform not found"); \
|
---|
36 | glUniform(loc,value); \
|
---|
37 | EIGEN_CAT(glGetUniform,SUFFIX)(prg_id,loc,data.data()); \
|
---|
38 | if(!value.isApprox(data)) { \
|
---|
39 | std::cerr << "Expected:\n" << value << "\n" << "got\n" << data << "\n\n"; \
|
---|
40 | } \
|
---|
41 | VERIFY_IS_APPROX(value, data); \
|
---|
42 | }
|
---|
43 |
|
---|
44 | #define VERIFY_UNIFORMi(NAME,TYPE) { \
|
---|
45 | TYPE value = TYPE::Random().eval().cast<float>().cast<TYPE::Scalar>(); \
|
---|
46 | TYPE data; \
|
---|
47 | int loc = glGetUniformLocation(prg_id, #NAME); \
|
---|
48 | VERIFY((loc!=-1) && "uniform not found"); \
|
---|
49 | glUniform(loc,value); \
|
---|
50 | glGetUniformiv(prg_id,loc,(GLint*)data.data()); \
|
---|
51 | if(!value.isApprox(data)) { \
|
---|
52 | std::cerr << "Expected:\n" << value << "\n" << "got\n" << data << "\n\n"; \
|
---|
53 | } \
|
---|
54 | VERIFY_IS_APPROX(value, data); \
|
---|
55 | }
|
---|
56 |
|
---|
57 | void printInfoLog(GLuint objectID)
|
---|
58 | {
|
---|
59 | int infologLength, charsWritten;
|
---|
60 | GLchar *infoLog;
|
---|
61 | glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength);
|
---|
62 | if(infologLength > 0)
|
---|
63 | {
|
---|
64 | infoLog = new GLchar[infologLength];
|
---|
65 | glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog);
|
---|
66 | if (charsWritten>0)
|
---|
67 | std::cerr << "Shader info : \n" << infoLog << std::endl;
|
---|
68 | delete[] infoLog;
|
---|
69 | }
|
---|
70 | }
|
---|
71 |
|
---|
72 | GLint createShader(const char* vtx, const char* frg)
|
---|
73 | {
|
---|
74 | GLint prg_id = glCreateProgram();
|
---|
75 | GLint vtx_id = glCreateShader(GL_VERTEX_SHADER);
|
---|
76 | GLint frg_id = glCreateShader(GL_FRAGMENT_SHADER);
|
---|
77 | GLint ok;
|
---|
78 |
|
---|
79 | glShaderSource(vtx_id, 1, &vtx, 0);
|
---|
80 | glCompileShader(vtx_id);
|
---|
81 | glGetShaderiv(vtx_id,GL_COMPILE_STATUS,&ok);
|
---|
82 | if(!ok)
|
---|
83 | {
|
---|
84 | std::cerr << "vtx compilation failed\n";
|
---|
85 | }
|
---|
86 |
|
---|
87 | glShaderSource(frg_id, 1, &frg, 0);
|
---|
88 | glCompileShader(frg_id);
|
---|
89 | glGetShaderiv(frg_id,GL_COMPILE_STATUS,&ok);
|
---|
90 | if(!ok)
|
---|
91 | {
|
---|
92 | std::cerr << "frg compilation failed\n";
|
---|
93 | }
|
---|
94 |
|
---|
95 | glAttachShader(prg_id, vtx_id);
|
---|
96 | glAttachShader(prg_id, frg_id);
|
---|
97 | glLinkProgram(prg_id);
|
---|
98 | glGetProgramiv(prg_id,GL_LINK_STATUS,&ok);
|
---|
99 | if(!ok)
|
---|
100 | {
|
---|
101 | std::cerr << "linking failed\n";
|
---|
102 | }
|
---|
103 | printInfoLog(prg_id);
|
---|
104 |
|
---|
105 | glUseProgram(prg_id);
|
---|
106 | return prg_id;
|
---|
107 | }
|
---|
108 |
|
---|
109 | void test_openglsupport()
|
---|
110 | {
|
---|
111 | int argc = 0;
|
---|
112 | glutInit(&argc, 0);
|
---|
113 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
|
---|
114 | glutInitWindowPosition (0,0);
|
---|
115 | glutInitWindowSize(10, 10);
|
---|
116 |
|
---|
117 | if(glutCreateWindow("Eigen") <= 0)
|
---|
118 | {
|
---|
119 | std::cerr << "Error: Unable to create GLUT Window.\n";
|
---|
120 | exit(1);
|
---|
121 | }
|
---|
122 |
|
---|
123 | glewExperimental = GL_TRUE;
|
---|
124 | if(glewInit() != GLEW_OK)
|
---|
125 | {
|
---|
126 | std::cerr << "Warning: Failed to initialize GLEW\n";
|
---|
127 | }
|
---|
128 |
|
---|
129 | Vector3f v3f;
|
---|
130 | Matrix3f rot;
|
---|
131 | glBegin(GL_POINTS);
|
---|
132 |
|
---|
133 | glVertex(v3f);
|
---|
134 | glVertex(2*v3f+v3f);
|
---|
135 | glVertex(rot*v3f);
|
---|
136 |
|
---|
137 | glEnd();
|
---|
138 |
|
---|
139 | // 4x4 matrices
|
---|
140 | Matrix4f mf44; mf44.setRandom();
|
---|
141 | VERIFY_MATRIX(glLoadMatrix(mf44), mf44);
|
---|
142 | VERIFY_MATRIX(glMultMatrix(mf44), mf44);
|
---|
143 | Matrix4d md44; md44.setRandom();
|
---|
144 | VERIFY_MATRIX(glLoadMatrix(md44), md44);
|
---|
145 | VERIFY_MATRIX(glMultMatrix(md44), md44);
|
---|
146 |
|
---|
147 | // Quaternion
|
---|
148 | Quaterniond qd(AngleAxisd(internal::random<double>(), Vector3d::Random()));
|
---|
149 | VERIFY_MATRIX(glRotate(qd), Projective3d(qd).matrix());
|
---|
150 |
|
---|
151 | Quaternionf qf(AngleAxisf(internal::random<double>(), Vector3f::Random()));
|
---|
152 | VERIFY_MATRIX(glRotate(qf), Projective3f(qf).matrix());
|
---|
153 |
|
---|
154 | // 3D Transform
|
---|
155 | Transform<float,3,AffineCompact> acf3; acf3.matrix().setRandom();
|
---|
156 | VERIFY_MATRIX(glLoadMatrix(acf3), Projective3f(acf3).matrix());
|
---|
157 | VERIFY_MATRIX(glMultMatrix(acf3), Projective3f(acf3).matrix());
|
---|
158 |
|
---|
159 | Transform<float,3,Affine> af3(acf3);
|
---|
160 | VERIFY_MATRIX(glLoadMatrix(af3), Projective3f(af3).matrix());
|
---|
161 | VERIFY_MATRIX(glMultMatrix(af3), Projective3f(af3).matrix());
|
---|
162 |
|
---|
163 | Transform<float,3,Projective> pf3; pf3.matrix().setRandom();
|
---|
164 | VERIFY_MATRIX(glLoadMatrix(pf3), Projective3f(pf3).matrix());
|
---|
165 | VERIFY_MATRIX(glMultMatrix(pf3), Projective3f(pf3).matrix());
|
---|
166 |
|
---|
167 | Transform<double,3,AffineCompact> acd3; acd3.matrix().setRandom();
|
---|
168 | VERIFY_MATRIX(glLoadMatrix(acd3), Projective3d(acd3).matrix());
|
---|
169 | VERIFY_MATRIX(glMultMatrix(acd3), Projective3d(acd3).matrix());
|
---|
170 |
|
---|
171 | Transform<double,3,Affine> ad3(acd3);
|
---|
172 | VERIFY_MATRIX(glLoadMatrix(ad3), Projective3d(ad3).matrix());
|
---|
173 | VERIFY_MATRIX(glMultMatrix(ad3), Projective3d(ad3).matrix());
|
---|
174 |
|
---|
175 | Transform<double,3,Projective> pd3; pd3.matrix().setRandom();
|
---|
176 | VERIFY_MATRIX(glLoadMatrix(pd3), Projective3d(pd3).matrix());
|
---|
177 | VERIFY_MATRIX(glMultMatrix(pd3), Projective3d(pd3).matrix());
|
---|
178 |
|
---|
179 | // translations (2D and 3D)
|
---|
180 | {
|
---|
181 | Vector2f vf2; vf2.setRandom(); Vector3f vf23; vf23 << vf2, 0;
|
---|
182 | VERIFY_MATRIX(glTranslate(vf2), Projective3f(Translation3f(vf23)).matrix());
|
---|
183 | Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 0;
|
---|
184 | VERIFY_MATRIX(glTranslate(vd2), Projective3d(Translation3d(vd23)).matrix());
|
---|
185 |
|
---|
186 | Vector3f vf3; vf3.setRandom();
|
---|
187 | VERIFY_MATRIX(glTranslate(vf3), Projective3f(Translation3f(vf3)).matrix());
|
---|
188 | Vector3d vd3; vd3.setRandom();
|
---|
189 | VERIFY_MATRIX(glTranslate(vd3), Projective3d(Translation3d(vd3)).matrix());
|
---|
190 |
|
---|
191 | Translation<float,3> tf3; tf3.vector().setRandom();
|
---|
192 | VERIFY_MATRIX(glTranslate(tf3), Projective3f(tf3).matrix());
|
---|
193 |
|
---|
194 | Translation<double,3> td3; td3.vector().setRandom();
|
---|
195 | VERIFY_MATRIX(glTranslate(td3), Projective3d(td3).matrix());
|
---|
196 | }
|
---|
197 |
|
---|
198 | // scaling (2D and 3D)
|
---|
199 | {
|
---|
200 | Vector2f vf2; vf2.setRandom(); Vector3f vf23; vf23 << vf2, 1;
|
---|
201 | VERIFY_MATRIX(glScale(vf2), Projective3f(Scaling(vf23)).matrix());
|
---|
202 | Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 1;
|
---|
203 | VERIFY_MATRIX(glScale(vd2), Projective3d(Scaling(vd23)).matrix());
|
---|
204 |
|
---|
205 | Vector3f vf3; vf3.setRandom();
|
---|
206 | VERIFY_MATRIX(glScale(vf3), Projective3f(Scaling(vf3)).matrix());
|
---|
207 | Vector3d vd3; vd3.setRandom();
|
---|
208 | VERIFY_MATRIX(glScale(vd3), Projective3d(Scaling(vd3)).matrix());
|
---|
209 |
|
---|
210 | UniformScaling<float> usf(internal::random<float>());
|
---|
211 | VERIFY_MATRIX(glScale(usf), Projective3f(usf).matrix());
|
---|
212 |
|
---|
213 | UniformScaling<double> usd(internal::random<double>());
|
---|
214 | VERIFY_MATRIX(glScale(usd), Projective3d(usd).matrix());
|
---|
215 | }
|
---|
216 |
|
---|
217 | // uniform
|
---|
218 | {
|
---|
219 | const char* vtx = "void main(void) { gl_Position = gl_Vertex; }\n";
|
---|
220 |
|
---|
221 | if(GLEW_VERSION_2_0)
|
---|
222 | {
|
---|
223 | #ifdef GL_VERSION_2_0
|
---|
224 | const char* frg = ""
|
---|
225 | "uniform vec2 v2f;\n"
|
---|
226 | "uniform vec3 v3f;\n"
|
---|
227 | "uniform vec4 v4f;\n"
|
---|
228 | "uniform ivec2 v2i;\n"
|
---|
229 | "uniform ivec3 v3i;\n"
|
---|
230 | "uniform ivec4 v4i;\n"
|
---|
231 | "uniform mat2 m2f;\n"
|
---|
232 | "uniform mat3 m3f;\n"
|
---|
233 | "uniform mat4 m4f;\n"
|
---|
234 | "void main(void) { gl_FragColor = vec4(v2f[0]+v3f[0]+v4f[0])+vec4(v2i[0]+v3i[0]+v4i[0])+vec4(m2f[0][0]+m3f[0][0]+m4f[0][0]); }\n";
|
---|
235 |
|
---|
236 | GLint prg_id = createShader(vtx,frg);
|
---|
237 |
|
---|
238 | VERIFY_UNIFORM(fv,v2f, Vector2f);
|
---|
239 | VERIFY_UNIFORM(fv,v3f, Vector3f);
|
---|
240 | VERIFY_UNIFORM(fv,v4f, Vector4f);
|
---|
241 | VERIFY_UNIFORMi(v2i, Vector2i);
|
---|
242 | VERIFY_UNIFORMi(v3i, Vector3i);
|
---|
243 | VERIFY_UNIFORMi(v4i, Vector4i);
|
---|
244 | VERIFY_UNIFORM(fv,m2f, Matrix2f);
|
---|
245 | VERIFY_UNIFORM(fv,m3f, Matrix3f);
|
---|
246 | VERIFY_UNIFORM(fv,m4f, Matrix4f);
|
---|
247 | #endif
|
---|
248 | }
|
---|
249 | else
|
---|
250 | std::cerr << "Warning: opengl 2.0 was not tested\n";
|
---|
251 |
|
---|
252 | if(GLEW_VERSION_2_1)
|
---|
253 | {
|
---|
254 | #ifdef GL_VERSION_2_1
|
---|
255 | const char* frg = "#version 120\n"
|
---|
256 | "uniform mat2x3 m23f;\n"
|
---|
257 | "uniform mat3x2 m32f;\n"
|
---|
258 | "uniform mat2x4 m24f;\n"
|
---|
259 | "uniform mat4x2 m42f;\n"
|
---|
260 | "uniform mat3x4 m34f;\n"
|
---|
261 | "uniform mat4x3 m43f;\n"
|
---|
262 | "void main(void) { gl_FragColor = vec4(m23f[0][0]+m32f[0][0]+m24f[0][0]+m42f[0][0]+m34f[0][0]+m43f[0][0]); }\n";
|
---|
263 |
|
---|
264 | GLint prg_id = createShader(vtx,frg);
|
---|
265 |
|
---|
266 | typedef Matrix<float,2,3> Matrix23f;
|
---|
267 | typedef Matrix<float,3,2> Matrix32f;
|
---|
268 | typedef Matrix<float,2,4> Matrix24f;
|
---|
269 | typedef Matrix<float,4,2> Matrix42f;
|
---|
270 | typedef Matrix<float,3,4> Matrix34f;
|
---|
271 | typedef Matrix<float,4,3> Matrix43f;
|
---|
272 |
|
---|
273 | VERIFY_UNIFORM(fv,m23f, Matrix23f);
|
---|
274 | VERIFY_UNIFORM(fv,m32f, Matrix32f);
|
---|
275 | VERIFY_UNIFORM(fv,m24f, Matrix24f);
|
---|
276 | VERIFY_UNIFORM(fv,m42f, Matrix42f);
|
---|
277 | VERIFY_UNIFORM(fv,m34f, Matrix34f);
|
---|
278 | VERIFY_UNIFORM(fv,m43f, Matrix43f);
|
---|
279 | #endif
|
---|
280 | }
|
---|
281 | else
|
---|
282 | std::cerr << "Warning: opengl 2.1 was not tested\n";
|
---|
283 |
|
---|
284 | if(GLEW_VERSION_3_0)
|
---|
285 | {
|
---|
286 | #ifdef GL_VERSION_3_0
|
---|
287 | const char* frg = "#version 150\n"
|
---|
288 | "uniform uvec2 v2ui;\n"
|
---|
289 | "uniform uvec3 v3ui;\n"
|
---|
290 | "uniform uvec4 v4ui;\n"
|
---|
291 | "out vec4 data;\n"
|
---|
292 | "void main(void) { data = vec4(v2ui[0]+v3ui[0]+v4ui[0]); }\n";
|
---|
293 |
|
---|
294 | GLint prg_id = createShader(vtx,frg);
|
---|
295 |
|
---|
296 | typedef Matrix<unsigned int,2,1> Vector2ui;
|
---|
297 | typedef Matrix<unsigned int,3,1> Vector3ui;
|
---|
298 | typedef Matrix<unsigned int,4,1> Vector4ui;
|
---|
299 |
|
---|
300 | VERIFY_UNIFORMi(v2ui, Vector2ui);
|
---|
301 | VERIFY_UNIFORMi(v3ui, Vector3ui);
|
---|
302 | VERIFY_UNIFORMi(v4ui, Vector4ui);
|
---|
303 | #endif
|
---|
304 | }
|
---|
305 | else
|
---|
306 | std::cerr << "Warning: opengl 3.0 was not tested\n";
|
---|
307 |
|
---|
308 | #ifdef GLEW_ARB_gpu_shader_fp64
|
---|
309 | if(GLEW_ARB_gpu_shader_fp64)
|
---|
310 | {
|
---|
311 | #ifdef GL_ARB_gpu_shader_fp64
|
---|
312 | const char* frg = "#version 150\n"
|
---|
313 | "uniform dvec2 v2d;\n"
|
---|
314 | "uniform dvec3 v3d;\n"
|
---|
315 | "uniform dvec4 v4d;\n"
|
---|
316 | "out vec4 data;\n"
|
---|
317 | "void main(void) { data = vec4(v2d[0]+v3d[0]+v4d[0]); }\n";
|
---|
318 |
|
---|
319 | GLint prg_id = createShader(vtx,frg);
|
---|
320 |
|
---|
321 | typedef Vector2d Vector2d;
|
---|
322 | typedef Vector3d Vector3d;
|
---|
323 | typedef Vector4d Vector4d;
|
---|
324 |
|
---|
325 | VERIFY_UNIFORM(dv,v2d, Vector2d);
|
---|
326 | VERIFY_UNIFORM(dv,v3d, Vector3d);
|
---|
327 | VERIFY_UNIFORM(dv,v4d, Vector4d);
|
---|
328 | #endif
|
---|
329 | }
|
---|
330 | else
|
---|
331 | std::cerr << "Warning: GLEW_ARB_gpu_shader_fp64 was not tested\n";
|
---|
332 | #else
|
---|
333 | std::cerr << "Warning: GLEW_ARB_gpu_shader_fp64 was not tested\n";
|
---|
334 | #endif
|
---|
335 | }
|
---|
336 |
|
---|
337 | }
|
---|