1 /*
2 Copyright (c) 2014-2015 Timur Gafarov
3 
4 Boost Software License - Version 1.0 - August 17th, 2003
5 
6 Permission is hereby granted, free of charge, to any person or organization
7 obtaining a copy of the software and accompanying documentation covered by
8 this license (the "Software") to use, reproduce, display, distribute,
9 execute, and transmit the Software, and to prepare derivative works of the
10 Software, and to permit third-parties to whom the Software is furnished to
11 do so, all subject to the following:
12 
13 The copyright notices in the Software and this entire statement, including
14 the above license grant, this restriction and the following disclaimer,
15 must be included in all copies of the Software, in whole or in part, and
16 all derivative works of the Software, unless such copies or derivative
17 works are solely in the form of machine-executable object code generated by
18 a source language processor.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 */
28 
29 module dgl.graphics.shapes;
30 
31 import derelict.opengl.gl;
32 import derelict.opengl.glu;
33 import dlib.core.memory;
34 import dlib.math.vector;
35 import dgl.core.interfaces;
36 
37 class ShapeSphere: Drawable
38 {
39     uint displayList;
40 
41     this(float r)
42     {
43         GLUquadricObj* quadric = gluNewQuadric();
44         gluQuadricNormals(quadric, GLU_SMOOTH);
45         gluQuadricTexture(quadric, GL_TRUE);
46 
47         displayList = glGenLists(1);
48         glNewList(displayList, GL_COMPILE);
49         gluSphere(quadric, r, 24, 16);
50         glEndList();
51 
52         gluDeleteQuadric(quadric);
53     }
54 
55     override void draw(double dt)
56     {
57         glCallList(displayList);
58     }
59 
60     void free()
61     {
62         Delete(this);
63     }
64 
65     ~this()
66     {
67         glDeleteLists(displayList, 1);
68     }
69 }
70 
71 class ShapeBox: Drawable
72 {
73     uint displayList;
74 
75     this(Vector3f hsize)
76     {
77         displayList = glGenLists(1);
78         glNewList(displayList, GL_COMPILE);
79 
80         Vector3f pmax = +hsize;
81         Vector3f pmin = -hsize;
82 
83         glBegin(GL_QUADS);
84 
85             glNormal3f(0,0,1); glVertex3f(pmin.x,pmin.y,pmax.z);
86             glNormal3f(0,0,1); glVertex3f(pmax.x,pmin.y,pmax.z);
87             glNormal3f(0,0,1); glVertex3f(pmax.x,pmax.y,pmax.z);
88             glNormal3f(0,0,1); glVertex3f(pmin.x,pmax.y,pmax.z);
89 
90             glNormal3f(1,0,0); glVertex3f(pmax.x,pmin.y,pmax.z);
91             glNormal3f(1,0,0); glVertex3f(pmax.x,pmin.y,pmin.z);
92             glNormal3f(1,0,0); glVertex3f(pmax.x,pmax.y,pmin.z);
93             glNormal3f(1,0,0); glVertex3f(pmax.x,pmax.y,pmax.z);
94 
95             glNormal3f(0,1,0); glVertex3f(pmin.x,pmax.y,pmax.z);
96             glNormal3f(0,1,0); glVertex3f(pmax.x,pmax.y,pmax.z);
97             glNormal3f(0,1,0); glVertex3f(pmax.x,pmax.y,pmin.z);
98             glNormal3f(0,1,0); glVertex3f(pmin.x,pmax.y,pmin.z);
99 
100             glNormal3f(0,0,-1); glVertex3f(pmin.x,pmin.y,pmin.z);
101             glNormal3f(0,0,-1); glVertex3f(pmin.x,pmax.y,pmin.z);
102             glNormal3f(0,0,-1); glVertex3f(pmax.x,pmax.y,pmin.z);
103             glNormal3f(0,0,-1); glVertex3f(pmax.x,pmin.y,pmin.z);
104 
105             glNormal3f(0,-1,0); glVertex3f(pmin.x,pmin.y,pmin.z);
106             glNormal3f(0,-1,0); glVertex3f(pmax.x,pmin.y,pmin.z);
107             glNormal3f(0,-1,0); glVertex3f(pmax.x,pmin.y,pmax.z);
108             glNormal3f(0,-1,0); glVertex3f(pmin.x,pmin.y,pmax.z);
109 
110             glNormal3f(-1,0,0); glVertex3f(pmin.x,pmin.y,pmin.z);
111             glNormal3f(-1,0,0); glVertex3f(pmin.x,pmin.y,pmax.z);
112             glNormal3f(-1,0,0); glVertex3f(pmin.x,pmax.y,pmax.z);
113             glNormal3f(-1,0,0); glVertex3f(pmin.x,pmax.y,pmin.z);
114 
115         glEnd();
116 
117         glEndList();
118     }
119 
120     override void draw(double dt)
121     {
122         glCallList(displayList);
123     }
124 
125     void free()
126     {
127         Delete(this);
128     }
129 
130     ~this()
131     {
132         glDeleteLists(displayList, 1);
133     }
134 }
135 
136 class ShapeCylinder: Drawable
137 {
138     GLUquadricObj* quadric;
139     // TODO: slices, stacks
140     uint displayList;
141 
142     this(float h, float r)
143     {
144         quadric = gluNewQuadric();
145         gluQuadricNormals(quadric, GLU_SMOOTH);
146         gluQuadricTexture(quadric, GL_TRUE);
147 
148         displayList = glGenLists(1);
149         glNewList(displayList, GL_COMPILE);
150         glTranslatef(0.0f, h * 0.5f, 0.0f);
151         glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
152         gluCylinder(quadric, r, r, h, 16, 2);
153         gluQuadricOrientation(quadric, GLU_INSIDE);
154         gluDisk(quadric, 0, r, 16, 1);
155         gluQuadricOrientation(quadric, GLU_OUTSIDE);
156         glTranslatef(0.0f, 0.0f, h);
157         gluDisk(quadric, 0, r, 16, 1);
158         glEndList();
159 
160         // TODO: delete quadric
161     }
162 
163     override void draw(double dt)
164     {
165         glCallList(displayList);
166     }
167 
168     void free()
169     {
170         Delete(this);
171     }
172 
173     ~this()
174     {
175         glDeleteLists(displayList, 1);
176     }
177 }
178 
179 class ShapeCone: Drawable
180 {
181     GLUquadricObj* quadric;
182     // TODO: slices, stacks
183     uint displayList;
184 
185     this(float h, float r)
186     {
187         quadric = gluNewQuadric();
188         gluQuadricNormals(quadric, GLU_SMOOTH);
189         gluQuadricTexture(quadric, GL_TRUE);
190 
191         displayList = glGenLists(1);
192         glNewList(displayList, GL_COMPILE);
193         glTranslatef(0.0f, 0.0f, -h * 0.5f);
194         gluCylinder(quadric, r, 0.0f, h, 16, 2);
195         gluQuadricOrientation(quadric, GLU_INSIDE);
196         gluDisk(quadric, 0, r, 16, 1);
197         glEndList();
198 
199         // TODO: delete quadric
200     }
201 
202     override void draw(double dt)
203     {
204         glCallList(displayList);
205     }
206 
207     void free()
208     {
209         Delete(this);
210     }
211 
212     ~this()
213     {
214         glDeleteLists(displayList, 1);
215     }
216 }
217 
218 class ShapeEllipsoid: Drawable
219 {
220     GLUquadricObj* quadric;
221     uint displayList;
222 
223     Vector3f radii;
224 
225     this(Vector3f r)
226     {
227         radii = r;
228 
229         quadric = gluNewQuadric();
230         gluQuadricNormals(quadric, GLU_SMOOTH);
231         gluQuadricTexture(quadric, GL_TRUE);
232 
233         displayList = glGenLists(1);
234         glNewList(displayList, GL_COMPILE);
235         gluSphere(quadric, 1.0f, 24, 16);
236         glEndList();
237 
238         // TODO: delete quadric
239     }
240 
241     override void draw(double dt)
242     {
243         glPushMatrix();
244         glScalef(radii.x, radii.y, radii.z);
245         glCallList(displayList);
246         glPopMatrix();
247     }
248 
249     void free()
250     {
251         Delete(this);
252     }
253 
254     ~this()
255     {
256         glDeleteLists(displayList, 1);
257     }
258 }
259 
260 class ShapeTriangle: Drawable
261 {
262     Vector3f[3] v;
263     uint displayList;
264 
265     this(Vector3f a, Vector3f b, Vector3f c)
266     {
267         v[0] = a;
268         v[1] = b;
269         v[2] = c;
270 
271         displayList = glGenLists(1);
272         glNewList(displayList, GL_COMPILE);
273         glBegin(GL_TRIANGLES);
274         glVertex3fv(v[0].arrayof.ptr);
275         glVertex3fv(v[1].arrayof.ptr);
276         glVertex3fv(v[2].arrayof.ptr);
277         glEnd();
278         glEndList();
279     }
280 
281     override void draw(double dt)
282     {
283         glPushMatrix();
284         glDisable(GL_LIGHTING);
285         glDisable(GL_CULL_FACE);
286         glCallList(displayList);
287         glEnable(GL_CULL_FACE);
288         glEnable(GL_LIGHTING);
289         glPopMatrix();
290     }
291 
292     void free()
293     {
294         Delete(this);
295     }
296 
297     ~this()
298     {
299         glDeleteLists(displayList, 1);
300     }
301 }