UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ufomodel.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 1997-2001 Id Software, Inc.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "../../shared/ufotypes.h"
27 #include "../../common/mem.h"
28 #include "../../shared/shared.h"
29 #include "../../common/filesys.h"
30 #include "../../shared/typedefs.h"
31 #include "../../common/mem.h"
32 #define QGL_EXTERN
33 #include "../../client/renderer/r_gl.h"
34 #include "../../client/renderer/r_material.h"
35 #include "../../client/renderer/r_image.h"
36 #include "../../client/renderer/r_model.h"
37 #include "../../client/renderer/r_state.h"
38 #include "../../shared/images.h"
39 #include "../../common/common.h"
40 #include "md2.h"
41 #include <SDL_main.h>
42 #include <cstddef>
43 
44 #define VERSION "0.2"
45 
48 
49 typedef enum {
51 
60 
61 typedef struct modelConfig_s {
62  bool overwrite;
63  bool verbose;
66  float smoothness;
69 
71 
75 memPool_t* vid_lightPool; /* compilation dependency */
77 
78 static void Exit(int exitCode) __attribute__ ((__noreturn__));
79 
80 static void Exit (int exitCode)
81 {
82  Mem_Shutdown();
83 
84  exit(exitCode);
85 }
86 
87 void Com_Printf (const char* format, ...)
88 {
89  char out_buffer[4096];
90  va_list argptr;
91 
92  va_start(argptr, format);
93  Q_vsnprintf(out_buffer, sizeof(out_buffer), format, argptr);
94  va_end(argptr);
95 
96  printf("%s", out_buffer);
97 }
98 
99 void Com_DPrintf (int level, const char* fmt, ...)
100 {
101  if (config.verbose) {
102  char outBuffer[4096];
103  va_list argptr;
104 
105  va_start(argptr, fmt);
106  Q_vsnprintf(outBuffer, sizeof(outBuffer), fmt, argptr);
107  va_end(argptr);
108 
109  Com_Printf("%s", outBuffer);
110  }
111 }
112 
113 image_t* R_LoadImageData (const char* name, const byte* pic, int width, int height, imagetype_t type)
114 {
115  image_t* image;
116  size_t len;
117 
118  len = strlen(name);
119  if (len >= sizeof(image->name))
120  Com_Error(ERR_DROP, "R_LoadImageData: \"%s\" is too long", name);
121  if (len == 0)
122  Com_Error(ERR_DROP, "R_LoadImageData: name is empty");
123 
124  image = Mem_PoolAllocType(image_t, vid_imagePool);
125  image->has_alpha = false;
126  image->type = type;
127  image->width = width;
128  image->height = height;
129 
130  Q_strncpyz(image->name, name, sizeof(image->name));
131  /* drop extension */
132  if (len >= 4 && image->name[len - 4] == '.') {
133  image->name[len - 4] = '\0';
134  Com_Printf("Image with extension: '%s'\n", name);
135  }
136 
137  return image;
138 }
139 
140 image_t* R_FindImage (const char* pname, imagetype_t type)
141 {
142  char lname[MAX_QPATH];
143  image_t* image;
144  SDL_Surface* surf;
145 
146  if (!pname || !pname[0])
147  Com_Error(ERR_FATAL, "R_FindImage: invalid name");
148 
149  /* drop extension */
150  Com_StripExtension(pname, lname, sizeof(lname));
151 
152  if ((surf = Img_LoadImage(lname))) {
153  image = R_LoadImageData(lname, (byte*)surf->pixels, surf->w, surf->h, type);
154  SDL_FreeSurface(surf);
155  } else {
156  image = nullptr;
157  }
158 
159  /* no fitting texture found */
160  if (!image) {
161  Com_Printf(" \\ - could not load skin '%s'\n", pname);
162  image = r_noTexture;
163  }
164 
165  return image;
166 }
167 
172 void Com_Error (int code, const char* fmt, ...)
173 {
174  va_list argptr;
175  static char msg[1024];
176 
177  va_start(argptr, fmt);
178  Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
179  va_end(argptr);
180 
181  fprintf(stderr, "Error: %s\n", msg);
182  Exit(1);
183 }
184 
189 static model_t* LoadModel (const char* name)
190 {
191  byte* buf;
192  int modfilelen;
193 
194  /* load the file */
195  modfilelen = FS_LoadFile(name, &buf);
196  if (!buf) {
197  Com_Printf("Could not load '%s'\n", name);
198  return nullptr;
199  }
200 
201  model_t* const mod = Mem_PoolAllocType(model_t, vid_modelPool);
202  Q_strncpyz(mod->name, name, sizeof(mod->name));
203 
204  /* call the appropriate loader */
205  switch (LittleLong(*(unsigned* ) buf)) {
206  case IDALIASHEADER:
207  /* MD2 header */
208  R_ModLoadAliasMD2Model(mod, buf, modfilelen, false);
209  break;
210 
211  case IDMD3HEADER:
212  /* MD3 header */
213  R_ModLoadAliasMD3Model(mod, buf, modfilelen);
214  break;
215 
216  default:
217  if (!Q_strcasecmp(mod->name + strlen(mod->name) - 4, ".obj"))
218  R_LoadObjModel(mod, buf, modfilelen);
219  else
220  Com_Error(ERR_FATAL, "LoadModel: unknown fileid for %s", mod->name);
221  }
222 
223  FS_FreeFile(buf);
224 
225  return mod;
226 }
227 
228 static void WriteToFile (const model_t* mod, const mAliasMesh_t* mesh, const char* fileName)
229 {
230  uint32_t version = MDX_VERSION;
231  int32_t numIndexes, numVerts;
232 
233  Com_Printf(" \\ - writing to file '%s'\n", fileName);
234 
235  ScopedFile f;
236  FS_OpenFile(fileName, &f, FILE_WRITE);
237  if (!f) {
238  Com_Printf(" \\ - can not open '%s' for writing\n", fileName);
239  return;
240  }
241 
242  FS_Write(IDMDXHEADER, strlen(IDMDXHEADER), &f);
243  version = LittleLong(version);
244  FS_Write(&version, sizeof(version), &f);
245 
246  numIndexes = LittleLong(mesh->num_tris * 3);
247  numVerts = LittleLong(mesh->num_verts);
248  FS_Write(&numVerts, sizeof(numVerts), &f);
249  FS_Write(&numIndexes, sizeof(numIndexes), &f);
250 
251  for (int i = 0; i < mesh->num_tris * 3; i++) {
252  const int32_t idx = LittleLong(mesh->indexes[i]);
253  FS_Write(&idx, sizeof(idx), &f);
254  }
255 }
256 
257 static int PrecalcNormalsAndTangents (const char* filename)
258 {
259  char mdxFileName[MAX_QPATH];
260  int cntCalculated = 0;
261 
262  Com_Printf("- model '%s'\n", filename);
263 
264  Com_StripExtension(filename, mdxFileName, sizeof(mdxFileName));
265  Q_strcat(mdxFileName, sizeof(mdxFileName), ".mdx");
266 
267  if (!config.overwrite && FS_CheckFile("%s", mdxFileName) != -1) {
268  Com_Printf(" \\ - mdx already exists\n");
269  return 0;
270  }
271 
272  model_t* mod = LoadModel(filename);
273  if (!mod)
274  Com_Error(ERR_DROP, "Could not load %s", filename);
275 
276  Com_Printf(" \\ - # meshes '%i', # frames '%i'\n", mod->alias.num_meshes, mod->alias.num_frames);
277 
278  for (int i = 0; i < mod->alias.num_meshes; i++) {
279  mAliasMesh_t* mesh = &mod->alias.meshes[i];
283  WriteToFile(mod, mesh, mdxFileName);
284 
285  cntCalculated++;
286  }
287 
288  return cntCalculated;
289 }
290 
291 static void PrecalcNormalsAndTangentsBatch (const char* pattern)
292 {
293  const char* filename;
294  int cntCalculated, cntAll;
295 
296  FS_BuildFileList(pattern);
297 
298  cntAll = cntCalculated = 0;
299 
300  while ((filename = FS_NextFileFromFileList(pattern)) != nullptr) {
301  cntAll++;
302  cntCalculated += PrecalcNormalsAndTangents(filename);
303  }
304 
305  FS_NextFileFromFileList(nullptr);
306 
307  Com_Printf("%i/%i\n", cntCalculated, cntAll);
308 }
309 
310 static void Usage (void)
311 {
312  Com_Printf("Usage:\n");
313  Com_Printf(" -mdx generate mdx files\n");
314  Com_Printf(" -skinfix fix skins for md2 models\n");
315  Com_Printf(" -glcmds remove the unused glcmds from md2 models\n");
316  Com_Printf(" -check perform general checks for all the models\n");
317  Com_Printf(" -skinedit <filename> edit skin of a model\n");
318  Com_Printf(" -skinnum <filename> edit the skin numbers of a model\n");
319  Com_Printf(" -info <filename> show model information\n");
320  Com_Printf(" -overwrite overwrite existing mdx files\n");
321  Com_Printf(" -s <float> sets the smoothness value for normal-smoothing (in the range -1.0 to 1.0)\n");
322  Com_Printf(" -f <filename> build tangentspace for the specified model file\n");
323  Com_Printf(" -v --verbose print debug messages\n");
324  Com_Printf(" -h --help show this help screen\n");
325 }
326 
327 static void UM_DefaultParameter (void)
328 {
329  config.smoothness = 0.5;
330 }
331 
335 static void UM_Parameter (int argc, char** argv)
336 {
337  int i;
338 
339  for (i = 1; i < argc; i++) {
340  if (Q_streq(argv[i], "-overwrite")) {
341  config.overwrite = true;
342  } else if (Q_streq(argv[i], "-f") && (i + 1 < argc)) {
343  Q_strncpyz(config.inputName, argv[++i], sizeof(config.inputName));
344  } else if (Q_streq(argv[i], "-s") && (i + 1 < argc)) {
345  config.smoothness = strtod(argv[++i], nullptr);
346  if (config.smoothness < -1.0 || config.smoothness > 1.0) {
347  Usage();
348  Exit(1);
349  }
350  } else if (Q_streq(argv[i], "-mdx")) {
351  config.action = ACTION_MDX;
352  } else if (Q_streq(argv[i], "-glcmds")) {
353  config.action = ACTION_GLCMDSREMOVE;
354  } else if (Q_streq(argv[i], "-skinfix")) {
355  config.action = ACTION_SKINFIX;
356  } else if (Q_streq(argv[i], "-check")) {
357  config.action = ACTION_CHECK;
358  } else if (Q_streq(argv[i], "-info")) {
359  config.action = ACTION_INFO;
360  if (i + 1 == argc) {
361  Usage();
362  Exit(1);
363  }
364  Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
365  i++;
366  } else if (Q_streq(argv[i], "-skinedit")) {
367  config.action = ACTION_SKINEDIT;
368  if (i + 1 == argc) {
369  Usage();
370  Exit(1);
371  }
372  Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
373  i++;
374  } else if (Q_streq(argv[i], "-skinnum")) {
375  config.action = ACTION_SKINNUM;
376  if (i + 1 == argc) {
377  Usage();
378  Exit(1);
379  }
380  Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
381  i++;
382  } else if (Q_streq(argv[i], "-v") || Q_streq(argv[i], "--verbose")) {
383  config.verbose = true;
384  } else if (Q_streq(argv[i], "-h") || Q_streq(argv[i], "--help")) {
385  Usage();
386  Exit(0);
387  } else {
388  Com_Printf("Parameters unknown. Try --help.\n");
389  Usage();
390  Exit(1);
391  }
392  }
393 }
394 
395 typedef void (*modelWorker_t) (const byte* buf, const char* fileName, int bufSize, void* userData);
396 
403 static void ModelWorker (modelWorker_t worker, const char* fileName, void* userData)
404 {
405  byte* buf = nullptr;
406  int modfilelen;
407 
408  /* load the file */
409  modfilelen = FS_LoadFile(fileName, &buf);
410  if (!buf)
411  Com_Error(ERR_FATAL, "%s not found", fileName);
412 
413  switch (LittleLong(*(unsigned* ) buf)) {
414  case IDALIASHEADER:
415  case IDMD3HEADER:
416  case IDBSPHEADER:
417  worker(buf, fileName, modfilelen, userData);
418  break;
419 
420  default:
421  if (!Q_strcasecmp(fileName + strlen(fileName) - 4, ".obj"))
422  worker(buf, fileName, modfilelen, userData);
423  else
424  Com_Error(ERR_DROP, "ModelWorker: unknown fileid for %s", fileName);
425  }
426 
427  FS_FreeFile(buf);
428 }
429 
430 static void MD2SkinFix (const byte* buf, const char* fileName, int bufSize, void* userData)
431 {
432  const dMD2Model_t* md2 = (const dMD2Model_t*)buf;
433  byte* model = nullptr;
434 
435  MD2HeaderCheck(md2, fileName, bufSize);
436 
437  const char* md2Path = (const char*) md2 + LittleLong(md2->ofs_skins);
438  uint32_t numSkins = LittleLong(md2->num_skins);
439 
440  for (int i = 0; i < numSkins; i++) {
441  const char* extension;
442  int errors = 0;
443  const char* name = md2Path + i * MD2_MAX_SKINNAME;
444 
445  if (name[0] != '.')
446  errors++;
447  else
448  /* skip the . to not confuse the extension extraction below */
449  name++;
450 
451  extension = Com_GetExtension(name);
452  if (extension != nullptr)
453  errors++;
454 
455  if (errors > 0) {
456  dMD2Model_t* fixedMD2;
457  char* skinPath;
458  char path[MD2_MAX_SKINNAME];
459  char pathBuf[MD2_MAX_SKINNAME];
460  const char* fixedPath;
461  if (model == nullptr) {
462  model = Mem_Dup(byte, buf, bufSize);
463  Com_Printf("model: %s\n", fileName);
464  }
465  fixedMD2 = (dMD2Model_t*)model;
466  skinPath = (char*) fixedMD2 + LittleLong(fixedMD2->ofs_skins) + i * MD2_MAX_SKINNAME;
467 
468  OBJZERO(path);
469 
470  if (extension != nullptr) {
471  Com_StripExtension(name, pathBuf, sizeof(pathBuf));
472  fixedPath = pathBuf;
473  } else {
474  fixedPath = name;
475  }
476  if (name[0] != '.')
477  Com_sprintf(path, sizeof(path), ".%s", Com_SkipPath(fixedPath));
478  Com_Printf(" \\ - skin %i: changed path to '%s'\n", i + 1, path);
479  if (R_AliasModelGetSkin(fileName, path) == r_noTexture) {
480  Com_Printf(" \\ - could not load the skin with the new path\n");
481  } else {
482  memcpy(skinPath, path, sizeof(path));
483  }
484  }
485  }
486  if (model != nullptr) {
487  FS_WriteFile(model, bufSize, fileName);
488  Mem_Free(model);
489  }
490 }
491 
492 static void MD2Check (const byte* buf, const char* fileName, int bufSize, void* userData)
493 {
494  bool headline = false;
495  const dMD2Model_t* md2 = (const dMD2Model_t*)buf;
496 
497  MD2HeaderCheck(md2, fileName, bufSize);
498 
499  const char* md2Path = (const char*) md2 + LittleLong(md2->ofs_skins);
500  uint32_t numSkins = LittleLong(md2->num_skins);
501 
502  for (int i = 0; i < numSkins; i++) {
503  const char* extension;
504  int errors = 0;
505  const char* name = md2Path + i * MD2_MAX_SKINNAME;
506 
507  if (name[0] != '.')
508  errors++;
509  else
510  /* skip the . to not confuse the extension extraction below */
511  name++;
512 
513  extension = Com_GetExtension(name);
514  if (extension != nullptr)
515  errors++;
516 
517  if (errors > 0) {
518  if (!headline) {
519  Com_Printf("model: %s\n", fileName);
520  headline = true;
521  }
522  Com_Printf(" \\ - skin %i: %s - %i errors/warnings\n", i + 1, name, errors);
523  if (name[0] != '.')
524  Com_Printf(" \\ - skin contains full path\n");
525  if (extension != nullptr)
526  Com_Printf(" \\ - skin contains extension '%s'\n", extension);
527  if (R_AliasModelGetSkin(fileName, md2Path + i * MD2_MAX_SKINNAME) == r_noTexture)
528  Com_Printf(" \\ - could not load the skin\n");
529  }
530  }
531 }
532 
533 static void MD2Visitor (modelWorker_t worker, void* userData)
534 {
535  const char* fileName;
536  const char* pattern = "**.md2";
537 
538  FS_BuildFileList(pattern);
539 
540  while ((fileName = FS_NextFileFromFileList(pattern)) != nullptr)
541  ModelWorker(worker, fileName, userData);
542 
543  FS_NextFileFromFileList(nullptr);
544 }
545 
546 static void ModelCheck (void)
547 {
548  MD2Visitor(MD2Check, nullptr);
549 }
550 
551 static void SkinFix (void)
552 {
553  MD2Visitor(MD2SkinFix, nullptr);
554 }
555 
556 static void GLCmdsRemove (void)
557 {
558  size_t bytes = 0;
559  MD2Visitor(MD2GLCmdsRemove, &bytes);
560  Com_Printf("Saved " UFO_SIZE_T "bytes after removing all glcmds from the md2 files\n", bytes);
561 }
562 
564 {
565  /* TODO: check if stub without code would be sufficient here */
566  if (size <= r_state.array_size)
567  return;
568  r_state.vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.vertex_array_3d, size * 3 * sizeof(GLfloat));
569  r_state.vertex_array_2d = (GLshort*) Mem_SafeReAlloc(r_state.vertex_array_2d, size * 2 * sizeof(GLshort));
570  r_state.color_array = (GLfloat*) Mem_SafeReAlloc(r_state.color_array, size * 4 * sizeof(GLfloat));
571  r_state.normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.normal_array, size * 3 * sizeof(GLfloat));
572  r_state.tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.tangent_array, size * 4 * sizeof(GLfloat));
573  r_state.next_vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.next_vertex_array_3d, size * 3 * sizeof(GLfloat));
574  r_state.next_normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_normal_array, size * 3 * sizeof(GLfloat));
575  r_state.next_tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_tangent_array, size * 4 * sizeof(GLfloat));
576  r_state.array_size = size;
577 }
578 
580 {
581  /* TODO: check if stub without code would be sufficient here */
582  if (size <= texunit->array_size)
583  return;
584  texunit->texcoord_array = (GLfloat*) Mem_SafeReAlloc(texunit->texcoord_array, size * 2 * sizeof(GLfloat));
585  texunit->array_size = size;
586  if (!r_state.active_texunit)
587  r_state.active_texunit = texunit;
588 }
589 
590 int main (int argc, char** argv)
591 {
592  Com_Printf("---- ufomodel " VERSION " ----\n");
593 
595  UM_Parameter(argc, argv);
596 
597  if (config.action == ACTION_NONE) {
598  Usage();
599  Exit(1);
600  }
601 
602  com_genericPool = Mem_CreatePool("ufomodel");
603  com_fileSysPool = Mem_CreatePool("ufomodel filesys");
604  vid_modelPool = Mem_CreatePool("ufomodel model");
605  vid_imagePool = Mem_CreatePool("ufomodel image");
606 
607  Swap_Init();
608  Mem_Init();
609 
610  FS_InitFilesystem(false);
611 
612  r_noTexture = Mem_PoolAllocType(image_t, vid_imagePool);
613  Q_strncpyz(r_noTexture->name, "noTexture", sizeof(r_noTexture->name));
614 
615  switch (config.action) {
616  case ACTION_MDX:
617  if (config.inputName[0] == '\0') {
621  /*PrecalcNormalsAndTangentsBatch("**.obj");*/
622  } else {
624  }
625  break;
626 
627  case ACTION_SKINEDIT:
628  ModelWorker(MD2SkinEdit, config.fileName, nullptr);
629  break;
630 
631  case ACTION_SKINNUM:
632  ModelWorker(MD2SkinNum, config.fileName, nullptr);
633  break;
634 
635  case ACTION_INFO:
636  ModelWorker(MD2Info, config.fileName, nullptr);
637  break;
638 
639  case ACTION_CHECK:
640  ModelCheck();
641  break;
642 
643  case ACTION_SKINFIX:
644  SkinFix();
645  break;
646 
647  case ACTION_GLCMDSREMOVE:
648  GLCmdsRemove();
649  break;
650 
651  default:
652  Exit(1);
653  }
654 
655  Mem_Shutdown();
656 
657  return 0;
658 }
memPool_t * vid_imagePool
Definition: ufomodel.cpp:76
static void UM_Parameter(int argc, char **argv)
Parameter parsing.
Definition: ufomodel.cpp:335
memPool_t * com_fileSysPool
Definition: ufomodel.cpp:73
#define IDALIASHEADER
Definition: qfiles.h:40
const char * FS_NextFileFromFileList(const char *files)
Returns the next file that is found in the virtual filesystem identified by the given file pattern...
Definition: files.cpp:1079
static void ModelCheck(void)
Definition: ufomodel.cpp:546
uint32_t num_skins
Definition: qfiles.h:121
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition: shared.cpp:535
mAliasModel_t alias
Definition: r_model.h:63
void MD2SkinEdit(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: md2.cpp:39
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition: files.cpp:298
static void PrecalcNormalsAndTangentsBatch(const char *pattern)
Definition: ufomodel.cpp:291
char inputName[MAX_QPATH]
Definition: ufomodel.cpp:67
image_t * r_noTexture
Definition: ufomodel.cpp:47
QGL_EXTERN GLint GLenum type
Definition: r_gl.h:94
imagetype_t
Definition: r_image.h:41
void Mem_Shutdown(void)
Definition: mem.cpp:603
rstate_t r_state
Definition: ufomodel.cpp:46
image_t * R_AliasModelGetSkin(const char *modelFileName, const char *skin)
const char * Com_SkipPath(const char *pathname)
Returns just the filename from a given path.
Definition: shared.cpp:37
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition: files.cpp:162
void R_LoadObjModel(model_t *mod, byte *buffer, int bufSize)
const char * Com_GetExtension(const char *path)
Definition: shared.cpp:282
int32_t * indexes
void Swap_Init(void)
Definition: byte.cpp:31
void Com_Printf(const char *format,...)
Definition: ufomodel.cpp:87
#define VERSION
Definition: ufomodel.cpp:44
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
void Com_StripExtension(const char *in, char *out, const size_t size)
Removes the file extension from a filename.
Definition: shared.cpp:259
GLfloat * vertex_array_3d
Definition: r_state.h:100
const char * filename
Definition: ioapi.h:41
ufoModelAction_t
Definition: ufomodel.cpp:49
int array_size
Definition: r_state.h:55
GLfloat * normal_array
Definition: r_state.h:104
int main(int argc, char **argv)
Definition: ufomodel.cpp:590
#define IDMDXHEADER
Definition: qfiles.h:33
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition: files.cpp:384
#define MD2_MAX_SKINNAME
Definition: qfiles.h:49
void MD2SkinNum(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: md2.cpp:120
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition: ufomodel.cpp:563
int FS_BuildFileList(const char *fileList)
Build a filelist.
Definition: files.cpp:960
int width
Definition: r_image.h:64
#define __attribute__(x)
Definition: cxx.h:37
voidpf void * buf
Definition: ioapi.h:42
#define ERR_FATAL
Definition: common.h:210
GLshort * vertex_array_2d
Definition: r_state.h:101
void MD2Info(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: md2.cpp:71
ufoModelAction_t action
Definition: ufomodel.cpp:65
#define Mem_SafeReAlloc(ptr, size)
Definition: mem.h:45
GLfloat * tangent_array
Definition: r_state.h:105
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
imagetype_t type
Definition: r_image.h:63
#define ERR_DROP
Definition: common.h:211
gltexunit_t * active_texunit
Definition: r_state.h:117
GLsizei size
Definition: r_gl.h:152
#define IDMD3HEADER
Definition: qfiles.h:159
#define OBJZERO(obj)
Definition: shared.h:178
char name[MAX_QPATH]
Definition: r_image.h:62
void Com_Error(int code, const char *fmt,...)
Definition: ufomodel.cpp:172
static void GLCmdsRemove(void)
Definition: ufomodel.cpp:556
static void UM_DefaultParameter(void)
Definition: ufomodel.cpp:327
static model_t * LoadModel(const char *name)
Loads in a model for the given name.
Definition: ufomodel.cpp:189
void R_ModCalcUniqueNormalsAndTangents(mAliasMesh_t *mesh, int nFrames, float smoothness)
Calculates normals and tangents for all frames and does vertex merging based on smoothness.
static void WriteToFile(const model_t *mod, const mAliasMesh_t *mesh, const char *fileName)
Definition: ufomodel.cpp:228
memPool_t * com_genericPool
Definition: ufomodel.cpp:72
bool overwrite
Definition: ufomodel.cpp:62
void R_ReallocateTexunitArray(gltexunit_t *texunit, int size)
Reallocate texcoord array of the specified texunit, if needed.
Definition: ufomodel.cpp:579
uint32_t ofs_skins
Definition: qfiles.h:128
int array_size
Definition: r_state.h:111
texunits maintain multitexture state
Definition: r_state.h:48
static void Exit(int exitCode) __attribute__((__noreturn__))
Definition: ufomodel.cpp:80
void FS_InitFilesystem(bool writeToHomeDir)
Definition: files.cpp:888
GLfloat * next_vertex_array_3d
Definition: r_state.h:106
SDL_Surface * Img_LoadImage(char const *name)
Loads the specified image from the game filesystem and populates the provided SDL_Surface.
Definition: images.cpp:435
#define Mem_CreatePool(name)
Definition: mem.h:32
char name[MAX_QPATH]
Definition: r_model.h:44
int FS_WriteFile(const void *buffer, size_t len, const char *filename)
Definition: files.cpp:1544
static modelConfig_t config
Definition: ufomodel.cpp:70
void R_ModLoadAliasMD2Model(model_t *mod, byte *buffer, int bufSize, bool loadNormals)
Load MD2 models from file.
#define Q_strcasecmp(a, b)
Definition: shared.h:131
void MD2GLCmdsRemove(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: md2.cpp:213
#define MDX_VERSION
Definition: qfiles.h:34
void Com_DPrintf(int level, const char *fmt,...)
Definition: ufomodel.cpp:99
float smoothness
Definition: ufomodel.cpp:66
static void MD2Visitor(modelWorker_t worker, void *userData)
Definition: ufomodel.cpp:533
static void ModelWorker(modelWorker_t worker, const char *fileName, void *userData)
The caller has to ensure that the model is from the expected format.
Definition: ufomodel.cpp:403
void R_ModLoadAliasMD3Model(model_t *mod, byte *buffer, int bufSize)
Load MD3 models from file.
Definition: r_model_md3.cpp:38
const GLuint *typedef void(APIENTRY *GenRenderbuffersEXT_t)(GLsizei
Definition: r_gl.h:189
struct modelConfig_s modelConfig_t
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
mAliasMesh_t * meshes
memPool_t * vid_lightPool
Definition: ufomodel.cpp:75
the glcmd format: a positive integer starts a tristrip command, followed by that many vertex structur...
Definition: qfiles.h:109
image_t * R_LoadImageData(const char *name, const byte *pic, int width, int height, imagetype_t type)
Creates a new image from RGBA data. Stores it in the gltextures array and also uploads it...
Definition: ufomodel.cpp:113
#define MAX_QPATH
Definition: filesys.h:40
QGL_EXTERN GLint i
Definition: r_gl.h:113
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
void Mem_Init(void)
Definition: mem.cpp:588
void MD2HeaderCheck(const dMD2Model_t *md2, const char *fileName, int bufSize)
Definition: md2.cpp:11
static int PrecalcNormalsAndTangents(const char *filename)
Definition: ufomodel.cpp:257
static void Usage(void)
Definition: ufomodel.cpp:310
static void MD2Check(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: ufomodel.cpp:492
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
int height
Definition: r_image.h:64
static void SkinFix(void)
Definition: ufomodel.cpp:551
#define Mem_Free(ptr)
Definition: mem.h:35
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition: shared.cpp:475
#define IDBSPHEADER
Definition: qfiles.h:251
GLfloat * next_normal_array
Definition: r_state.h:107
#define UFO_SIZE_T
Definition: ufotypes.h:89
GLfloat * color_array
Definition: r_state.h:102
bool has_alpha
Definition: r_image.h:67
#define Q_streq(a, b)
Definition: shared.h:136
int32_t num_verts
GLfloat * next_tangent_array
Definition: r_state.h:108
#define Mem_PoolAllocType(type, pool)
Definition: mem.h:43
static void MD2SkinFix(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: ufomodel.cpp:430
uint8_t byte
Definition: ufotypes.h:34
QGL_EXTERN GLuint GLsizei bufSize
Definition: r_gl.h:110
char fileName[MAX_QPATH]
Definition: ufomodel.cpp:64
#define Mem_Dup(type, in, n)
Definition: mem.h:47
image_t * R_FindImage(const char *pname, imagetype_t type)
Finds or loads the given image.
Definition: ufomodel.cpp:140
void(* modelWorker_t)(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition: ufomodel.cpp:395
memPool_t * vid_modelPool
Definition: ufomodel.cpp:74
void format(__printf__, 1, 2)))
level_locals_t level
Definition: g_main.cpp:38
void FS_FreeFile(void *buffer)
Definition: files.cpp:411
#define LittleLong(X)
Definition: byte.h:37
GLfloat * texcoord_array
Definition: r_state.h:53
int FS_Write(const void *buffer, int len, qFILE *f)
Properly handles partial writes.
Definition: files.cpp:1511