1 /*
2 * Sample BMF file reader (from view3ds by David Farrell)
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <ctype.h>
7 #ifdef WIN32
8 #include <windows.h>
9 #endif
10 #include "GL/glut.h"
11 #include "bmf.h"
12 #include "ou.h"
13
14 GLubyte *read_JPEG_file(char *, int *, int *, int *);
15
16 char modelspath[100] = MODEL_DIR;
17
LoadBMF(char * filename,double radius)18 BMFObject *LoadBMF(char *filename, double radius)
19 {
20 uword MeshType;
21 SparseMesh *MaterialList;
22 StripMesh *StripMaterialList;
23 BMFObject *obj;
24 FILE *in;
25 int i, j;
26 int width, height, components;
27 GLubyte *image;
28 char s[120]; /* openuniverse */
29 double max = 0.0, d; /* openuniverse */
30
31 /* Create the new BMF object */
32 if (!(obj = (BMFObject *) malloc(sizeof(BMFObject)))) {
33 error("Can't allocate memory for BMFObject\n");
34 shutdown(1);
35 }
36
37 sprintf(s, "%s/%s", modelspath, filename);
38
39 if (!(in = fopen(s, "rb"))) {
40 sprintf(s, "Can't open file %s", filename);
41 error("Can't open file\n");
42 shutdown(1);
43 }
44 obj->texsize = 0;
45
46 /* Get number of materials */
47 fread(&obj->NumMaterials, sizeof(uword), 1, in);
48
49 /* Get mesh type */
50 fread(&MeshType, sizeof(uword), 1, in);
51
52 if (MeshType == 0) {
53 /* Sparse Triangles */
54
55 /* Allocate space for the materials */
56 if (!
57 (MaterialList =
58 (SparseMesh *) malloc(sizeof(SparseMesh) *
59 obj->NumMaterials))) {
60 error("Can't allocate memory for materials\n");
61 shutdown(1);
62 }
63 obj->sparse = MaterialList;
64 obj->strip = 0;
65
66 /* Read in each material */
67 for (i = 0; i < obj->NumMaterials; i++) {
68 /* Get the texture's name length */
69 fread(&MaterialList[i].texture_name_length, sizeof(uword), 1,
70 in);
71
72 if (MaterialList[i].texture_name_length == 0) {
73 error("Invalid texture name length\n");
74 shutdown(1);
75 }
76
77 /* Get the texture's name */
78 MaterialList[i].texture_name =
79 (char *) malloc(MaterialList[i].texture_name_length);
80 fread(MaterialList[i].texture_name,
81 MaterialList[i].texture_name_length, 1, in);
82
83 if (MaterialList[i].texture_name_length > 1) {
84
85 for (j = 0; j < MaterialList[i].texture_name_length; j++)
86 MaterialList[i].texture_name[j] =
87 (char) tolower(MaterialList[i].texture_name[j]);
88
89 image =
90 read_JPEG_file(MaterialList[i].texture_name, &width,
91 &height, &components);
92
93 if (image == NULL) {
94 sprintf(s, "reading image %s",
95 MaterialList[i].texture_name);
96 error(s);
97 shutdown(1);
98 }
99 image = texture_LOD(image, &width, &height, components);
100 if (components == 1)
101 j = 1;
102 else
103 j = color_depth / 8;
104 obj->texsize += (width * height * j);
105
106 glGenTextures(1, &MaterialList[i].texbind);
107 glBindTexture(GL_TEXTURE_2D, MaterialList[i].texbind);
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
109 GL_LINEAR);
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
111 GL_LINEAR);
112 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
113 GL_MODULATE);
114
115 glTexImage2D(GL_TEXTURE_2D,
116 0,
117 components == 3 ? cd_rgb : cd_lum,
118 width, height,
119 0,
120 components == 3 ? GL_RGB : GL_LUMINANCE,
121 GL_UNSIGNED_BYTE, image);
122 free(image);
123 }
124
125
126 /* Read in RGB colors */
127 fread(&MaterialList[i].ambient, sizeof(BMF_RGBCOLOR), 1, in);
128
129 fread(&MaterialList[i].diffuse, sizeof(BMF_RGBCOLOR), 1, in);
130
131 fread(&MaterialList[i].specular, sizeof(BMF_RGBCOLOR), 1, in);
132
133 /* Get the number of vertices */
134 fread(&MaterialList[i].number_of_vertices, sizeof(uword), 1,
135 in);
136
137 /* Allocate space for the vertex list */
138 MaterialList[i].vertexlist =
139 (BMF_UNVERTEX *) malloc(sizeof(BMF_UNVERTEX) *
140 MaterialList
141 [i].number_of_vertices);
142
143 if (MaterialList[i].vertexlist == 0) {
144 error("Error allocating memory for vertexlist\n");
145 shutdown(1);
146 }
147
148 /* Read in the vertex list */
149 fread(MaterialList[i].vertexlist,
150 sizeof(BMF_UNVERTEX),
151 MaterialList[i].number_of_vertices, in);
152
153 for (j = 0; j < MaterialList[i].number_of_vertices; j++) {
154 d = DISTANCE(MaterialList[i].vertexlist[j].x,
155 MaterialList[i].vertexlist[j].y,
156 MaterialList[i].vertexlist[j].z);
157 if (d > max)
158 max = d;
159 }
160
161
162 /* Read in the number of polygons */
163 fread(&MaterialList[i].number_of_triangles, sizeof(uword), 1,
164 in);
165
166 /* Allocate space for the index list */
167 MaterialList[i].indexlist =
168 (BMF_SURFACE *) malloc(sizeof(BMF_SURFACE) *
169 MaterialList
170 [i].number_of_triangles);
171
172 /* Read in the triangle indices */
173 fread(MaterialList[i].indexlist,
174 sizeof(BMF_SURFACE),
175 MaterialList[i].number_of_triangles, in);
176 }
177
178 /* Sorta vertex normalization */
179 for (i = 0; i < obj->NumMaterials; i++) {
180 for (j = 0; j < MaterialList[i].number_of_vertices; j++) {
181 MaterialList[i].vertexlist[j].x /= max / radius;
182 MaterialList[i].vertexlist[j].y /= max / radius;
183 MaterialList[i].vertexlist[j].z /= max / radius;
184 }
185 }
186 } else {
187 /* Triangle Strips */
188
189 /* Allocate space for the materials */
190 if (!
191 (StripMaterialList =
192 (StripMesh *) malloc(sizeof(StripMesh) *
193 obj->NumMaterials))) {
194 error("Can't allocate memory for materials\n");
195 shutdown(1);
196 }
197 obj->sparse = 0;
198 obj->strip = StripMaterialList;
199
200 /* Read in each material */
201 for (i = 0; i < obj->NumMaterials; i++) {
202 /* Get the texture's name length */
203 fread(&StripMaterialList[i].texture_name_length,
204 sizeof(uword), 1, in);
205
206 if (StripMaterialList[i].texture_name_length == 0) {
207 error("Invalid texture name length\n");
208 shutdown(1);
209 }
210
211 /* Get the texture's name */
212 StripMaterialList[i].texture_name =
213 (char *) malloc(StripMaterialList[i].texture_name_length);
214 fread(StripMaterialList[i].texture_name,
215 StripMaterialList[i].texture_name_length, 1, in);
216
217 if (StripMaterialList[i].texture_name_length > 1) {
218
219 for (j = 0; j < StripMaterialList[i].texture_name_length;
220 j++)
221 StripMaterialList[i].texture_name[j] = (char)
222 tolower(StripMaterialList[i].texture_name[j]);
223
224 image =
225 read_JPEG_file(StripMaterialList[i].texture_name,
226 &width, &height, &components);
227 if (image == NULL) {
228 sprintf(s, "error reading image %s",
229 StripMaterialList[i].texture_name);
230 error(s);
231 shutdown(1);
232 }
233 image = texture_LOD(image, &width, &height, components);
234 if (components == 1)
235 j = 1;
236 else
237 j = color_depth / 8;
238 obj->texsize += (width * height * j);
239
240 glGenTextures(1, &StripMaterialList[i].texbind);
241 glBindTexture(GL_TEXTURE_2D, StripMaterialList[i].texbind);
242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
243 GL_LINEAR);
244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
245 GL_LINEAR);
246 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
247 GL_MODULATE);
248 glTexImage2D(GL_TEXTURE_2D, 0,
249 components == 3 ? cd_rgb : cd_lum,
250 width, height, 0,
251 components == 3 ? GL_RGB : GL_LUMINANCE,
252 GL_UNSIGNED_BYTE, image);
253 free(image);
254 }
255
256 /* Read in RGB colors */
257 fread(&StripMaterialList[i].ambient, sizeof(BMF_RGBCOLOR), 1,
258 in);
259
260 fread(&StripMaterialList[i].diffuse, sizeof(BMF_RGBCOLOR), 1,
261 in);
262
263 fread(&StripMaterialList[i].specular,
264 sizeof(BMF_RGBCOLOR), 1, in);
265
266 /* Get the number of vertices */
267 fread(&StripMaterialList[i].number_of_vertices,
268 sizeof(uword), 1, in);
269
270 /* Allocate space for the vertex list */
271 StripMaterialList[i].vertexlist =
272 (BMF_UNVERTEX *) malloc(sizeof(BMF_UNVERTEX) *
273 StripMaterialList
274 [i].number_of_vertices);
275
276 if (StripMaterialList[i].vertexlist == 0) {
277 error("Error allocating memory for vertexlist\n");
278 shutdown(1);
279 }
280
281 /* Read in the vertex list */
282 fread(StripMaterialList[i].vertexlist,
283 sizeof(BMF_UNVERTEX),
284 StripMaterialList[i].number_of_vertices, in);
285
286 for (j = 0; j < StripMaterialList[i].number_of_vertices; j++) {
287 d = DISTANCE(StripMaterialList[i].vertexlist[j].x,
288 StripMaterialList[i].vertexlist[j].y,
289 StripMaterialList[i].vertexlist[j].z);
290 if (d > max)
291 max = d;
292 }
293
294
295 /* Read in the number of strips */
296 fread(&StripMaterialList[i].number_of_strips,
297 sizeof(uword), 1, in);
298
299 /* Allocate space for the strip length list */
300 StripMaterialList[i].length_of_strip =
301 (uword *) malloc(sizeof(uword) *
302 StripMaterialList[i].number_of_strips);
303
304 /* Read in the triangle strip lengths */
305 fread(StripMaterialList[i].length_of_strip,
306 sizeof(uword), StripMaterialList[i].number_of_strips,
307 in);
308
309 /* Read in the number of strip points */
310 fread(&StripMaterialList[i].number_of_strip_indices,
311 sizeof(uword), 1, in);
312
313 /* Allocate space for the strip length list */
314 StripMaterialList[i].stripindex =
315 (uword *) malloc(sizeof(uword) *
316 StripMaterialList
317 [i].number_of_strip_indices);
318
319 /* Read in the triangle strip lengths */
320 fread(StripMaterialList[i].stripindex,
321 sizeof(uword),
322 StripMaterialList[i].number_of_strip_indices, in);
323 }
324
325 /* Sorta vertex normalization */
326 for (i = 0; i < obj->NumMaterials; i++) {
327 for (j = 0; j < StripMaterialList[i].number_of_vertices; j++) {
328 StripMaterialList[i].vertexlist[j].x /= max / radius;
329 StripMaterialList[i].vertexlist[j].y /= max / radius;
330 StripMaterialList[i].vertexlist[j].z /= max / radius;
331 }
332 }
333 }
334
335 fclose(in);
336 obj->radius = radius;
337 return obj;
338 }
339