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