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