xref: /haiku/src/apps/glteapot/GLObject.cpp (revision 552bd60c4bbb4ffb20de6b638d51875ca6e9ff28)
1c8c44fa0SJérôme Duval /*
2*552bd60cSAlexandre Deckner  * Copyright 2008 Haiku Inc. All rights reserved.
3*552bd60cSAlexandre Deckner  * Distributed under the terms of the MIT License.
4*552bd60cSAlexandre Deckner  *
5*552bd60cSAlexandre Deckner  * Authors:
6*552bd60cSAlexandre Deckner  *		Alexandre Deckner
7*552bd60cSAlexandre Deckner  *
8*552bd60cSAlexandre Deckner  */
9*552bd60cSAlexandre Deckner 
10*552bd60cSAlexandre Deckner /*
11*552bd60cSAlexandre Deckner  * Original Be Sample source modified to use a quaternion for the object's orientation
12*552bd60cSAlexandre Deckner  */
13*552bd60cSAlexandre Deckner 
14*552bd60cSAlexandre Deckner /*
15c8c44fa0SJérôme Duval 	Copyright 1999, Be Incorporated.   All Rights Reserved.
16c8c44fa0SJérôme Duval 	This file may be used under the terms of the Be Sample Code License.
17c8c44fa0SJérôme Duval */
18c8c44fa0SJérôme Duval 
19c8c44fa0SJérôme Duval #include "GLObject.h"
20be98a602SStefano Ceccherini #include <GL/gl.h>
21be98a602SStefano Ceccherini #include <stdlib.h>
22be98a602SStefano Ceccherini #include <InterfaceKit.h>
23c8c44fa0SJérôme Duval #include "glob.h"
24c8c44fa0SJérôme Duval 
25c8c44fa0SJérôme Duval struct material {
26c8c44fa0SJérôme Duval 	float ambient[3], diffuse[3], specular[3];
27c8c44fa0SJérôme Duval };
28c8c44fa0SJérôme Duval 
29be98a602SStefano Ceccherini float *colors[] = {NULL, white, yellow, blue, red, green};
30c8c44fa0SJérôme Duval 
31c8c44fa0SJérôme Duval material materials[] = {
32c8c44fa0SJérôme Duval 	// Null
33c8c44fa0SJérôme Duval 	{
34c8c44fa0SJérôme Duval 		{0.1745, 0.03175, 0.03175},
35c8c44fa0SJérôme Duval 		{0.61424, 0.10136, 0.10136},
36c8c44fa0SJérôme Duval 		{0.727811, 0.626959, 0.626959}
37c8c44fa0SJérôme Duval 	},
38c8c44fa0SJérôme Duval 	// White
39c8c44fa0SJérôme Duval 	{
40c8c44fa0SJérôme Duval 		{0.1745, 0.1745, 0.1745},
41c8c44fa0SJérôme Duval 		{0.61424, 0.61424, 0.61424},
42c8c44fa0SJérôme Duval 		{0.727811, 0.727811, 0.727811}
43c8c44fa0SJérôme Duval 	},
44c8c44fa0SJérôme Duval 	// Yellow
45c8c44fa0SJérôme Duval 	{
46c8c44fa0SJérôme Duval 		{0.1745, 0.1745, 0.03175},
47c8c44fa0SJérôme Duval 		{0.61424, 0.61424, 0.10136},
48c8c44fa0SJérôme Duval 		{0.727811, 0.727811, 0.626959}
49c8c44fa0SJérôme Duval 	},
50c8c44fa0SJérôme Duval 	// Blue
51c8c44fa0SJérôme Duval 	{
52c8c44fa0SJérôme Duval 		{0.03175, 0.03175, 0.1745},
53c8c44fa0SJérôme Duval 		{0.10136, 0.10136, 0.61424},
54c8c44fa0SJérôme Duval 		{0.626959, 0.626959, 0.727811}
55c8c44fa0SJérôme Duval 	},
56c8c44fa0SJérôme Duval 	// Red
57c8c44fa0SJérôme Duval 	{
58c8c44fa0SJérôme Duval 		{0.1745, 0.03175, 0.03175},
59c8c44fa0SJérôme Duval 		{0.61424, 0.10136, 0.10136},
60c8c44fa0SJérôme Duval 		{0.727811, 0.626959, 0.626959}
61c8c44fa0SJérôme Duval 	},
62c8c44fa0SJérôme Duval 	// Green
63c8c44fa0SJérôme Duval 	{
64c8c44fa0SJérôme Duval 		{0.03175, 0.1745, 0.03175},
65c8c44fa0SJérôme Duval 		{0.10136, 0.61424, 0.10136},
66c8c44fa0SJérôme Duval 		{0.626959, 0.727811, 0.626959}
67c8c44fa0SJérôme Duval 	},
68c8c44fa0SJérôme Duval };
69c8c44fa0SJérôme Duval 
70c8c44fa0SJérôme Duval #define USE_QUAD_STRIPS 1
71c8c44fa0SJérôme Duval 
72c8c44fa0SJérôme Duval extern long setEvent(sem_id event);
73c8c44fa0SJérôme Duval 
74be98a602SStefano Ceccherini 
75c8c44fa0SJérôme Duval GLObject::GLObject(ObjectView* ov)
7663355585SIngo Weinhold 	:
77be98a602SStefano Ceccherini 	x(0),
78be98a602SStefano Ceccherini 	y(0),
79be98a602SStefano Ceccherini 	z(-2.0),
80*552bd60cSAlexandre Deckner 	fRotation(0.0f, 0.0f, 0.0f, 1.0f),
81*552bd60cSAlexandre Deckner 	spinX(2),
82*552bd60cSAlexandre Deckner 	spinY(2),
83be98a602SStefano Ceccherini 	solidity(0),
84450bb3e5SStephan Aßmus 	color(4),
85be98a602SStefano Ceccherini 	changed(false),
86450bb3e5SStephan Aßmus 	fObjView(ov)
87c8c44fa0SJérôme Duval {
88450bb3e5SStephan Aßmus }
89c8c44fa0SJérôme Duval 
90be98a602SStefano Ceccherini 
91c8c44fa0SJérôme Duval GLObject::~GLObject()
92c8c44fa0SJérôme Duval {
93450bb3e5SStephan Aßmus }
94c8c44fa0SJérôme Duval 
95be98a602SStefano Ceccherini 
96be98a602SStefano Ceccherini void
97be98a602SStefano Ceccherini GLObject::MenuInvoked(BPoint point)
98c8c44fa0SJérôme Duval {
99c8c44fa0SJérôme Duval 	BPopUpMenu* m = new BPopUpMenu("Object",false,false);
100c8c44fa0SJérôme Duval 	BMenuItem* i;
101c8c44fa0SJérôme Duval 
102c8c44fa0SJérôme Duval 	int c = 1;
103c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("White",NULL));
104c8c44fa0SJérôme Duval 	if (color == c++)
105c8c44fa0SJérôme Duval 		i->SetMarked(true);
106c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Yellow",NULL));
107c8c44fa0SJérôme Duval 	if (color == c++)
108c8c44fa0SJérôme Duval 		i->SetMarked(true);
109c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Blue",NULL));
110c8c44fa0SJérôme Duval 	if (color == c++)
111c8c44fa0SJérôme Duval 		i->SetMarked(true);
112c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Red",NULL));
113c8c44fa0SJérôme Duval 	if (color == c++)
114c8c44fa0SJérôme Duval 		i->SetMarked(true);
115c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Green",NULL));
116c8c44fa0SJérôme Duval 	if (color == c++)
117c8c44fa0SJérôme Duval 		i->SetMarked(true);
118c8c44fa0SJérôme Duval 	m->AddSeparatorItem();
119c8c44fa0SJérôme Duval 
120c8c44fa0SJérôme Duval 	c = 0;
121c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Solid",NULL));
122c8c44fa0SJérôme Duval 	if (solidity == c++)
123c8c44fa0SJérôme Duval 		i->SetMarked(true);
124c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Translucent",NULL));
125c8c44fa0SJérôme Duval 	if (solidity == c++)
126c8c44fa0SJérôme Duval 		i->SetMarked(true);
127c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Transparent",NULL));
128c8c44fa0SJérôme Duval 	if (solidity == c++)
129c8c44fa0SJérôme Duval 		i->SetMarked(true);
130c8c44fa0SJérôme Duval 
131c8c44fa0SJérôme Duval 	i = m->Go(point);
132c8c44fa0SJérôme Duval 	int32 index = m->IndexOf(i);
133c8c44fa0SJérôme Duval 	delete m;
134c8c44fa0SJérôme Duval 
135c8c44fa0SJérôme Duval 	if (index < 5) {
136c8c44fa0SJérôme Duval 		color = index+1;
137c8c44fa0SJérôme Duval 	} else if (index > 5) {
138c8c44fa0SJérôme Duval 		solidity = index-6;
139450bb3e5SStephan Aßmus 	}
140c8c44fa0SJérôme Duval 	changed = true;
141450bb3e5SStephan Aßmus 	setEvent(fObjView->drawEvent);
142450bb3e5SStephan Aßmus }
143c8c44fa0SJérôme Duval 
144*552bd60cSAlexandre Deckner int
145*552bd60cSAlexandre Deckner GLObject::Solidity() const
146*552bd60cSAlexandre Deckner {
147*552bd60cSAlexandre Deckner 	return solidity;
148*552bd60cSAlexandre Deckner }
149*552bd60cSAlexandre Deckner 
150be98a602SStefano Ceccherini 
151be98a602SStefano Ceccherini bool
152be98a602SStefano Ceccherini GLObject::SpinIt()
153c8c44fa0SJérôme Duval {
154c8c44fa0SJérôme Duval 	bool c = changed;
155*552bd60cSAlexandre Deckner 	c = c || ((spinX != 0.0f) || (spinY != 0.0f));
156*552bd60cSAlexandre Deckner 
157*552bd60cSAlexandre Deckner 	if (c)
158*552bd60cSAlexandre Deckner 		RotateWorldSpace(spinY, spinX);
159c8c44fa0SJérôme Duval 
160c8c44fa0SJérôme Duval 	return c;
161450bb3e5SStephan Aßmus }
162c8c44fa0SJérôme Duval 
163be98a602SStefano Ceccherini 
164be98a602SStefano Ceccherini void
165*552bd60cSAlexandre Deckner GLObject::Spin(float rx, float ry)
166*552bd60cSAlexandre Deckner {
167*552bd60cSAlexandre Deckner 	spinX = rx;
168*552bd60cSAlexandre Deckner 	spinY = ry;
169*552bd60cSAlexandre Deckner }
170*552bd60cSAlexandre Deckner 
171*552bd60cSAlexandre Deckner 
172*552bd60cSAlexandre Deckner void
173*552bd60cSAlexandre Deckner GLObject::RotateWorldSpace(float rx, float ry)
174*552bd60cSAlexandre Deckner {
175*552bd60cSAlexandre Deckner 	fRotation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 0.01f * rx) * fRotation;
176*552bd60cSAlexandre Deckner 	fRotation = Quaternion(Vector3(1.0f, 0.0f, 0.0f), 0.01f * ry) * fRotation;
177*552bd60cSAlexandre Deckner 	changed = true;
178*552bd60cSAlexandre Deckner }
179*552bd60cSAlexandre Deckner 
180*552bd60cSAlexandre Deckner 
181*552bd60cSAlexandre Deckner void
182be98a602SStefano Ceccherini GLObject::Draw(bool forID, float IDcolor[])
183c8c44fa0SJérôme Duval {
184c8c44fa0SJérôme Duval 	glPushMatrix();
185c8c44fa0SJérôme Duval 		glTranslatef(x, y, z);
186*552bd60cSAlexandre Deckner 
187*552bd60cSAlexandre Deckner 		float mat[4][4];
188*552bd60cSAlexandre Deckner 		fRotation.toOpenGLMatrix(mat);
189*552bd60cSAlexandre Deckner 		glMultMatrixf((GLfloat*)mat);
190c8c44fa0SJérôme Duval 
191c8c44fa0SJérôme Duval 		if (forID) {
192c8c44fa0SJérôme Duval 			glColor3fv(IDcolor);
193450bb3e5SStephan Aßmus 		}
194c8c44fa0SJérôme Duval 
195c8c44fa0SJérôme Duval 		DoDrawing(forID);
196c8c44fa0SJérôme Duval 
197c8c44fa0SJérôme Duval 	glPopMatrix();
198c8c44fa0SJérôme Duval 
199c8c44fa0SJérôme Duval 	changed = false;
200450bb3e5SStephan Aßmus }
201c8c44fa0SJérôme Duval 
202be98a602SStefano Ceccherini 
203c8c44fa0SJérôme Duval TriangleObject::TriangleObject(ObjectView* ov, char* filename)
204c8c44fa0SJérôme Duval 	: 	GLObject(ov),
205450bb3e5SStephan Aßmus 		fPoints(100,100),
206450bb3e5SStephan Aßmus 		fTriangles(100,100),
207450bb3e5SStephan Aßmus 		fQs(50,50)
208c8c44fa0SJérôme Duval {
209c8c44fa0SJérôme Duval 	float maxp = 0;
210c8c44fa0SJérôme Duval 	int numPt,numTri;
211c8c44fa0SJérôme Duval 
212c8c44fa0SJérôme Duval 	FILE* f = fopen(filename,"r");
213c8c44fa0SJérôme Duval 	fscanf(f,"%d",&numPt);
214c8c44fa0SJérôme Duval //	printf("Points: %d\n",numPt);
215c8c44fa0SJérôme Duval 	for (int i = 0; i < numPt; i++) {
216c8c44fa0SJérôme Duval 		point p;
217c8c44fa0SJérôme Duval 		fscanf(f,"%f %f %f %f %f %f",
218c8c44fa0SJérôme Duval 			&p.x,
219c8c44fa0SJérôme Duval 			&p.y,
220c8c44fa0SJérôme Duval 			&p.z,
221c8c44fa0SJérôme Duval 			&p.nx,
222c8c44fa0SJérôme Duval 			&p.ny,
223c8c44fa0SJérôme Duval 			&p.nz);
224c8c44fa0SJérôme Duval 		if (fabs(p.x) > maxp)
225c8c44fa0SJérôme Duval 			maxp = fabs(p.x);
226c8c44fa0SJérôme Duval 		if (fabs(p.y) > maxp)
227c8c44fa0SJérôme Duval 			maxp = fabs(p.y);
228c8c44fa0SJérôme Duval 		if (fabs(p.z) > maxp)
229c8c44fa0SJérôme Duval 			maxp = fabs(p.z);
230450bb3e5SStephan Aßmus 		fPoints.add(p);
231450bb3e5SStephan Aßmus 	}
232450bb3e5SStephan Aßmus 
233450bb3e5SStephan Aßmus 	for (int i = 0; i < fPoints.num_items; i++) {
234450bb3e5SStephan Aßmus 		fPoints[i].x /= maxp;
235450bb3e5SStephan Aßmus 		fPoints[i].y /= maxp;
236450bb3e5SStephan Aßmus 		fPoints[i].z /= maxp;
237450bb3e5SStephan Aßmus 	}
238c8c44fa0SJérôme Duval 
239c8c44fa0SJérôme Duval 	fscanf(f,"%d",&numTri);
240c8c44fa0SJérôme Duval //	printf("Triangles: %d\n",numTri);
241c8c44fa0SJérôme Duval 	int tpts = 0;
242c8c44fa0SJérôme Duval 	for (int i = 0; i < numTri; i++) {
243c8c44fa0SJérôme Duval 		tri t;
244c8c44fa0SJérôme Duval 		fscanf(f,"%d %d %d",
245c8c44fa0SJérôme Duval 			&t.p1,
246c8c44fa0SJérôme Duval 			&t.p2,
247c8c44fa0SJérôme Duval 			&t.p3);
248450bb3e5SStephan Aßmus 		fTriangles.add(t);
249c8c44fa0SJérôme Duval 		tpts += 3;
250450bb3e5SStephan Aßmus 	}
251c8c44fa0SJérôme Duval 
252c8c44fa0SJérôme Duval 	int qpts = 4;
253c8c44fa0SJérôme Duval 	int qp[1024];
254c8c44fa0SJérôme Duval 	quadStrip q;
255c8c44fa0SJérôme Duval 	q.pts = qp;
256c8c44fa0SJérôme Duval 	q.numpts = 4;
257450bb3e5SStephan Aßmus 	q.pts[2] = fTriangles[0].p1;
258450bb3e5SStephan Aßmus 	q.pts[0] = fTriangles[0].p2;
259450bb3e5SStephan Aßmus 	q.pts[1] = fTriangles[0].p3;
260450bb3e5SStephan Aßmus 	q.pts[3] = fTriangles[1].p3;
261c8c44fa0SJérôme Duval 
262c8c44fa0SJérôme Duval 	for (int i = 2; i < numTri; i += 2) {
263450bb3e5SStephan Aßmus 		if ((fTriangles[i-1].p1 == fTriangles[i].p2) &&
264450bb3e5SStephan Aßmus 			(fTriangles[i-1].p3 == fTriangles[i].p3)) {
265450bb3e5SStephan Aßmus 			q.pts[q.numpts++] = fTriangles[i+1].p1;
266450bb3e5SStephan Aßmus 			q.pts[q.numpts++] = fTriangles[i+1].p3;
267c8c44fa0SJérôme Duval 			qpts+=2;
268c8c44fa0SJérôme Duval 		} else {
269c8c44fa0SJérôme Duval 			int *np = (int*)malloc(sizeof(int)*q.numpts);
270c8c44fa0SJérôme Duval 			memcpy(np,qp,q.numpts*sizeof(int));
271c8c44fa0SJérôme Duval 			quadStrip nqs;
272c8c44fa0SJérôme Duval 			nqs.numpts = q.numpts;
273c8c44fa0SJérôme Duval 			nqs.pts = np;
274450bb3e5SStephan Aßmus 			fQs.add(nqs);
275c8c44fa0SJérôme Duval 
276c8c44fa0SJérôme Duval 			qpts += 4;
277c8c44fa0SJérôme Duval 			q.numpts = 4;
278450bb3e5SStephan Aßmus 			q.pts[2] = fTriangles[i].p1;
279450bb3e5SStephan Aßmus 			q.pts[0] = fTriangles[i].p2;
280450bb3e5SStephan Aßmus 			q.pts[1] = fTriangles[i].p3;
281450bb3e5SStephan Aßmus 			q.pts[3] = fTriangles[i+1].p3;
282450bb3e5SStephan Aßmus 		}
283450bb3e5SStephan Aßmus 	}
284c8c44fa0SJérôme Duval 
285c8c44fa0SJérôme Duval 	int* np = (int*)malloc(sizeof(int)*q.numpts);
286c8c44fa0SJérôme Duval 	memcpy(np,qp,q.numpts*sizeof(int));
287c8c44fa0SJérôme Duval 	quadStrip nqs;
288c8c44fa0SJérôme Duval 	nqs.numpts = q.numpts;
289c8c44fa0SJérôme Duval 	nqs.pts = np;
290450bb3e5SStephan Aßmus 	fQs.add(nqs);
291c8c44fa0SJérôme Duval 
292c8c44fa0SJérôme Duval 	fclose(f);
293450bb3e5SStephan Aßmus }
294c8c44fa0SJérôme Duval 
295be98a602SStefano Ceccherini 
296c8c44fa0SJérôme Duval TriangleObject::~TriangleObject()
297c8c44fa0SJérôme Duval {
298450bb3e5SStephan Aßmus 	for (int i = 0; i < fQs.num_items; i++) {
299450bb3e5SStephan Aßmus 		free(fQs[i].pts);
300450bb3e5SStephan Aßmus 	}
301450bb3e5SStephan Aßmus }
302c8c44fa0SJérôme Duval 
303be98a602SStefano Ceccherini 
304be98a602SStefano Ceccherini void
305be98a602SStefano Ceccherini TriangleObject::DoDrawing(bool forID)
306c8c44fa0SJérôme Duval {
307c8c44fa0SJérôme Duval 	if (!forID) {
308c8c44fa0SJérôme Duval 		float c[3][4];
309c8c44fa0SJérôme Duval 		c[0][0] = materials[color].ambient[0];
310c8c44fa0SJérôme Duval 		c[0][1] = materials[color].ambient[1];
311c8c44fa0SJérôme Duval 		c[0][2] = materials[color].ambient[2];
312c8c44fa0SJérôme Duval 		c[1][0] = materials[color].diffuse[0];
313c8c44fa0SJérôme Duval 		c[1][1] = materials[color].diffuse[1];
314c8c44fa0SJérôme Duval 		c[1][2] = materials[color].diffuse[2];
315c8c44fa0SJérôme Duval 		c[2][0] = materials[color].specular[0];
316c8c44fa0SJérôme Duval 		c[2][1] = materials[color].specular[1];
317c8c44fa0SJérôme Duval 		c[2][2] = materials[color].specular[2];
318c8c44fa0SJérôme Duval 
319c8c44fa0SJérôme Duval 		float alpha = 1;
320c8c44fa0SJérôme Duval 		if (solidity == 0)
321c8c44fa0SJérôme Duval 			alpha = 1.0;
322c8c44fa0SJérôme Duval 		else if (solidity == 1)
323c8c44fa0SJérôme Duval 			alpha = 0.95;
324c8c44fa0SJérôme Duval 		else if (solidity == 2)
325c8c44fa0SJérôme Duval 			alpha = 0.6;
326c8c44fa0SJérôme Duval 		c[0][3] = c[1][3] = c[2][3] = alpha;
327c8c44fa0SJérôme Duval 		if (solidity != 0) {
328c8c44fa0SJérôme Duval 			glBlendFunc(GL_SRC_ALPHA,GL_ONE);
329c8c44fa0SJérôme Duval 			glEnable(GL_BLEND);
330c8c44fa0SJérôme Duval 			glDepthMask(GL_FALSE);
331c8c44fa0SJérôme Duval 			glDisable(GL_CULL_FACE);
332c8c44fa0SJérôme Duval 		} else {
333c8c44fa0SJérôme Duval 			glDisable(GL_BLEND);
334c8c44fa0SJérôme Duval 			glDepthMask(GL_TRUE);
335450bb3e5SStephan Aßmus 		}
336c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_AMBIENT, c[0]);
337c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_DIFFUSE, c[1]);
338c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_SPECULAR, c[2]);
339c8c44fa0SJérôme Duval 	} else {
340c8c44fa0SJérôme Duval 		glDisable(GL_BLEND);
341c8c44fa0SJérôme Duval 		glDepthMask(GL_TRUE);
342450bb3e5SStephan Aßmus 	}
343c8c44fa0SJérôme Duval 
344c8c44fa0SJérôme Duval #if USE_QUAD_STRIPS
345450bb3e5SStephan Aßmus 		for (int i = 0; i < fQs.num_items; i++) {
346c8c44fa0SJérôme Duval  			glBegin(GL_QUAD_STRIP);
347450bb3e5SStephan Aßmus 			for (int j = 0; j < fQs[i].numpts; j++) {
348c8c44fa0SJérôme Duval  				glNormal3f(
349450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].nx,
350450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].ny,
351450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].nz
352c8c44fa0SJérôme Duval 				);
353c8c44fa0SJérôme Duval  				glVertex3f(
354450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].x,
355450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].y,
356450bb3e5SStephan Aßmus 					fPoints[fQs[i].pts[j]].z
357c8c44fa0SJérôme Duval 				);
358450bb3e5SStephan Aßmus 			}
359c8c44fa0SJérôme Duval 			glEnd();
360450bb3e5SStephan Aßmus 		}
361c8c44fa0SJérôme Duval #else
362c8c44fa0SJérôme Duval  		glBegin(GL_TRIANGLES);
363450bb3e5SStephan Aßmus 		for (int i = 0; i < fTriangles.num_items; i++) {
364450bb3e5SStephan Aßmus 			int v3 = fTriangles[i].p1;
365450bb3e5SStephan Aßmus 			int v1 = fTriangles[i].p2;
366450bb3e5SStephan Aßmus 			int v2 = fTriangles[i].p3;
367c8c44fa0SJérôme Duval  	  		glNormal3f(
368450bb3e5SStephan Aßmus 				fPoints[v1].nx,
369450bb3e5SStephan Aßmus 				fPoints[v1].ny,
370450bb3e5SStephan Aßmus 				fPoints[v1].nz
371c8c44fa0SJérôme Duval 			);
372c8c44fa0SJérôme Duval  			glVertex3f(
373450bb3e5SStephan Aßmus 				fPoints[v1].x,
374450bb3e5SStephan Aßmus 				fPoints[v1].y,
375450bb3e5SStephan Aßmus 				fPoints[v1].z
376c8c44fa0SJérôme Duval 			);
377c8c44fa0SJérôme Duval  			glNormal3f(
378450bb3e5SStephan Aßmus 				fPoints[v2].nx,
379450bb3e5SStephan Aßmus 				fPoints[v2].ny,
380450bb3e5SStephan Aßmus 				fPoints[v2].nz
381c8c44fa0SJérôme Duval 			);
382c8c44fa0SJérôme Duval  			glVertex3f(
383450bb3e5SStephan Aßmus 				fPoints[v2].x,
384450bb3e5SStephan Aßmus 				fPoints[v2].y,
385450bb3e5SStephan Aßmus 				fPoints[v2].z
386c8c44fa0SJérôme Duval 			);
387c8c44fa0SJérôme Duval  			glNormal3f(
388450bb3e5SStephan Aßmus 				fPoints[v3].nx,
389450bb3e5SStephan Aßmus 				fPoints[v3].ny,
390450bb3e5SStephan Aßmus 				fPoints[v3].nz
391c8c44fa0SJérôme Duval 			);
392c8c44fa0SJérôme Duval 			glVertex3f(
393450bb3e5SStephan Aßmus 				fPoints[v3].x,
394450bb3e5SStephan Aßmus 				fPoints[v3].y,
395450bb3e5SStephan Aßmus 				fPoints[v3].z
396c8c44fa0SJérôme Duval 			);
397450bb3e5SStephan Aßmus 		}
398c8c44fa0SJérôme Duval 		glEnd();
399c8c44fa0SJérôme Duval  #endif
400450bb3e5SStephan Aßmus }
401c8c44fa0SJérôme Duval 
402