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