Skip to content

Commit 1703ab0

Browse files
committed
Add simple OpenGL viewer example.
1 parent 93acf63 commit 1703ab0

File tree

5 files changed

+779
-0
lines changed

5 files changed

+779
-0
lines changed

examples/viewer/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
GLFW_INC=-I/usr/local/include
2+
GLFW_LIBS=-L/usr/local/lib -lglfw3 -lglew
3+
GL_LIBS=-framework OpenGL
4+
5+
CXX_FLAGS=-Wno-deprecated-declarations
6+
7+
all:
8+
g++ -fsanitize=address -O0 -g -o objviewer $(CXX_FLAGS) viewer.cc ../../tiny_obj_loader.cc trackball.cc $(GLFW_INC) $(GL_LIBS) $(GLFW_LIBS)

examples/viewer/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Simple .obj viewer with glew + glfw3 + OpenGL

examples/viewer/trackball.cc

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/*
2+
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
3+
* ALL RIGHTS RESERVED
4+
* Permission to use, copy, modify, and distribute this software for
5+
* any purpose and without fee is hereby granted, provided that the above
6+
* copyright notice appear in all copies and that both the copyright notice
7+
* and this permission notice appear in supporting documentation, and that
8+
* the name of Silicon Graphics, Inc. not be used in advertising
9+
* or publicity pertaining to distribution of the software without specific,
10+
* written prior permission.
11+
*
12+
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13+
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14+
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15+
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
16+
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17+
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18+
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19+
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20+
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
21+
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22+
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23+
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24+
*
25+
* US Government Users Restricted Rights
26+
* Use, duplication, or disclosure by the Government is subject to
27+
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
28+
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
29+
* clause at DFARS 252.227-7013 and/or in similar or successor
30+
* clauses in the FAR or the DOD or NASA FAR Supplement.
31+
* Unpublished-- rights reserved under the copyright laws of the
32+
* United States. Contractor/manufacturer is Silicon Graphics,
33+
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
34+
*
35+
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
36+
*/
37+
/*
38+
* Trackball code:
39+
*
40+
* Implementation of a virtual trackball.
41+
* Implemented by Gavin Bell, lots of ideas from Thant Tessman and
42+
* the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
43+
*
44+
* Vector manip code:
45+
*
46+
* Original code from:
47+
* David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
48+
*
49+
* Much mucking with by:
50+
* Gavin Bell
51+
*/
52+
#include <math.h>
53+
#include "trackball.h"
54+
55+
/*
56+
* This size should really be based on the distance from the center of
57+
* rotation to the point on the object underneath the mouse. That
58+
* point would then track the mouse as closely as possible. This is a
59+
* simple example, though, so that is left as an Exercise for the
60+
* Programmer.
61+
*/
62+
#define TRACKBALLSIZE (0.8)
63+
64+
/*
65+
* Local function prototypes (not defined in trackball.h)
66+
*/
67+
static float tb_project_to_sphere(float, float, float);
68+
static void normalize_quat(float[4]);
69+
70+
static void vzero(float *v) {
71+
v[0] = 0.0;
72+
v[1] = 0.0;
73+
v[2] = 0.0;
74+
}
75+
76+
static void vset(float *v, float x, float y, float z) {
77+
v[0] = x;
78+
v[1] = y;
79+
v[2] = z;
80+
}
81+
82+
static void vsub(const float *src1, const float *src2, float *dst) {
83+
dst[0] = src1[0] - src2[0];
84+
dst[1] = src1[1] - src2[1];
85+
dst[2] = src1[2] - src2[2];
86+
}
87+
88+
static void vcopy(const float *v1, float *v2) {
89+
register int i;
90+
for (i = 0; i < 3; i++)
91+
v2[i] = v1[i];
92+
}
93+
94+
static void vcross(const float *v1, const float *v2, float *cross) {
95+
float temp[3];
96+
97+
temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
98+
temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
99+
temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
100+
vcopy(temp, cross);
101+
}
102+
103+
static float vlength(const float *v) {
104+
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
105+
}
106+
107+
static void vscale(float *v, float div) {
108+
v[0] *= div;
109+
v[1] *= div;
110+
v[2] *= div;
111+
}
112+
113+
static void vnormal(float *v) { vscale(v, 1.0 / vlength(v)); }
114+
115+
static float vdot(const float *v1, const float *v2) {
116+
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
117+
}
118+
119+
static void vadd(const float *src1, const float *src2, float *dst) {
120+
dst[0] = src1[0] + src2[0];
121+
dst[1] = src1[1] + src2[1];
122+
dst[2] = src1[2] + src2[2];
123+
}
124+
125+
/*
126+
* Ok, simulate a track-ball. Project the points onto the virtual
127+
* trackball, then figure out the axis of rotation, which is the cross
128+
* product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
129+
* Note: This is a deformed trackball-- is a trackball in the center,
130+
* but is deformed into a hyperbolic sheet of rotation away from the
131+
* center. This particular function was chosen after trying out
132+
* several variations.
133+
*
134+
* It is assumed that the arguments to this routine are in the range
135+
* (-1.0 ... 1.0)
136+
*/
137+
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y) {
138+
float a[3]; /* Axis of rotation */
139+
float phi; /* how much to rotate about axis */
140+
float p1[3], p2[3], d[3];
141+
float t;
142+
143+
if (p1x == p2x && p1y == p2y) {
144+
/* Zero rotation */
145+
vzero(q);
146+
q[3] = 1.0;
147+
return;
148+
}
149+
150+
/*
151+
* First, figure out z-coordinates for projection of P1 and P2 to
152+
* deformed sphere
153+
*/
154+
vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
155+
vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));
156+
157+
/*
158+
* Now, we want the cross product of P1 and P2
159+
*/
160+
vcross(p2, p1, a);
161+
162+
/*
163+
* Figure out how much to rotate around that axis.
164+
*/
165+
vsub(p1, p2, d);
166+
t = vlength(d) / (2.0 * TRACKBALLSIZE);
167+
168+
/*
169+
* Avoid problems with out-of-control values...
170+
*/
171+
if (t > 1.0)
172+
t = 1.0;
173+
if (t < -1.0)
174+
t = -1.0;
175+
phi = 2.0 * asin(t);
176+
177+
axis_to_quat(a, phi, q);
178+
}
179+
180+
/*
181+
* Given an axis and angle, compute quaternion.
182+
*/
183+
void axis_to_quat(float a[3], float phi, float q[4]) {
184+
vnormal(a);
185+
vcopy(a, q);
186+
vscale(q, sin(phi / 2.0));
187+
q[3] = cos(phi / 2.0);
188+
}
189+
190+
/*
191+
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
192+
* if we are away from the center of the sphere.
193+
*/
194+
static float tb_project_to_sphere(float r, float x, float y) {
195+
float d, t, z;
196+
197+
d = sqrt(x * x + y * y);
198+
if (d < r * 0.70710678118654752440) { /* Inside sphere */
199+
z = sqrt(r * r - d * d);
200+
} else { /* On hyperbola */
201+
t = r / 1.41421356237309504880;
202+
z = t * t / d;
203+
}
204+
return z;
205+
}
206+
207+
/*
208+
* Given two rotations, e1 and e2, expressed as quaternion rotations,
209+
* figure out the equivalent single rotation and stuff it into dest.
210+
*
211+
* This routine also normalizes the result every RENORMCOUNT times it is
212+
* called, to keep error from creeping in.
213+
*
214+
* NOTE: This routine is written so that q1 or q2 may be the same
215+
* as dest (or each other).
216+
*/
217+
218+
#define RENORMCOUNT 97
219+
220+
void add_quats(float q1[4], float q2[4], float dest[4]) {
221+
static int count = 0;
222+
float t1[4], t2[4], t3[4];
223+
float tf[4];
224+
225+
vcopy(q1, t1);
226+
vscale(t1, q2[3]);
227+
228+
vcopy(q2, t2);
229+
vscale(t2, q1[3]);
230+
231+
vcross(q2, q1, t3);
232+
vadd(t1, t2, tf);
233+
vadd(t3, tf, tf);
234+
tf[3] = q1[3] * q2[3] - vdot(q1, q2);
235+
236+
dest[0] = tf[0];
237+
dest[1] = tf[1];
238+
dest[2] = tf[2];
239+
dest[3] = tf[3];
240+
241+
if (++count > RENORMCOUNT) {
242+
count = 0;
243+
normalize_quat(dest);
244+
}
245+
}
246+
247+
/*
248+
* Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
249+
* If they don't add up to 1.0, dividing by their magnitued will
250+
* renormalize them.
251+
*
252+
* Note: See the following for more information on quaternions:
253+
*
254+
* - Shoemake, K., Animating rotation with quaternion curves, Computer
255+
* Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
256+
* - Pletinckx, D., Quaternion calculus as a basic tool in computer
257+
* graphics, The Visual Computer 5, 2-13, 1989.
258+
*/
259+
static void normalize_quat(float q[4]) {
260+
int i;
261+
float mag;
262+
263+
mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
264+
for (i = 0; i < 4; i++)
265+
q[i] /= mag;
266+
}
267+
268+
/*
269+
* Build a rotation matrix, given a quaternion rotation.
270+
*
271+
*/
272+
void build_rotmatrix(float m[4][4], const float q[4]) {
273+
m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
274+
m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
275+
m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
276+
m[0][3] = 0.0;
277+
278+
m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
279+
m[1][1] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
280+
m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
281+
m[1][3] = 0.0;
282+
283+
m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
284+
m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
285+
m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
286+
m[2][3] = 0.0;
287+
288+
m[3][0] = 0.0;
289+
m[3][1] = 0.0;
290+
m[3][2] = 0.0;
291+
m[3][3] = 1.0;
292+
}

examples/viewer/trackball.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
3+
* ALL RIGHTS RESERVED
4+
* Permission to use, copy, modify, and distribute this software for
5+
* any purpose and without fee is hereby granted, provided that the above
6+
* copyright notice appear in all copies and that both the copyright notice
7+
* and this permission notice appear in supporting documentation, and that
8+
* the name of Silicon Graphics, Inc. not be used in advertising
9+
* or publicity pertaining to distribution of the software without specific,
10+
* written prior permission.
11+
*
12+
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13+
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14+
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15+
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
16+
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17+
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18+
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19+
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20+
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
21+
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22+
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23+
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24+
*
25+
* US Government Users Restricted Rights
26+
* Use, duplication, or disclosure by the Government is subject to
27+
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
28+
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
29+
* clause at DFARS 252.227-7013 and/or in similar or successor
30+
* clauses in the FAR or the DOD or NASA FAR Supplement.
31+
* Unpublished-- rights reserved under the copyright laws of the
32+
* United States. Contractor/manufacturer is Silicon Graphics,
33+
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
34+
*
35+
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
36+
*/
37+
/*
38+
* trackball.h
39+
* A virtual trackball implementation
40+
* Written by Gavin Bell for Silicon Graphics, November 1988.
41+
*/
42+
43+
/*
44+
* Pass the x and y coordinates of the last and current positions of
45+
* the mouse, scaled so they are from (-1.0 ... 1.0).
46+
*
47+
* The resulting rotation is returned as a quaternion rotation in the
48+
* first paramater.
49+
*/
50+
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
51+
52+
void negate_quat(float *q, float *qn);
53+
54+
/*
55+
* Given two quaternions, add them together to get a third quaternion.
56+
* Adding quaternions to get a compound rotation is analagous to adding
57+
* translations to get a compound translation. When incrementally
58+
* adding rotations, the first argument here should be the new
59+
* rotation, the second and third the total rotation (which will be
60+
* over-written with the resulting new total rotation).
61+
*/
62+
void add_quats(float *q1, float *q2, float *dest);
63+
64+
/*
65+
* A useful function, builds a rotation matrix in Matrix based on
66+
* given quaternion.
67+
*/
68+
void build_rotmatrix(float m[4][4], const float q[4]);
69+
70+
/*
71+
* This function computes a quaternion based on an axis (defined by
72+
* the given vector) and an angle about which to rotate. The angle is
73+
* expressed in radians. The result is put into the third argument.
74+
*/
75+
void axis_to_quat(float a[3], float phi, float q[4]);

0 commit comments

Comments
 (0)