xref: /haiku/src/apps/glteapot/GLObject.cpp (revision be98a6028dd663b62c489fe10a7a1e8be2c32888)
1c8c44fa0SJérôme Duval /*
2c8c44fa0SJérôme Duval 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3c8c44fa0SJérôme Duval 	This file may be used under the terms of the Be Sample Code License.
4c8c44fa0SJérôme Duval */
5c8c44fa0SJérôme Duval 
6c8c44fa0SJérôme Duval #include "GLObject.h"
7*be98a602SStefano Ceccherini #include <GL/gl.h>
8*be98a602SStefano Ceccherini #include <stdlib.h>
9*be98a602SStefano Ceccherini #include <InterfaceKit.h>
10c8c44fa0SJérôme Duval #include "glob.h"
11c8c44fa0SJérôme Duval 
12c8c44fa0SJérôme Duval struct material {
13c8c44fa0SJérôme Duval 	float ambient[3], diffuse[3], specular[3];
14c8c44fa0SJérôme Duval };
15c8c44fa0SJérôme Duval 
16*be98a602SStefano Ceccherini float *colors[] = {NULL, white, yellow, blue, red, green};
17c8c44fa0SJérôme Duval 
18c8c44fa0SJérôme Duval material materials[] = {
19c8c44fa0SJérôme Duval 	// Null
20c8c44fa0SJérôme Duval 	{
21c8c44fa0SJérôme Duval 		{0.1745, 0.03175, 0.03175},
22c8c44fa0SJérôme Duval 		{0.61424, 0.10136, 0.10136},
23c8c44fa0SJérôme Duval 		{0.727811, 0.626959, 0.626959}
24c8c44fa0SJérôme Duval 	},
25c8c44fa0SJérôme Duval 	// White
26c8c44fa0SJérôme Duval 	{
27c8c44fa0SJérôme Duval 		{0.1745, 0.1745, 0.1745},
28c8c44fa0SJérôme Duval 		{0.61424, 0.61424, 0.61424},
29c8c44fa0SJérôme Duval 		{0.727811, 0.727811, 0.727811}
30c8c44fa0SJérôme Duval 	},
31c8c44fa0SJérôme Duval 	// Yellow
32c8c44fa0SJérôme Duval 	{
33c8c44fa0SJérôme Duval 		{0.1745, 0.1745, 0.03175},
34c8c44fa0SJérôme Duval 		{0.61424, 0.61424, 0.10136},
35c8c44fa0SJérôme Duval 		{0.727811, 0.727811, 0.626959}
36c8c44fa0SJérôme Duval 	},
37c8c44fa0SJérôme Duval 	// Blue
38c8c44fa0SJérôme Duval 	{
39c8c44fa0SJérôme Duval 		{0.03175, 0.03175, 0.1745},
40c8c44fa0SJérôme Duval 		{0.10136, 0.10136, 0.61424},
41c8c44fa0SJérôme Duval 		{0.626959, 0.626959, 0.727811}
42c8c44fa0SJérôme Duval 	},
43c8c44fa0SJérôme Duval 	// Red
44c8c44fa0SJérôme Duval 	{
45c8c44fa0SJérôme Duval 		{0.1745, 0.03175, 0.03175},
46c8c44fa0SJérôme Duval 		{0.61424, 0.10136, 0.10136},
47c8c44fa0SJérôme Duval 		{0.727811, 0.626959, 0.626959}
48c8c44fa0SJérôme Duval 	},
49c8c44fa0SJérôme Duval 	// Green
50c8c44fa0SJérôme Duval 	{
51c8c44fa0SJérôme Duval 		{0.03175, 0.1745, 0.03175},
52c8c44fa0SJérôme Duval 		{0.10136, 0.61424, 0.10136},
53c8c44fa0SJérôme Duval 		{0.626959, 0.727811, 0.626959}
54c8c44fa0SJérôme Duval 	},
55c8c44fa0SJérôme Duval };
56c8c44fa0SJérôme Duval 
57c8c44fa0SJérôme Duval #define USE_QUAD_STRIPS 1
58c8c44fa0SJérôme Duval 
59c8c44fa0SJérôme Duval extern long setEvent(sem_id event);
60c8c44fa0SJérôme Duval 
61*be98a602SStefano Ceccherini 
62c8c44fa0SJérôme Duval GLObject::GLObject(ObjectView *ov)
63*be98a602SStefano Ceccherini 	: rotX(0),
64*be98a602SStefano Ceccherini 	rotY(0),
65*be98a602SStefano Ceccherini 	lastRotX(0),
66*be98a602SStefano Ceccherini 	lastRotY(0),
67*be98a602SStefano Ceccherini 	spinX(2),
68*be98a602SStefano Ceccherini 	spinY(2),
69*be98a602SStefano Ceccherini 	x(0),
70*be98a602SStefano Ceccherini 	y(0),
71*be98a602SStefano Ceccherini 	z(-2.0),
72*be98a602SStefano Ceccherini 	color(4),
73*be98a602SStefano Ceccherini 	solidity(0),
74*be98a602SStefano Ceccherini 	changed(false),
75*be98a602SStefano Ceccherini 	objView(ov)
76c8c44fa0SJérôme Duval {
77c8c44fa0SJérôme Duval };
78c8c44fa0SJérôme Duval 
79*be98a602SStefano Ceccherini 
80c8c44fa0SJérôme Duval GLObject::~GLObject()
81c8c44fa0SJérôme Duval {
82c8c44fa0SJérôme Duval };
83c8c44fa0SJérôme Duval 
84*be98a602SStefano Ceccherini 
85*be98a602SStefano Ceccherini void
86*be98a602SStefano Ceccherini GLObject::MenuInvoked(BPoint point)
87c8c44fa0SJérôme Duval {
88c8c44fa0SJérôme Duval 	BPopUpMenu *m = new BPopUpMenu("Object",false,false);
89c8c44fa0SJérôme Duval 	BMenuItem *i;
90c8c44fa0SJérôme Duval 
91c8c44fa0SJérôme Duval 	int c = 1;
92c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("White",NULL));
93c8c44fa0SJérôme Duval 	if (color == c++)
94c8c44fa0SJérôme Duval 		i->SetMarked(true);
95c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Yellow",NULL));
96c8c44fa0SJérôme Duval 	if (color == c++)
97c8c44fa0SJérôme Duval 		i->SetMarked(true);
98c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Blue",NULL));
99c8c44fa0SJérôme Duval 	if (color == c++)
100c8c44fa0SJérôme Duval 		i->SetMarked(true);
101c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Red",NULL));
102c8c44fa0SJérôme Duval 	if (color == c++)
103c8c44fa0SJérôme Duval 		i->SetMarked(true);
104c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Green",NULL));
105c8c44fa0SJérôme Duval 	if (color == c++)
106c8c44fa0SJérôme Duval 		i->SetMarked(true);
107c8c44fa0SJérôme Duval 	m->AddSeparatorItem();
108c8c44fa0SJérôme Duval 
109c8c44fa0SJérôme Duval 	c = 0;
110c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Solid",NULL));
111c8c44fa0SJérôme Duval 	if (solidity == c++)
112c8c44fa0SJérôme Duval 		i->SetMarked(true);
113c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Translucent",NULL));
114c8c44fa0SJérôme Duval 	if (solidity == c++)
115c8c44fa0SJérôme Duval 		i->SetMarked(true);
116c8c44fa0SJérôme Duval 	m->AddItem(i = new BMenuItem("Transparent",NULL));
117c8c44fa0SJérôme Duval 	if (solidity == c++)
118c8c44fa0SJérôme Duval 		i->SetMarked(true);
119c8c44fa0SJérôme Duval 
120c8c44fa0SJérôme Duval 	i = m->Go(point);
121c8c44fa0SJérôme Duval 	int32 index = m->IndexOf(i);
122c8c44fa0SJérôme Duval 	delete m;
123c8c44fa0SJérôme Duval 
124c8c44fa0SJérôme Duval 	if (index < 5) {
125c8c44fa0SJérôme Duval 		color = index+1;
126c8c44fa0SJérôme Duval 	} else if (index > 5) {
127c8c44fa0SJérôme Duval 		solidity = index-6;
128c8c44fa0SJérôme Duval 	};
129c8c44fa0SJérôme Duval 	changed = true;
130c8c44fa0SJérôme Duval 	setEvent(objView->drawEvent);
131c8c44fa0SJérôme Duval };
132c8c44fa0SJérôme Duval 
133*be98a602SStefano Ceccherini 
134*be98a602SStefano Ceccherini bool
135*be98a602SStefano Ceccherini GLObject::SpinIt()
136c8c44fa0SJérôme Duval {
137c8c44fa0SJérôme Duval 	rotX += spinX;
138c8c44fa0SJérôme Duval 	rotY += spinY;
139c8c44fa0SJérôme Duval 	bool c = changed;
140c8c44fa0SJérôme Duval 	c = c || ((rotX != lastRotX) || (rotY != lastRotY));
141c8c44fa0SJérôme Duval 	lastRotX = rotX;
142c8c44fa0SJérôme Duval 	lastRotY = rotY;
143c8c44fa0SJérôme Duval 
144c8c44fa0SJérôme Duval 	return c;
145c8c44fa0SJérôme Duval };
146c8c44fa0SJérôme Duval 
147*be98a602SStefano Ceccherini 
148*be98a602SStefano Ceccherini void
149*be98a602SStefano Ceccherini GLObject::Draw(bool forID, float IDcolor[])
150c8c44fa0SJérôme Duval {
151c8c44fa0SJérôme Duval 	glPushMatrix();
152c8c44fa0SJérôme Duval 		glTranslatef(x, y, z);
153c8c44fa0SJérôme Duval 		glRotatef(rotY, 0.0,1.0,0.0);
154c8c44fa0SJérôme Duval 		glRotatef(rotX, 1.0,0.0,0.0);
155c8c44fa0SJérôme Duval 
156c8c44fa0SJérôme Duval 		if (forID) {
157c8c44fa0SJérôme Duval 			glColor3fv(IDcolor);
158c8c44fa0SJérôme Duval 		};
159c8c44fa0SJérôme Duval 
160c8c44fa0SJérôme Duval 		DoDrawing(forID);
161c8c44fa0SJérôme Duval 
162c8c44fa0SJérôme Duval 	glPopMatrix();
163c8c44fa0SJérôme Duval 
164c8c44fa0SJérôme Duval 	changed = false;
165c8c44fa0SJérôme Duval };
166c8c44fa0SJérôme Duval 
167*be98a602SStefano Ceccherini 
168c8c44fa0SJérôme Duval TriangleObject::TriangleObject(ObjectView *ov, char *filename)
169c8c44fa0SJérôme Duval 	: 	GLObject(ov),
170c8c44fa0SJérôme Duval 		points(100,100),
171c8c44fa0SJérôme Duval 		triangles(100,100),
172c8c44fa0SJérôme Duval 		qs(50,50)
173c8c44fa0SJérôme Duval {
174c8c44fa0SJérôme Duval 	float maxp=0;
175c8c44fa0SJérôme Duval 	int numPt,numTri;
176c8c44fa0SJérôme Duval 
177c8c44fa0SJérôme Duval 	FILE *f = fopen(filename,"r");
178c8c44fa0SJérôme Duval 	fscanf(f,"%d",&numPt);
179c8c44fa0SJérôme Duval //	printf("Points: %d\n",numPt);
180c8c44fa0SJérôme Duval 	for (int i=0;i<numPt;i++) {
181c8c44fa0SJérôme Duval 		point p;
182c8c44fa0SJérôme Duval 		fscanf(f,"%f %f %f %f %f %f",
183c8c44fa0SJérôme Duval 			&p.x,
184c8c44fa0SJérôme Duval 			&p.y,
185c8c44fa0SJérôme Duval 			&p.z,
186c8c44fa0SJérôme Duval 			&p.nx,
187c8c44fa0SJérôme Duval 			&p.ny,
188c8c44fa0SJérôme Duval 			&p.nz);
189c8c44fa0SJérôme Duval 		if (fabs(p.x) > maxp)
190c8c44fa0SJérôme Duval 			maxp = fabs(p.x);
191c8c44fa0SJérôme Duval 		if (fabs(p.y) > maxp)
192c8c44fa0SJérôme Duval 			maxp = fabs(p.y);
193c8c44fa0SJérôme Duval 		if (fabs(p.z) > maxp)
194c8c44fa0SJérôme Duval 			maxp = fabs(p.z);
195c8c44fa0SJérôme Duval 		points.add(p);
196c8c44fa0SJérôme Duval 	};
197c8c44fa0SJérôme Duval 	for (int i=0;i<points.num_items;i++) {
198c8c44fa0SJérôme Duval 		points[i].x /= maxp;
199c8c44fa0SJérôme Duval 		points[i].y /= maxp;
200c8c44fa0SJérôme Duval 		points[i].z /= maxp;
201c8c44fa0SJérôme Duval 	};
202c8c44fa0SJérôme Duval 
203c8c44fa0SJérôme Duval 	fscanf(f,"%d",&numTri);
204c8c44fa0SJérôme Duval //	printf("Triangles: %d\n",numTri);
205c8c44fa0SJérôme Duval 	int tpts=0;
206c8c44fa0SJérôme Duval 	for (int i=0;i<numTri;i++) {
207c8c44fa0SJérôme Duval 		tri t;
208c8c44fa0SJérôme Duval 		fscanf(f,"%d %d %d",
209c8c44fa0SJérôme Duval 			&t.p1,
210c8c44fa0SJérôme Duval 			&t.p2,
211c8c44fa0SJérôme Duval 			&t.p3);
212c8c44fa0SJérôme Duval 		triangles.add(t);
213c8c44fa0SJérôme Duval 		tpts+=3;
214c8c44fa0SJérôme Duval 	};
215c8c44fa0SJérôme Duval 
216c8c44fa0SJérôme Duval 	int qpts=4;
217c8c44fa0SJérôme Duval 	int qp[1024];
218c8c44fa0SJérôme Duval 	quadStrip q;
219c8c44fa0SJérôme Duval 	q.pts = qp;
220c8c44fa0SJérôme Duval 	q.numpts = 4;
221c8c44fa0SJérôme Duval 	q.pts[2] = triangles[0].p1;
222c8c44fa0SJérôme Duval 	q.pts[0] = triangles[0].p2;
223c8c44fa0SJérôme Duval 	q.pts[1] = triangles[0].p3;
224c8c44fa0SJérôme Duval 	q.pts[3] = triangles[1].p3;
225c8c44fa0SJérôme Duval 
226c8c44fa0SJérôme Duval 	for (int i=2;i<numTri;i+=2) {
227c8c44fa0SJérôme Duval 		if ((triangles[i-1].p1 == triangles[i].p2) &&
228c8c44fa0SJérôme Duval 			(triangles[i-1].p3 == triangles[i].p3)) {
229c8c44fa0SJérôme Duval 			q.pts[q.numpts++] = triangles[i+1].p1;
230c8c44fa0SJérôme Duval 			q.pts[q.numpts++] = triangles[i+1].p3;
231c8c44fa0SJérôme Duval 			qpts+=2;
232c8c44fa0SJérôme Duval 		} else {
233c8c44fa0SJérôme Duval 			int *np = (int*)malloc(sizeof(int)*q.numpts);
234c8c44fa0SJérôme Duval 			memcpy(np,qp,q.numpts*sizeof(int));
235c8c44fa0SJérôme Duval 			quadStrip nqs;
236c8c44fa0SJérôme Duval 			nqs.numpts = q.numpts;
237c8c44fa0SJérôme Duval 			nqs.pts = np;
238c8c44fa0SJérôme Duval 			qs.add(nqs);
239c8c44fa0SJérôme Duval 
240c8c44fa0SJérôme Duval 			qpts+=4;
241c8c44fa0SJérôme Duval 			q.numpts = 4;
242c8c44fa0SJérôme Duval 			q.pts[2] = triangles[i].p1;
243c8c44fa0SJérôme Duval 			q.pts[0] = triangles[i].p2;
244c8c44fa0SJérôme Duval 			q.pts[1] = triangles[i].p3;
245c8c44fa0SJérôme Duval 			q.pts[3] = triangles[i+1].p3;
246c8c44fa0SJérôme Duval 		};
247c8c44fa0SJérôme Duval 	};
248c8c44fa0SJérôme Duval 
249c8c44fa0SJérôme Duval 	int *np = (int*)malloc(sizeof(int)*q.numpts);
250c8c44fa0SJérôme Duval 	memcpy(np,qp,q.numpts*sizeof(int));
251c8c44fa0SJérôme Duval 	quadStrip nqs;
252c8c44fa0SJérôme Duval 	nqs.numpts = q.numpts;
253c8c44fa0SJérôme Duval 	nqs.pts = np;
254c8c44fa0SJérôme Duval 	qs.add(nqs);
255c8c44fa0SJérôme Duval 
256c8c44fa0SJérôme Duval 	fclose(f);
257c8c44fa0SJérôme Duval };
258c8c44fa0SJérôme Duval 
259*be98a602SStefano Ceccherini 
260c8c44fa0SJérôme Duval TriangleObject::~TriangleObject()
261c8c44fa0SJérôme Duval {
262c8c44fa0SJérôme Duval 	for (int i=0;i<qs.num_items;i++) {
263c8c44fa0SJérôme Duval 		free(qs[i].pts);
264c8c44fa0SJérôme Duval 	};
265c8c44fa0SJérôme Duval };
266c8c44fa0SJérôme Duval 
267*be98a602SStefano Ceccherini 
268*be98a602SStefano Ceccherini void
269*be98a602SStefano Ceccherini TriangleObject::DoDrawing(bool forID)
270c8c44fa0SJérôme Duval {
271c8c44fa0SJérôme Duval 	if (!forID) {
272c8c44fa0SJérôme Duval 		float c[3][4];
273c8c44fa0SJérôme Duval 		c[0][0] = materials[color].ambient[0];
274c8c44fa0SJérôme Duval 		c[0][1] = materials[color].ambient[1];
275c8c44fa0SJérôme Duval 		c[0][2] = materials[color].ambient[2];
276c8c44fa0SJérôme Duval 		c[1][0] = materials[color].diffuse[0];
277c8c44fa0SJérôme Duval 		c[1][1] = materials[color].diffuse[1];
278c8c44fa0SJérôme Duval 		c[1][2] = materials[color].diffuse[2];
279c8c44fa0SJérôme Duval 		c[2][0] = materials[color].specular[0];
280c8c44fa0SJérôme Duval 		c[2][1] = materials[color].specular[1];
281c8c44fa0SJérôme Duval 		c[2][2] = materials[color].specular[2];
282c8c44fa0SJérôme Duval 
283c8c44fa0SJérôme Duval 		float alpha = 1;
284c8c44fa0SJérôme Duval 		if (solidity == 0)
285c8c44fa0SJérôme Duval 			alpha = 1.0;
286c8c44fa0SJérôme Duval 		else if (solidity == 1)
287c8c44fa0SJérôme Duval 			alpha = 0.95;
288c8c44fa0SJérôme Duval 		else if (solidity == 2)
289c8c44fa0SJérôme Duval 			alpha = 0.6;
290c8c44fa0SJérôme Duval 		c[0][3] = c[1][3] = c[2][3] = alpha;
291c8c44fa0SJérôme Duval 		if (solidity != 0) {
292c8c44fa0SJérôme Duval 			glBlendFunc(GL_SRC_ALPHA,GL_ONE);
293c8c44fa0SJérôme Duval 			glEnable(GL_BLEND);
294c8c44fa0SJérôme Duval 			glDepthMask(GL_FALSE);
295c8c44fa0SJérôme Duval 			glDisable(GL_CULL_FACE);
296c8c44fa0SJérôme Duval 		} else {
297c8c44fa0SJérôme Duval 			glDisable(GL_BLEND);
298c8c44fa0SJérôme Duval 			glDepthMask(GL_TRUE);
299c8c44fa0SJérôme Duval 		};
300c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_AMBIENT, c[0]);
301c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_DIFFUSE, c[1]);
302c8c44fa0SJérôme Duval 		glMaterialfv(GL_FRONT, GL_SPECULAR, c[2]);
303c8c44fa0SJérôme Duval 	} else {
304c8c44fa0SJérôme Duval 		glDisable(GL_BLEND);
305c8c44fa0SJérôme Duval 		glDepthMask(GL_TRUE);
306c8c44fa0SJérôme Duval 	};
307c8c44fa0SJérôme Duval 
308c8c44fa0SJérôme Duval #if USE_QUAD_STRIPS
309c8c44fa0SJérôme Duval 		for (int i=0;i<qs.num_items;i++) {
310c8c44fa0SJérôme Duval 			glBegin(GL_QUAD_STRIP);
311c8c44fa0SJérôme Duval 			for (int j=0;j<qs[i].numpts;j++) {
312c8c44fa0SJérôme Duval 				glNormal3f(
313c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].nx,
314c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].ny,
315c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].nz
316c8c44fa0SJérôme Duval 				);
317c8c44fa0SJérôme Duval 				glVertex3f(
318c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].x,
319c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].y,
320c8c44fa0SJérôme Duval 					points[qs[i].pts[j]].z
321c8c44fa0SJérôme Duval 				);
322c8c44fa0SJérôme Duval 			};
323c8c44fa0SJérôme Duval 			glEnd();
324c8c44fa0SJérôme Duval 		};
325c8c44fa0SJérôme Duval #else
326c8c44fa0SJérôme Duval 		glBegin(GL_TRIANGLES);
327c8c44fa0SJérôme Duval 		for (int i=0;i<triangles.num_items;i++) {
328c8c44fa0SJérôme Duval 			int v3 = triangles[i].p1;
329c8c44fa0SJérôme Duval 			int v1 = triangles[i].p2;
330c8c44fa0SJérôme Duval 			int v2 = triangles[i].p3;
331c8c44fa0SJérôme Duval 	  		glNormal3f(
332c8c44fa0SJérôme Duval 				points[v1].nx,
333c8c44fa0SJérôme Duval 				points[v1].ny,
334c8c44fa0SJérôme Duval 				points[v1].nz
335c8c44fa0SJérôme Duval 			);
336c8c44fa0SJérôme Duval 			glVertex3f(
337c8c44fa0SJérôme Duval 				points[v1].x,
338c8c44fa0SJérôme Duval 				points[v1].y,
339c8c44fa0SJérôme Duval 				points[v1].z
340c8c44fa0SJérôme Duval 			);
341c8c44fa0SJérôme Duval 			glNormal3f(
342c8c44fa0SJérôme Duval 				points[v2].nx,
343c8c44fa0SJérôme Duval 				points[v2].ny,
344c8c44fa0SJérôme Duval 				points[v2].nz
345c8c44fa0SJérôme Duval 			);
346c8c44fa0SJérôme Duval 			glVertex3f(
347c8c44fa0SJérôme Duval 				points[v2].x,
348c8c44fa0SJérôme Duval 				points[v2].y,
349c8c44fa0SJérôme Duval 				points[v2].z
350c8c44fa0SJérôme Duval 			);
351c8c44fa0SJérôme Duval 			glNormal3f(
352c8c44fa0SJérôme Duval 				points[v3].nx,
353c8c44fa0SJérôme Duval 				points[v3].ny,
354c8c44fa0SJérôme Duval 				points[v3].nz
355c8c44fa0SJérôme Duval 			);
356c8c44fa0SJérôme Duval 			glVertex3f(
357c8c44fa0SJérôme Duval 				points[v3].x,
358c8c44fa0SJérôme Duval 				points[v3].y,
359c8c44fa0SJérôme Duval 				points[v3].z
360c8c44fa0SJérôme Duval 			);
361c8c44fa0SJérôme Duval 		};
362c8c44fa0SJérôme Duval 		glEnd();
363c8c44fa0SJérôme Duval #endif
364c8c44fa0SJérôme Duval };
365c8c44fa0SJérôme Duval 
366