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