2 //Last update Oct 17, 2003
4 //Loads, stores and displays .obj files on command
11 ModelType::ModelType()
31 ModelType::~ModelType()
36 void ModelType::Draw()
38 /* GLfloat n10Mat[] = { 1.00f, 1.00f, 1.00f, 1.00f };
39 GLfloat n05Mat[] = { 0.50f, 0.50f, 0.50f, 1.00f };
40 GLfloat n00Mat[] = { 0.00f, 0.00f, 0.00f, 1.00f };*/
41 GLfloat nullMat
[] = { 0.00f
, 0.00f
, 0.00f
, 1.00f
};
44 glPushAttrib(GL_LINE_SMOOTH
| GL_POLYGON_SMOOTH
| GL_TEXTURE_2D
| GL_BLEND
);
45 // glEnable(GL_LINE_SMOOTH);
46 //glEnable(GL_POLYGON_SMOOTH);
47 glShadeModel(GL_SMOOTH
);
48 // glEnable(GL_POLYGON_OFFSET_FILL);
49 // glEnable(GL_POLYGON_OFFSET_LINE);
51 glDisable(GL_CULL_FACE
);
53 /*for (int i = 0; i < numObjects; i++)
56 glMaterialf(GL_FRONT, GL_SHININESS, 128 );
57 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
58 glMaterialfv(GL_FRONT, GL_SPECULAR, n10Mat);
59 glMaterialfv(GL_FRONT, GL_DIFFUSE, cDispObj[i].dMat);
60 glMaterialfv(GL_FRONT, GL_AMBIENT, cDispObj[i].aMat);
61 glColor3fv(cDispObj[i].dMat);
63 glCallList(cDispObj[i].DispList);
67 for (int i
= 0; i
< numObjects
; i
++)
70 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, 64 /*cDispObj[i].SpecQty*/ );
71 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
72 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, cDispObj
[i
].sMat
);
73 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, cDispObj
[i
].dMat
);
74 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, cDispObj
[i
].aMat
);
75 glPolygonOffset(1.0, 2.0);
78 if (cDispObj
[i
].hasTexts
)
80 glBindTexture(GL_TEXTURE_2D
, cDispObj
[i
].TextMap
.texID
);
81 glCallList(cDispObj
[i
].DispList
);
82 glDepthMask(GL_FALSE
);
83 if (cDispObj
[i
].hasEdges
&& useSmooth
)
85 glPolygonOffset(1.0, 3.0);
87 glCallList(cDispObj
[i
].EdgeList
);
90 glPolygonMode(GL_FRONT
, GL_LINE
);
91 glCallList(cDispObj
[i
].DispList
);
92 glPolygonMode(GL_FRONT
, GL_FILL
);
98 glDisable(GL_TEXTURE_2D
);
99 glCallList(cDispObj
[i
].DispList
);
100 glDepthMask(GL_FALSE
);
101 if (cDispObj
[i
].hasEdges
&& useSmooth
)
103 glPolygonOffset(1.0, 3.0);
105 glCallList(cDispObj
[i
].EdgeList
);
108 glPolygonMode(GL_FRONT
, GL_LINE
);
109 glCallList(cDispObj
[i
].DispList
);
110 glPolygonMode(GL_FRONT
, GL_FILL
);
113 glEnable(GL_TEXTURE_2D
);
118 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
119 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, cDispObj
[i
].sMat
);
120 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, nullMat
);
121 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, nullMat
);
122 glPolygonOffset(1.0, 1.0);
123 if (cDispObj
[i
].hasSpecs
)
125 glBindTexture(GL_TEXTURE_2D
, cDispObj
[i
].SpecMap
.texID
);
126 glCallList(cDispObj
[i
].DispList
);
128 if (cDispObj
[i
].hasGlows
)
130 glDisable(GL_LIGHTING
);
131 glPolygonOffset(0.0, 0.0);
132 glBindTexture(GL_TEXTURE_2D
, cDispObj
[i
].GlowMap
.texID
);
133 glCallList(cDispObj
[i
].DispList
);
134 glEnable(GL_LIGHTING
);
142 bool ModelType::LoadObj(const char *filename
, float Scale
)
146 const GLubyte
*strRenderer
;
147 strRenderer
= glGetString (GL_RENDERER
);
148 if ((strncmp((char*)strRenderer
, "ATi Rage 128", 12) == 0) || (strncmp((char*)strRenderer
, "ATI Rage 128", 12) == 0))
153 if (!ParseObj(filename
))
161 cDispObj
= (OBJCModel
*)malloc(sizeof(OBJCModel
) * numObjects
);
164 if (__E3D_ENGINE_DEBUG
) printf("Completed loading model %s.\n\n", filename
);
169 for (int i
= 0; i
< numObjects
; i
++)
171 if (tDispObj
->group
[i
].objEdges
!= NULL
)
173 Delete_Edge(tDispObj
->group
[i
].objEdges
);
174 tDispObj
->group
[i
].objEdges
= NULL
;
179 for (int i
= 0; i
< numObjects
; i
++)
181 Delete_Face(tDispObj
->group
[i
].objTngls
);
182 Delete_Face(tDispObj
->group
[i
].objQuads
);
183 tDispObj
->group
[i
].objTngls
= NULL
;
184 tDispObj
->group
[i
].objQuads
= NULL
;
193 void ModelType::DeleteModel()
195 for (int i
= 0; i
< numObjects
; i
++)
197 glDeleteLists(cDispObj
[i
].DispList
, 1);
198 glDeleteLists(cDispObj
[i
].EdgeList
, 1);
200 DeleteTexture(cDispObj
[i
].TextMap
);
201 DeleteTexture(cDispObj
[i
].GlowMap
);
202 DeleteTexture(cDispObj
[i
].SpecMap
);
206 void ModelType::Normalise_Vector(OBJVertex
&vec
)
210 length
= sqrt((vec
.x
* vec
.x
) + (vec
.y
* vec
.y
) + (vec
.z
* vec
.z
));
220 void ModelType::Calc_Norm_Vector(const OBJVertex
& p1
, const OBJVertex
& p2
, const OBJVertex
& p3
, OBJVertex
&normal
)
232 normal
.x
= v1
.y
* v2
.z
- v1
.z
* v2
.y
;
233 normal
.y
= v1
.z
* v2
.x
- v1
.x
* v2
.z
;
234 normal
.z
= v1
.x
* v2
.y
- v1
.y
* v2
.x
;
236 Normalise_Vector(normal
);
239 void ModelType::Delete_Edge(OBJEdge
*currPtr
)
241 if (currPtr
->smlNext
!= NULL
)
242 Delete_Edge(currPtr
->smlNext
);
243 if (currPtr
->gtrNext
!= NULL
)
244 Delete_Edge(currPtr
->gtrNext
);
245 currPtr
->smlNext
= NULL
;
246 currPtr
->gtrNext
= NULL
;
249 bool ModelType::Insert_Edge(OBJEdge
*currPtr
, OBJEdge
*newEdge
)
251 if (currPtr
->gEdge
< newEdge
->gEdge
)
253 if (currPtr
->smlNext
== NULL
)
255 currPtr
->smlNext
= newEdge
;
258 return Insert_Edge(currPtr
->smlNext
, newEdge
);
261 if (currPtr
->gEdge
> newEdge
->gEdge
)
263 if (currPtr
->gtrNext
== NULL
)
265 currPtr
->gtrNext
= newEdge
;
268 return Insert_Edge(currPtr
->gtrNext
, newEdge
);
271 if (currPtr
->lEdge
< newEdge
->lEdge
)
273 if (currPtr
->smlNext
== NULL
)
275 currPtr
->smlNext
= newEdge
;
278 return Insert_Edge(currPtr
->smlNext
, newEdge
);
281 if (currPtr
->lEdge
> newEdge
->lEdge
)
283 if (currPtr
->gtrNext
== NULL
)
285 currPtr
->gtrNext
= newEdge
;
288 return Insert_Edge(currPtr
->gtrNext
, newEdge
);
291 currPtr
->lEdgeNorm
.x
+= newEdge
->lEdgeNorm
.x
;
292 currPtr
->lEdgeNorm
.y
+= newEdge
->lEdgeNorm
.y
;
293 currPtr
->lEdgeNorm
.z
+= newEdge
->lEdgeNorm
.z
;
294 currPtr
->gEdgeNorm
.x
+= newEdge
->gEdgeNorm
.x
;
295 currPtr
->gEdgeNorm
.y
+= newEdge
->gEdgeNorm
.y
;
296 currPtr
->gEdgeNorm
.z
+= newEdge
->gEdgeNorm
.z
;
300 OBJEdge
* ModelType::Add_New_Edge(OBJEdge
*headPtr
, int v1
, int t1
, const OBJVertex
& n1
, int v2
, int t2
, const OBJVertex
& n2
)
305 OBJEdge
*newEdge
= (OBJEdge
*)malloc(sizeof(OBJEdge
));
309 newEdge
->lEdgeText
= t1
;
310 newEdge
->lEdgeNorm
.x
= n1
.x
;
311 newEdge
->lEdgeNorm
.y
= n1
.y
;
312 newEdge
->lEdgeNorm
.z
= n1
.z
;
314 newEdge
->gEdgeText
= t2
;
315 newEdge
->gEdgeNorm
.x
= n2
.x
;
316 newEdge
->gEdgeNorm
.y
= n2
.y
;
317 newEdge
->gEdgeNorm
.z
= n2
.z
;
322 newEdge
->lEdgeText
= t2
;
323 newEdge
->lEdgeNorm
.x
= n2
.x
;
324 newEdge
->lEdgeNorm
.y
= n2
.y
;
325 newEdge
->lEdgeNorm
.z
= n2
.z
;
327 newEdge
->gEdgeText
= t1
;
328 newEdge
->gEdgeNorm
.x
= n1
.x
;
329 newEdge
->gEdgeNorm
.y
= n1
.y
;
330 newEdge
->gEdgeNorm
.z
= n1
.z
;
332 newEdge
->smlNext
= NULL
;
333 newEdge
->gtrNext
= NULL
;
338 if (!Insert_Edge(headPtr
, newEdge
))
344 void ModelType::Build_Edge_List()
346 for (int i
= 0; i
< numObjects
; i
++)
350 currPtr
= tDispObj
->group
[i
].objTngls
;
351 while (currPtr
!= NULL
)
353 if (currPtr
->NormType
)
355 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v1
, currPtr
->t1
, tDispObj
->objNorms
[currPtr
->n1
],
356 currPtr
->v2
, currPtr
->t2
, tDispObj
->objNorms
[currPtr
->n2
]);
357 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v2
, currPtr
->t2
, tDispObj
->objNorms
[currPtr
->n2
],
358 currPtr
->v3
, currPtr
->t3
, tDispObj
->objNorms
[currPtr
->n3
]);
359 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v3
, currPtr
->t3
, tDispObj
->objNorms
[currPtr
->n3
],
360 currPtr
->v1
, currPtr
->t1
, tDispObj
->objNorms
[currPtr
->n1
]);
364 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v1
, currPtr
->t1
, currPtr
->faceNorm
,
365 currPtr
->v2
, currPtr
->t2
, currPtr
->faceNorm
);
366 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v2
, currPtr
->t2
, currPtr
->faceNorm
,
367 currPtr
->v3
, currPtr
->t3
, currPtr
->faceNorm
);
368 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v3
, currPtr
->t3
, currPtr
->faceNorm
,
369 currPtr
->v1
, currPtr
->t1
, currPtr
->faceNorm
);
371 currPtr
= currPtr
->next
;
374 currPtr
= tDispObj
->group
[i
].objQuads
;
375 while (currPtr
!= NULL
)
377 if (currPtr
->NormType
)
379 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v1
, currPtr
->t1
, tDispObj
->objNorms
[currPtr
->n1
],
380 currPtr
->v2
, currPtr
->t2
, tDispObj
->objNorms
[currPtr
->n2
]);
381 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v2
, currPtr
->t2
, tDispObj
->objNorms
[currPtr
->n2
],
382 currPtr
->v3
, currPtr
->t3
, tDispObj
->objNorms
[currPtr
->n3
]);
383 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v3
, currPtr
->t3
, tDispObj
->objNorms
[currPtr
->n3
],
384 currPtr
->v4
, currPtr
->t4
, tDispObj
->objNorms
[currPtr
->n4
]);
385 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v4
, currPtr
->t4
, tDispObj
->objNorms
[currPtr
->n4
],
386 currPtr
->v1
, currPtr
->t1
, tDispObj
->objNorms
[currPtr
->n1
]);
390 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v1
, currPtr
->t1
, currPtr
->faceNorm
,
391 currPtr
->v2
, currPtr
->t2
, currPtr
->faceNorm
);
392 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v2
, currPtr
->t2
, currPtr
->faceNorm
,
393 currPtr
->v3
, currPtr
->t3
, currPtr
->faceNorm
);
394 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v3
, currPtr
->t3
, currPtr
->faceNorm
,
395 currPtr
->v4
, currPtr
->t4
, currPtr
->faceNorm
);
396 tDispObj
->group
[i
].objEdges
= Add_New_Edge(tDispObj
->group
[i
].objEdges
, currPtr
->v4
, currPtr
->t4
, currPtr
->faceNorm
,
397 currPtr
->v1
, currPtr
->t1
, currPtr
->faceNorm
);
399 currPtr
= currPtr
->next
;
404 void ModelType::Delete_Face(OBJFace
*headPtr
)
406 OBJFace
*currPtr
= headPtr
, *prevPtr
;
407 while (currPtr
!= NULL
)
410 currPtr
= currPtr
->next
;
415 void ModelType::Insert_Face(OBJFace
*headPtr
, OBJFace
*newFace
)
417 OBJFace
*currPtr
= headPtr
;
418 while (currPtr
->next
!= NULL
)
419 currPtr
= currPtr
->next
;
421 currPtr
->next
= newFace
;
424 bool ModelType::LoadTGA_CMP(FILE *in_file
, TextureImage
&texture
, GLubyte
*imageData
)
426 GLuint bytesPerPixel
= texture
.bpp
/ 8;
427 GLuint pixelcount
= texture
.height
* texture
.width
;
428 GLuint currentpixel
= 0;
429 GLuint currentbyte
= 0;
430 GLubyte
*colorbuffer
= (GLubyte
*)malloc(bytesPerPixel
);
432 if (colorbuffer
== NULL
)
434 printf("error, unable to allocate memory!\n");
440 GLubyte chunkheader
= 0;
441 if (fread(&chunkheader
, sizeof(GLubyte
), 1, in_file
) == 0)
443 printf("error, could not read RLE header.\n");
448 if (chunkheader
< 128)
452 for (counter
= 0; counter
< chunkheader
; counter
++)
454 if (fread(colorbuffer
, 1, bytesPerPixel
, in_file
) != bytesPerPixel
)
456 printf("error, could not read image data.\n");
461 imageData
[currentbyte
] = colorbuffer
[2];
462 imageData
[currentbyte
+ 1] = colorbuffer
[1];
463 imageData
[currentbyte
+ 2] = colorbuffer
[0];
465 if (bytesPerPixel
== 4)
466 imageData
[currentbyte
+ 3] = colorbuffer
[3];
468 currentbyte
+= bytesPerPixel
;
471 if (currentpixel
> pixelcount
)
473 printf("error, too many pixels read.\n");
483 if (fread(colorbuffer
, 1, bytesPerPixel
, in_file
) != bytesPerPixel
)
485 printf("error, could not read from file.\n");
490 for (counter
= 0; counter
< chunkheader
; counter
++)
492 imageData
[currentbyte
] = colorbuffer
[2];
493 imageData
[currentbyte
+ 1] = colorbuffer
[1];
494 imageData
[currentbyte
+ 2] = colorbuffer
[0];
496 if (bytesPerPixel
== 4)
497 imageData
[currentbyte
+ 3] = colorbuffer
[3];
499 currentbyte
+= bytesPerPixel
;
502 if(currentpixel
> pixelcount
)
504 printf("error, too many pixels read.\n");
510 } while (currentpixel
< pixelcount
);
516 bool ModelType::LoadTGA_RAW(FILE *in_file
, TextureImage
&texture
, GLubyte
*imageData
)
518 GLuint bytesPerPixel
= texture
.bpp
/ 8;
519 GLuint imageSize
= texture
.width
* texture
.height
* bytesPerPixel
;
522 if (fread(imageData
, 1, imageSize
, in_file
) != imageSize
)
524 printf("error, file appears to be damaged!\n");
528 for(int i
= 0; i
< int(imageSize
); i
+= bytesPerPixel
)
531 imageData
[i
] = imageData
[i
+ 2];
532 imageData
[i
+ 2] = temp
;
538 bool ModelType::LoadTGA(TextureImage
&texture
, const char *filename
, int UseMipMaps
)
540 GLubyte RAW_Header
[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
541 GLubyte CMP_Header
[12] = { 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
542 GLubyte TGAcompare
[12];
544 GLuint type
= GL_RGBA
;
549 FILE *in_file
= fopen(filename
, "rb");
551 if (__E3D_ENGINE_DEBUG
) printf("Loading texture %s: ", filename
);
555 printf("error, file not found!\n");
559 if (fread(TGAcompare
, 1, sizeof(TGAcompare
), in_file
) != sizeof(TGAcompare
))
561 printf("error, invalid format!\n");
566 if (memcmp(RAW_Header
, TGAcompare
, sizeof(TGAcompare
)) == 0)
568 else if (memcmp(CMP_Header
, TGAcompare
, sizeof(TGAcompare
)) == 0)
572 printf("error, invalid format!\n");
577 if (fread(header
, 1, sizeof(header
), in_file
) != sizeof(header
))
579 printf("error, invalid format!\n");
584 texture
.width
= header
[1] * 256 + header
[0];
585 texture
.height
= header
[3] * 256 + header
[2];
586 texture
.bpp
= header
[4];
587 if (texture
.width
<= 0 || texture
.height
<= 0 || (texture
.bpp
!= 24 && texture
.bpp
!= 32))
589 printf("error, invalid format!\n");
594 imageData
= (GLubyte
*)malloc(texture
.width
* texture
.height
* texture
.bpp
);
595 if (imageData
== NULL
)
597 printf("error, unable to allocate memory!\n");
604 if (!LoadTGA_CMP(in_file
, texture
, imageData
))
613 if (!LoadTGA_RAW(in_file
, texture
, imageData
))
622 glGenTextures(1, &texture
.texID
);
623 if (texture
.bpp
== 24)
626 glBindTexture(GL_TEXTURE_2D
, texture
.texID
);
629 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
630 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR_MIPMAP_LINEAR
);
631 gluBuild2DMipmaps(GL_TEXTURE_2D
, 3, texture
.width
, texture
.height
, type
, GL_UNSIGNED_BYTE
, (GLvoid
*)imageData
);
635 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
636 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
637 glTexImage2D(GL_TEXTURE_2D
, 0, type
, texture
.width
, texture
.height
, 0, type
, GL_UNSIGNED_BYTE
, (GLvoid
*)imageData
);
643 /* printf("done.\n");
645 printf("-> Format of texture: RLE Compressed.\n");
647 printf("-> Format of texture: Uncompressed.\n");
648 printf("-> Width of texture: %d\n", (int)texture.width);
649 printf("-> Height of texture: %d\n", (int)texture.height);
650 printf("-> Bitdepth of texture: %d\n", (int)texture.bpp);*/
654 void ModelType::DeleteTexture(TextureImage
&texture
)
656 glDeleteTextures(1, &texture
.texID
);
659 bool ModelType::ParseMtl(const char *filename
)
664 float cVal1
, cVal2
, cVal3
;
667 sprintf(file
,"data/ships/%s",filename
);
668 if (__E3D_ENGINE_DEBUG
) printf("Loading material library %s: ", filename
);
669 in_file
= fopen(file
, "rt");
672 printf("error, file not found!\n");
676 while (!feof(in_file
))
678 if (better_fgets(oneline
, 255, in_file
) == NULL
)
681 if (strncmp(oneline
, "newmtl", 6) == 0)
684 sscanf(oneline
, "newmtl %s", tDispObj
->mtrl
[currMtrl
].Name
);
686 if (strncmp(oneline
, "Ka", 2) == 0)
688 sscanf(oneline
, "Ka %f %f %f", &cVal1
, &cVal2
, &cVal3
);
689 tDispObj
->mtrl
[currMtrl
].aCol
.x
= cVal1
;
690 tDispObj
->mtrl
[currMtrl
].aCol
.y
= cVal2
;
691 tDispObj
->mtrl
[currMtrl
].aCol
.z
= cVal3
;
693 if (strncmp(oneline
, "Kd", 2) == 0)
695 sscanf(oneline
, "Kd %f %f %f", &cVal1
, &cVal2
, &cVal3
);
696 tDispObj
->mtrl
[currMtrl
].dCol
.x
= cVal1
;
697 tDispObj
->mtrl
[currMtrl
].dCol
.y
= cVal2
;
698 tDispObj
->mtrl
[currMtrl
].dCol
.z
= cVal3
;
700 if (strncmp(oneline
, "Ks", 2) == 0)
702 sscanf(oneline
, "Ks %f %f %f", &cVal1
, &cVal2
, &cVal3
);
703 tDispObj
->mtrl
[currMtrl
].sCol
.x
= cVal1
;
704 tDispObj
->mtrl
[currMtrl
].sCol
.y
= cVal2
;
705 tDispObj
->mtrl
[currMtrl
].sCol
.z
= cVal3
;
707 if (strncmp(oneline
, "Tr", 2) == 0)
709 sscanf(oneline
, "Tr %f", &cVal1
);
710 tDispObj
->mtrl
[currMtrl
].Opacity
= cVal1
;
712 if (strncmp(oneline
, "Ns", 2) == 0)
714 sscanf(oneline
, "Ns %f", &cVal1
);
715 tDispObj
->mtrl
[currMtrl
].Reflect
= cVal1
;
717 else if (strncmp(oneline
, "map_Ka", 6) == 0)
718 sscanf(oneline
, "map_Ka %s", tDispObj
->mtrl
[currMtrl
].aTextName
);
719 else if (strncmp(oneline
, "map_Kd", 6) == 0)
720 sscanf(oneline
, "map_Kd %s", tDispObj
->mtrl
[currMtrl
].dTextName
);
721 else if (strncmp(oneline
, "map_Ks", 6) == 0)
722 sscanf(oneline
, "map_Ks %s", tDispObj
->mtrl
[currMtrl
].sTextName
);
723 else if (sscanf(oneline
, "Smooth %d", &bVal
) == 1)
724 tDispObj
->mtrl
[currMtrl
].SmthType
= bVal
;
725 else if (sscanf(oneline
, "Normal %d", &bVal
) == 1)
726 tDispObj
->mtrl
[currMtrl
].NormType
= bVal
;
730 // printf("-> Number of materials: %d\n", ++currMtrl);
731 numObjects
= currMtrl
;
735 bool ModelType::ParseObj(const char *filename
)
742 int iV1
, iV2
, iV3
, iV4
, iT1
, iT2
, iT3
, iT4
, iN1
, iN2
, iN3
, iN4
;
744 if (__E3D_ENGINE_DEBUG
) printf("Loading model %s: ", filename
);
745 in_file
= fopen(filename
, "rt");
748 printf("error, file not found!\n");
752 // printf("done.\n");
754 tDispObj
= (OBJModel
*)malloc(sizeof(OBJModel
));
755 tDispObj
->NumVerts
= 0;
756 tDispObj
->NumTexts
= 0;
757 tDispObj
->NumNorms
= 0;
758 tDispObj
->NumTngls
= 0;
759 tDispObj
->NumQuads
= 0;
761 for (int i
= 0; i
< objMaxNumMats
; i
++)
763 tDispObj
->group
[i
].objTngls
= NULL
;
764 tDispObj
->group
[i
].objQuads
= NULL
;
765 tDispObj
->group
[i
].objEdges
= NULL
;
766 tDispObj
->group
[i
].matID
= -1;
768 tDispObj
->mtrl
[i
].Name
[0] = '\0';
769 tDispObj
->mtrl
[i
].aTextName
[0] = '\0';
770 tDispObj
->mtrl
[i
].dTextName
[0] = '\0';
771 tDispObj
->mtrl
[i
].sTextName
[0] = '\0';
772 tDispObj
->mtrl
[i
].NormType
= 0;
773 tDispObj
->mtrl
[i
].SmthType
= 0;
774 tDispObj
->mtrl
[i
].aCol
.x
= 1.0f
;
775 tDispObj
->mtrl
[i
].aCol
.y
= 1.0f
;
776 tDispObj
->mtrl
[i
].aCol
.z
= 1.0f
;
777 tDispObj
->mtrl
[i
].dCol
.x
= 1.0f
;
778 tDispObj
->mtrl
[i
].dCol
.y
= 1.0f
;
779 tDispObj
->mtrl
[i
].dCol
.z
= 1.0f
;
780 tDispObj
->mtrl
[i
].sCol
.x
= 1.0f
;
781 tDispObj
->mtrl
[i
].sCol
.y
= 1.0f
;
782 tDispObj
->mtrl
[i
].sCol
.z
= 1.0f
;
783 tDispObj
->mtrl
[i
].Reflect
= 1.0f
;
784 tDispObj
->mtrl
[i
].Opacity
= 1.0f
;
787 while (!feof(in_file
))
789 if (better_fgets(oneline
, 255, in_file
) == NULL
)
792 if (strncmp(oneline
, "mtllib", 6) == 0)
794 if (sscanf(oneline
, "mtllib %s", mtlname
) == 1)
798 if (strncmp(oneline
, "usemtl", 6) == 0)
802 if ((sscanf(oneline
, "usemtl %s", mtlname
) == 1) && (numObjects
!= 0))
804 while (strncmp(mtlname
, tDispObj
->mtrl
[matID
].Name
, 32) != 0)
807 if (matID
== numObjects
)
812 tDispObj
->group
[currGroup
].matID
= matID
;
815 if (sscanf(oneline
, "v %f %f %f", &x
, &y
, &z
) == 3)
820 tDispObj
->objVerts
[tDispObj
->NumVerts
].x
= x
;
821 tDispObj
->objVerts
[tDispObj
->NumVerts
].y
= y
;
822 tDispObj
->objVerts
[tDispObj
->NumVerts
].z
= z
;
823 tDispObj
->NumVerts
++;
837 else if (sscanf(oneline
, "vt %f %f %f", &x
, &y
, &z
) == 3)
839 tDispObj
->objTexts
[tDispObj
->NumTexts
].u
= x
;
840 tDispObj
->objTexts
[tDispObj
->NumTexts
].v
= y
;
841 tDispObj
->objTexts
[tDispObj
->NumTexts
].w
= z
;
842 tDispObj
->NumTexts
++;
844 else if (sscanf(oneline
, "vt %f %f", &x
, &y
) == 2)
846 tDispObj
->objTexts
[tDispObj
->NumTexts
].u
= x
;
847 tDispObj
->objTexts
[tDispObj
->NumTexts
].v
= y
;
848 tDispObj
->objTexts
[tDispObj
->NumTexts
].w
= 0.0f
;
849 tDispObj
->NumTexts
++;
851 else if (sscanf(oneline
, "vn %f %f %f", &x
, &y
, &z
) == 3)
853 tDispObj
->objNorms
[tDispObj
->NumNorms
].x
= x
;
854 tDispObj
->objNorms
[tDispObj
->NumNorms
].y
= y
;
855 tDispObj
->objNorms
[tDispObj
->NumNorms
].z
= z
;
856 tDispObj
->NumNorms
++;
858 else if (sscanf(oneline
, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &iV1
, &iT1
, &iN1
, &iV2
, &iT2
, &iN2
, &iV3
, &iT3
, &iN3
, &iV4
, &iT4
, &iN4
) == 12)
860 tDispObj
->NumQuads
++;
861 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
862 newFace
->next
= NULL
;
864 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
865 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
866 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
867 newFace
->v4
= (iV4
< 0) ? (tDispObj
->NumVerts
+ iV4
) : --iV4
;
869 newFace
->t1
= (iT1
< 0) ? (tDispObj
->NumTexts
+ iT1
) : --iT1
;
870 newFace
->t2
= (iT2
< 0) ? (tDispObj
->NumTexts
+ iT2
) : --iT2
;
871 newFace
->t3
= (iT3
< 0) ? (tDispObj
->NumTexts
+ iT3
) : --iT3
;
872 newFace
->t4
= (iT4
< 0) ? (tDispObj
->NumTexts
+ iT4
) : --iT4
;
874 newFace
->n1
= (iN1
< 0) ? (tDispObj
->NumNorms
+ iN1
) : --iN1
;
875 newFace
->n2
= (iN2
< 0) ? (tDispObj
->NumNorms
+ iN2
) : --iN2
;
876 newFace
->n3
= (iN3
< 0) ? (tDispObj
->NumNorms
+ iN3
) : --iN3
;
877 newFace
->n4
= (iN4
< 0) ? (tDispObj
->NumNorms
+ iN4
) : --iN4
;
879 newFace
->NormType
= 1;
881 currGroup
= numObjects
;
882 if (tDispObj
->group
[currGroup
].objQuads
== NULL
)
883 tDispObj
->group
[currGroup
].objQuads
= newFace
;
885 Insert_Face(tDispObj
->group
[currGroup
].objQuads
, newFace
);
887 else if (sscanf(oneline
, "f %d/%d/%d %d/%d/%d %d/%d/%d", &iV1
, &iT1
, &iN1
, &iV2
, &iT2
, &iN2
, &iV3
, &iT3
, &iN3
) == 9)
889 tDispObj
->NumTngls
++;
890 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
891 newFace
->next
= NULL
;
893 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
894 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
895 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
898 newFace
->t1
= (iT1
< 0) ? (tDispObj
->NumTexts
+ iT1
) : --iT1
;
899 newFace
->t2
= (iT2
< 0) ? (tDispObj
->NumTexts
+ iT2
) : --iT2
;
900 newFace
->t3
= (iT3
< 0) ? (tDispObj
->NumTexts
+ iT3
) : --iT3
;
903 newFace
->n1
= (iN1
< 0) ? (tDispObj
->NumNorms
+ iN1
) : --iN1
;
904 newFace
->n2
= (iN2
< 0) ? (tDispObj
->NumNorms
+ iN2
) : --iN2
;
905 newFace
->n3
= (iN3
< 0) ? (tDispObj
->NumNorms
+ iN3
) : --iN3
;
908 newFace
->NormType
= 1;
910 currGroup
= numObjects
;
911 if (tDispObj
->group
[currGroup
].objTngls
== NULL
)
912 tDispObj
->group
[currGroup
].objTngls
= newFace
;
914 Insert_Face(tDispObj
->group
[currGroup
].objTngls
, newFace
);
916 else if (sscanf(oneline
, "f %d//%d %d//%d %d//%d %d//%d", &iV1
, &iN1
, &iV2
, &iN2
, &iV3
, &iN3
, &iV4
, &iN4
) == 8)
918 tDispObj
->NumQuads
++;
919 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
920 newFace
->next
= NULL
;
922 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
923 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
924 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
925 newFace
->v4
= (iV4
< 0) ? (tDispObj
->NumVerts
+ iV4
) : --iV4
;
932 newFace
->n1
= (iN1
< 0) ? (tDispObj
->NumNorms
+ iN1
) : --iN1
;
933 newFace
->n2
= (iN2
< 0) ? (tDispObj
->NumNorms
+ iN2
) : --iN2
;
934 newFace
->n3
= (iN3
< 0) ? (tDispObj
->NumNorms
+ iN3
) : --iN3
;
935 newFace
->n4
= (iN4
< 0) ? (tDispObj
->NumNorms
+ iN4
) : --iN4
;
937 newFace
->NormType
= 1;
939 currGroup
= numObjects
;
940 if (tDispObj
->group
[currGroup
].objQuads
== NULL
)
941 tDispObj
->group
[currGroup
].objQuads
= newFace
;
943 Insert_Face(tDispObj
->group
[currGroup
].objQuads
, newFace
);
945 else if (sscanf(oneline
, "f %d/%d %d/%d %d/%d %d/%d", &iV1
, &iT1
, &iV2
, &iT2
, &iV3
, &iT3
, &iV4
, &iT4
) == 8)
947 tDispObj
->NumQuads
++;
948 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
949 newFace
->next
= NULL
;
951 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
952 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
953 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
954 newFace
->v4
= (iV4
< 0) ? (tDispObj
->NumVerts
+ iV4
) : --iV4
;
956 newFace
->t1
= (iT1
< 0) ? (tDispObj
->NumTexts
+ iT1
) : --iT1
;
957 newFace
->t2
= (iT2
< 0) ? (tDispObj
->NumTexts
+ iT2
) : --iT2
;
958 newFace
->t3
= (iT3
< 0) ? (tDispObj
->NumTexts
+ iT3
) : --iT3
;
959 newFace
->t4
= (iT4
< 0) ? (tDispObj
->NumTexts
+ iT4
) : --iT4
;
966 newFace
->NormType
= 0;
968 currGroup
= numObjects
;
969 if (tDispObj
->group
[currGroup
].objQuads
== NULL
)
970 tDispObj
->group
[currGroup
].objQuads
= newFace
;
972 Insert_Face(tDispObj
->group
[currGroup
].objQuads
, newFace
);
974 else if (sscanf(oneline
, "f %d//%d %d//%d %d//%d", &iV1
, &iN1
, &iV2
, &iN2
, &iV3
, &iN3
) == 6)
976 tDispObj
->NumTngls
++;
977 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
978 newFace
->next
= NULL
;
980 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
981 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
982 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
990 newFace
->n1
= (iN1
< 0) ? (tDispObj
->NumNorms
+ iN1
) : --iN1
;
991 newFace
->n2
= (iN2
< 0) ? (tDispObj
->NumNorms
+ iN2
) : --iN2
;
992 newFace
->n3
= (iN3
< 0) ? (tDispObj
->NumNorms
+ iN3
) : --iN3
;
995 newFace
->NormType
= 1;
997 currGroup
= numObjects
;
998 if (tDispObj
->group
[currGroup
].objTngls
== NULL
)
999 tDispObj
->group
[currGroup
].objTngls
= newFace
;
1001 Insert_Face(tDispObj
->group
[currGroup
].objTngls
, newFace
);
1003 else if (sscanf(oneline
, "f %d/%d %d/%d %d/%d", &iV1
, &iT1
, &iV2
, &iT2
, &iV3
, &iT3
) == 6)
1005 tDispObj
->NumTngls
++;
1006 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
1007 newFace
->next
= NULL
;
1009 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
1010 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
1011 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
1014 newFace
->t1
= (iT1
< 0) ? (tDispObj
->NumTexts
+ iT1
) : --iT1
;
1015 newFace
->t2
= (iT2
< 0) ? (tDispObj
->NumTexts
+ iT2
) : --iT2
;
1016 newFace
->t3
= (iT3
< 0) ? (tDispObj
->NumTexts
+ iT3
) : --iT3
;
1024 newFace
->NormType
= 0;
1025 if (currGroup
== -1)
1026 currGroup
= numObjects
;
1027 if (tDispObj
->group
[currGroup
].objTngls
== NULL
)
1028 tDispObj
->group
[currGroup
].objTngls
= newFace
;
1030 Insert_Face(tDispObj
->group
[currGroup
].objTngls
, newFace
);
1032 else if (sscanf(oneline
, "f %d %d %d %d", &iV1
, &iV2
, &iV3
, &iV4
) == 4)
1034 tDispObj
->NumQuads
++;
1035 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
1036 newFace
->next
= NULL
;
1038 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
1039 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
1040 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
1041 newFace
->v4
= (iV4
< 0) ? (tDispObj
->NumVerts
+ iV4
) : --iV4
;
1053 newFace
->NormType
= 0;
1054 if (currGroup
== -1)
1055 currGroup
= numObjects
;
1056 if (tDispObj
->group
[currGroup
].objQuads
== NULL
)
1057 tDispObj
->group
[currGroup
].objQuads
= newFace
;
1059 Insert_Face(tDispObj
->group
[currGroup
].objQuads
, newFace
);
1061 else if (sscanf(oneline
, "f %d %d %d", &iV1
, &iV2
, &iV3
) == 3)
1063 tDispObj
->NumTngls
++;
1064 OBJFace
*newFace
= (OBJFace
*)malloc(sizeof(OBJFace
));
1065 newFace
->next
= NULL
;
1067 newFace
->v1
= (iV1
< 0) ? (tDispObj
->NumVerts
+ iV1
) : --iV1
;
1068 newFace
->v2
= (iV2
< 0) ? (tDispObj
->NumVerts
+ iV2
) : --iV2
;
1069 newFace
->v3
= (iV3
< 0) ? (tDispObj
->NumVerts
+ iV3
) : --iV3
;
1082 newFace
->NormType
= 0;
1083 if (currGroup
== -1)
1084 currGroup
= numObjects
;
1085 if (tDispObj
->group
[currGroup
].objTngls
== NULL
)
1086 tDispObj
->group
[currGroup
].objTngls
= newFace
;
1088 Insert_Face(tDispObj
->group
[currGroup
].objTngls
, newFace
);
1093 if (numObjects
== 0)
1096 if (fabs(maxVerts
.x
) > myRadius
)
1097 myRadius
= fabs(maxVerts
.x
);
1098 if (fabs(maxVerts
.y
) > myRadius
)
1099 myRadius
= fabs(maxVerts
.y
);
1100 if (fabs(maxVerts
.z
) > myRadius
)
1101 myRadius
= fabs(maxVerts
.z
);
1102 if (fabs(minVerts
.x
) > myRadius
)
1103 myRadius
= fabs(maxVerts
.x
);
1104 if (fabs(minVerts
.y
) > myRadius
)
1105 myRadius
= fabs(maxVerts
.y
);
1106 if (fabs(minVerts
.z
) > myRadius
)
1107 myRadius
= fabs(maxVerts
.z
);
1109 // printf("-> Number of vertices: %d\n", tDispObj->NumVerts);
1110 // printf("-> Number of normals: %d\n", tDispObj->NumNorms);
1111 // printf("-> Number of tex coords: %d\n", tDispObj->NumTexts);
1112 // printf("-> Number of triangles: %d\n", tDispObj->NumTngls);
1113 // printf("-> Number of quads: %d\n", tDispObj->NumQuads);
1117 void ModelType::DrawEdges(OBJEdge
*theEdge
)
1119 if (theEdge
== NULL
)
1122 Normalise_Vector(theEdge
->lEdgeNorm
);
1123 Normalise_Vector(theEdge
->gEdgeNorm
);
1125 glNormal3f(theEdge
->lEdgeNorm
.x
, theEdge
->lEdgeNorm
.y
, theEdge
->lEdgeNorm
.z
);
1126 if (theEdge
->lEdgeText
>= 0)
1127 glTexCoord3f(tDispObj
->objTexts
[theEdge
->lEdgeText
].u
, tDispObj
->objTexts
[theEdge
->lEdgeText
].v
, tDispObj
->objTexts
[theEdge
->lEdgeText
].w
);
1128 glVertex3d(tDispObj
->objVerts
[theEdge
->lEdge
].x
, tDispObj
->objVerts
[theEdge
->lEdge
].y
, tDispObj
->objVerts
[theEdge
->lEdge
].z
);
1130 glNormal3f(theEdge
->gEdgeNorm
.x
, theEdge
->gEdgeNorm
.y
, theEdge
->gEdgeNorm
.z
);
1131 if (theEdge
->gEdgeText
>= 0)
1132 glTexCoord3f(tDispObj
->objTexts
[theEdge
->gEdgeText
].u
, tDispObj
->objTexts
[theEdge
->gEdgeText
].v
, tDispObj
->objTexts
[theEdge
->gEdgeText
].w
);
1133 glVertex3d(tDispObj
->objVerts
[theEdge
->gEdge
].x
, tDispObj
->objVerts
[theEdge
->gEdge
].y
, tDispObj
->objVerts
[theEdge
->gEdge
].z
);
1135 DrawEdges(theEdge
->smlNext
);
1136 DrawEdges(theEdge
->gtrNext
);
1139 void ModelType::GenEdgeObj()
1141 for (int i
= 0; i
< numObjects
; i
++)
1143 if (!tDispObj
->mtrl
[i
].SmthType
)
1146 cDispObj
[i
].hasEdges
= true;
1147 cDispObj
[i
].EdgeList
= glGenLists(1);
1148 glNewList(cDispObj
[i
].EdgeList
, GL_COMPILE
);
1152 DrawEdges(tDispObj
->group
[i
].objEdges
);
1160 void ModelType::NormDispObj()
1164 for (int i
= 0; i
< objMaxNumVerts
; i
++)
1166 tDispObj
->objNorms
[i
].x
= 0.0f
;
1167 tDispObj
->objNorms
[i
].y
= 0.0f
;
1168 tDispObj
->objNorms
[i
].z
= 0.0f
;
1171 for (int i
= 0; i
< numObjects
; i
++)
1173 int currMat
= tDispObj
->group
[i
].matID
;
1176 currPtr
= tDispObj
->group
[i
].objTngls
;
1177 while (currPtr
!= NULL
)
1179 if (!currPtr
->NormType
)
1181 if (tDispObj
->mtrl
[currMat
].NormType
)
1183 Calc_Norm_Vector(tDispObj
->objVerts
[currPtr
->v1
], tDispObj
->objVerts
[currPtr
->v2
], tDispObj
->objVerts
[currPtr
->v3
], myNormal
);
1184 tDispObj
->objNorms
[currPtr
->v1
].x
+= myNormal
.x
;
1185 tDispObj
->objNorms
[currPtr
->v1
].y
+= myNormal
.y
;
1186 tDispObj
->objNorms
[currPtr
->v1
].z
+= myNormal
.z
;
1187 tDispObj
->objNorms
[currPtr
->v2
].x
+= myNormal
.x
;
1188 tDispObj
->objNorms
[currPtr
->v2
].y
+= myNormal
.y
;
1189 tDispObj
->objNorms
[currPtr
->v2
].z
+= myNormal
.z
;
1190 tDispObj
->objNorms
[currPtr
->v3
].x
+= myNormal
.x
;
1191 tDispObj
->objNorms
[currPtr
->v3
].y
+= myNormal
.y
;
1192 tDispObj
->objNorms
[currPtr
->v3
].z
+= myNormal
.z
;
1193 currPtr
->n1
= currPtr
->v1
;
1194 currPtr
->n2
= currPtr
->v2
;
1195 currPtr
->n3
= currPtr
->v3
;
1196 currPtr
->NormType
= 1;
1200 Calc_Norm_Vector(tDispObj
->objVerts
[currPtr
->v1
], tDispObj
->objVerts
[currPtr
->v2
], tDispObj
->objVerts
[currPtr
->v3
], currPtr
->faceNorm
);
1203 currPtr
= currPtr
->next
;
1206 currPtr
= tDispObj
->group
[i
].objQuads
;
1207 while (currPtr
!= NULL
)
1209 if (!currPtr
->NormType
)
1211 if (tDispObj
->mtrl
[currMat
].NormType
)
1213 Calc_Norm_Vector(tDispObj
->objVerts
[currPtr
->v1
], tDispObj
->objVerts
[currPtr
->v2
], tDispObj
->objVerts
[currPtr
->v3
], myNormal
);
1214 tDispObj
->objNorms
[currPtr
->v1
].x
+= myNormal
.x
;
1215 tDispObj
->objNorms
[currPtr
->v1
].y
+= myNormal
.y
;
1216 tDispObj
->objNorms
[currPtr
->v1
].z
+= myNormal
.z
;
1217 tDispObj
->objNorms
[currPtr
->v2
].x
+= myNormal
.x
;
1218 tDispObj
->objNorms
[currPtr
->v2
].y
+= myNormal
.y
;
1219 tDispObj
->objNorms
[currPtr
->v2
].z
+= myNormal
.z
;
1220 tDispObj
->objNorms
[currPtr
->v3
].x
+= myNormal
.x
;
1221 tDispObj
->objNorms
[currPtr
->v3
].y
+= myNormal
.y
;
1222 tDispObj
->objNorms
[currPtr
->v3
].z
+= myNormal
.z
;
1223 tDispObj
->objNorms
[currPtr
->v4
].x
+= myNormal
.x
;
1224 tDispObj
->objNorms
[currPtr
->v4
].y
+= myNormal
.y
;
1225 tDispObj
->objNorms
[currPtr
->v4
].z
+= myNormal
.z
;
1226 currPtr
->n1
= currPtr
->v1
;
1227 currPtr
->n2
= currPtr
->v2
;
1228 currPtr
->n3
= currPtr
->v3
;
1229 currPtr
->n4
= currPtr
->v4
;
1230 currPtr
->NormType
= 1;
1234 Calc_Norm_Vector(tDispObj
->objVerts
[currPtr
->v1
], tDispObj
->objVerts
[currPtr
->v2
], tDispObj
->objVerts
[currPtr
->v3
], currPtr
->faceNorm
);
1237 currPtr
= currPtr
->next
;
1241 for (int i
= 0; i
< objMaxNumVerts
; i
++)
1243 Normalise_Vector(tDispObj
->objNorms
[i
]);
1247 void ModelType::GenDispObj()
1249 for (int i
= 0; i
< numObjects
; i
++)
1253 if (tDispObj
->mtrl
[i
].dTextName
[0] != '\0')
1254 cDispObj
[i
].hasTexts
= LoadTGA(cDispObj
[i
].TextMap
, tDispObj
->mtrl
[i
].dTextName
, 1);
1256 cDispObj
[i
].hasTexts
= false;
1257 if (tDispObj
->mtrl
[i
].sTextName
[0] != '\0')
1258 cDispObj
[i
].hasSpecs
= LoadTGA(cDispObj
[i
].SpecMap
, tDispObj
->mtrl
[i
].sTextName
, 1);
1260 cDispObj
[i
].hasSpecs
= false;
1261 if (tDispObj
->mtrl
[i
].aTextName
[0] != '\0')
1262 cDispObj
[i
].hasGlows
= LoadTGA(cDispObj
[i
].GlowMap
, tDispObj
->mtrl
[i
].aTextName
, 1);
1264 cDispObj
[i
].hasGlows
= false;
1266 cDispObj
[i
].SpecQty
= tDispObj
->mtrl
[i
].Reflect
;
1267 cDispObj
[i
].dMat
[0] = tDispObj
->mtrl
[i
].dCol
.x
;
1268 cDispObj
[i
].dMat
[1] = tDispObj
->mtrl
[i
].dCol
.y
;
1269 cDispObj
[i
].dMat
[2] = tDispObj
->mtrl
[i
].dCol
.z
;
1270 cDispObj
[i
].dMat
[3] = tDispObj
->mtrl
[i
].Opacity
;
1271 cDispObj
[i
].aMat
[0] = tDispObj
->mtrl
[i
].aCol
.x
;
1272 cDispObj
[i
].aMat
[1] = tDispObj
->mtrl
[i
].aCol
.y
;
1273 cDispObj
[i
].aMat
[2] = tDispObj
->mtrl
[i
].aCol
.z
;
1274 cDispObj
[i
].aMat
[3] = tDispObj
->mtrl
[i
].Opacity
;
1275 cDispObj
[i
].sMat
[0] = tDispObj
->mtrl
[i
].sCol
.x
;
1276 cDispObj
[i
].sMat
[1] = tDispObj
->mtrl
[i
].sCol
.y
;
1277 cDispObj
[i
].sMat
[2] = tDispObj
->mtrl
[i
].sCol
.z
;
1278 cDispObj
[i
].sMat
[3] = tDispObj
->mtrl
[i
].Opacity
;
1280 cDispObj
[i
].DispList
= glGenLists(1);
1281 glNewList(cDispObj
[i
].DispList
, GL_COMPILE
);
1283 glBegin(GL_TRIANGLES
);
1284 currPtr
= tDispObj
->group
[i
].objTngls
;
1285 while (currPtr
!= NULL
)
1287 if (!currPtr
->NormType
)
1288 glNormal3f(currPtr
->faceNorm
.x
, currPtr
->faceNorm
.y
, currPtr
->faceNorm
.z
);
1290 glNormal3f(tDispObj
->objNorms
[currPtr
->n1
].x
, tDispObj
->objNorms
[currPtr
->n1
].y
, tDispObj
->objNorms
[currPtr
->n1
].z
);
1291 if (currPtr
->t1
> 0)
1292 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t1
].u
, tDispObj
->objTexts
[currPtr
->t1
].v
, tDispObj
->objTexts
[currPtr
->t1
].w
);
1293 glVertex3f(tDispObj
->objVerts
[currPtr
->v1
].x
, tDispObj
->objVerts
[currPtr
->v1
].y
, tDispObj
->objVerts
[currPtr
->v1
].z
);
1295 if (currPtr
->NormType
)
1296 glNormal3f(tDispObj
->objNorms
[currPtr
->n2
].x
, tDispObj
->objNorms
[currPtr
->n2
].y
, tDispObj
->objNorms
[currPtr
->n2
].z
);
1297 if (currPtr
->t2
> 0)
1298 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t2
].u
, tDispObj
->objTexts
[currPtr
->t2
].v
, tDispObj
->objTexts
[currPtr
->t2
].w
);
1299 glVertex3f(tDispObj
->objVerts
[currPtr
->v2
].x
, tDispObj
->objVerts
[currPtr
->v2
].y
, tDispObj
->objVerts
[currPtr
->v2
].z
);
1301 if (currPtr
->NormType
)
1302 glNormal3f(tDispObj
->objNorms
[currPtr
->n3
].x
, tDispObj
->objNorms
[currPtr
->n3
].y
, tDispObj
->objNorms
[currPtr
->n3
].z
);
1303 if (currPtr
->t3
> 0)
1304 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t3
].u
, tDispObj
->objTexts
[currPtr
->t3
].v
, tDispObj
->objTexts
[currPtr
->t3
].w
);
1305 glVertex3f(tDispObj
->objVerts
[currPtr
->v3
].x
, tDispObj
->objVerts
[currPtr
->v3
].y
, tDispObj
->objVerts
[currPtr
->v3
].z
);
1307 currPtr
= currPtr
->next
;
1312 currPtr
= tDispObj
->group
[i
].objQuads
;
1313 while (currPtr
!= NULL
)
1315 if (!currPtr
->NormType
)
1316 glNormal3f(currPtr
->faceNorm
.x
, currPtr
->faceNorm
.y
, currPtr
->faceNorm
.z
);
1318 glNormal3f(tDispObj
->objNorms
[currPtr
->n1
].x
, tDispObj
->objNorms
[currPtr
->n1
].y
, tDispObj
->objNorms
[currPtr
->n1
].z
);
1319 if (currPtr
->t1
> 0)
1320 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t1
].u
, tDispObj
->objTexts
[currPtr
->t1
].v
, tDispObj
->objTexts
[currPtr
->t1
].w
);
1321 glVertex3f(tDispObj
->objVerts
[currPtr
->v1
].x
, tDispObj
->objVerts
[currPtr
->v1
].y
, tDispObj
->objVerts
[currPtr
->v1
].z
);
1323 if (currPtr
->NormType
)
1324 glNormal3f(tDispObj
->objNorms
[currPtr
->n2
].x
, tDispObj
->objNorms
[currPtr
->n2
].y
, tDispObj
->objNorms
[currPtr
->n2
].z
);
1325 if (currPtr
->t2
> 0)
1326 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t2
].u
, tDispObj
->objTexts
[currPtr
->t2
].v
, tDispObj
->objTexts
[currPtr
->t2
].w
);
1327 glVertex3f(tDispObj
->objVerts
[currPtr
->v2
].x
, tDispObj
->objVerts
[currPtr
->v2
].y
, tDispObj
->objVerts
[currPtr
->v2
].z
);
1329 if (currPtr
->NormType
)
1330 glNormal3f(tDispObj
->objNorms
[currPtr
->n3
].x
, tDispObj
->objNorms
[currPtr
->n3
].y
, tDispObj
->objNorms
[currPtr
->n3
].z
);
1331 if (currPtr
->t3
> 0)
1332 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t3
].u
, tDispObj
->objTexts
[currPtr
->t3
].v
, tDispObj
->objTexts
[currPtr
->t3
].w
);
1333 glVertex3f(tDispObj
->objVerts
[currPtr
->v3
].x
, tDispObj
->objVerts
[currPtr
->v3
].y
, tDispObj
->objVerts
[currPtr
->v3
].z
);
1335 if (currPtr
->NormType
)
1336 glNormal3f(tDispObj
->objNorms
[currPtr
->n4
].x
, tDispObj
->objNorms
[currPtr
->n4
].y
, tDispObj
->objNorms
[currPtr
->n4
].z
);
1337 if (currPtr
->t4
> 0)
1338 glTexCoord3f(tDispObj
->objTexts
[currPtr
->t4
].u
, tDispObj
->objTexts
[currPtr
->t4
].v
, tDispObj
->objTexts
[currPtr
->t4
].w
);
1339 glVertex3f(tDispObj
->objVerts
[currPtr
->v4
].x
, tDispObj
->objVerts
[currPtr
->v4
].y
, tDispObj
->objVerts
[currPtr
->v4
].z
);
1341 currPtr
= currPtr
->next
;
1349 char* better_fgets(char *line
, int len
, FILE *in_file
)
1361 val
= getc(in_file
);
1365 if (feof(in_file
) && temp
!= line
)
1374 } while (val
!= '\r' && val
!= '\n' && --len
);