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