Quake II RTX doxygen  1.0 dev
material.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 #include "material.h"
20 #include "common/files.h"
21 #include "refresh/images.h"
22 #include "vk_util.h"
23 #include "shader/constants.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 
30 extern int registration_sequence;
31 
32 //
33 // CSV parsing
34 //
35 
36 #define MAX_CSV_VALUES 32
37 typedef struct CSV_values_s {
40 } CSV_values_t;
41 
42 static qerror_t getStringValue(CSV_values_t const * csv, int index, char * dest)
43 {
44  if (index >= csv->num_values)
45  return Q_ERR_FAILURE;
46  strncpy(dest, csv->values[index], MAX_QPATH);
47  return Q_ERR_SUCCESS;
48 }
49 
50 static qerror_t getFloatValue(CSV_values_t const * csv, int index, float * dest)
51 {
52  dest[0] = '\0';
53  if (index >= csv->num_values || csv->values[index][0] == '\0')
54  return Q_ERR_FAILURE;
55  *dest = atof(csv->values[index]);
56  return Q_ERR_SUCCESS;
57 }
58 
59 static qerror_t getIntValue(CSV_values_t const * csv, int index, int * dest)
60 {
61  if (index >= csv->num_values || csv->values[index][0] == '\0')
62  return Q_ERR_FAILURE;
63  *dest = atoi(csv->values[index]);
64  return Q_ERR_SUCCESS;
65 }
66 
67 static qerror_t getFlagValue(CSV_values_t const * csv, int index, uint32_t * flags, uint32_t mask)
68 {
69  if (index >= csv->num_values || csv->values[index][0] == '\0')
70  return Q_ERR_FAILURE;
71  if (atoi(csv->values[index]))
72  *flags = *flags | mask;
73  return Q_ERR_SUCCESS;
74 }
75 
76 static qerror_t parse_CSV_line(char * linebuf, CSV_values_t * csv)
77 {
78  static char delim = ',';
79 
80  char * cptr = linebuf, c;
81  int inquote = 0;
82 
83  int index = 0;
84  csv->values[index] = cptr;
85 
86  while ((c = *cptr) != '\0' && index < MAX_CSV_VALUES)
87  {
88  if (c == '"')
89  {
90  if (!inquote)
91  csv->values[index] = cptr + 1;
92  else
93  *cptr = '\0';
94  inquote = !inquote;
95  }
96  else if (c == delim && !inquote)
97  {
98  *cptr = '\0';
99  csv->values[++index] = cptr + 1;
100  }
101  cptr++;
102  }
103  csv->num_values = index + 1;
104  return Q_ERR_SUCCESS;
105 }
106 
107 //
108 // Helpers
109 //
110 
111 static size_t truncateExtension(char const * src, char * dest)
112 {
113  // remove extension if any
114  size_t len = strlen(src);
115  assert(len < MAX_QPATH);
116 
117  if (len > 4 && src[len - 4] == '.')
118  len -= 4;
119 
120  // make a copy of the name without the extension: we need to compare full names, and "skin_rgh" == "skin" is unacceptable
121  memcpy(dest, src, len);
122  dest[len] = 0;
123  return len;
124 }
125 
126 //
127 // PBR materials cache
128 //
129 typedef struct pbr_materials_table_s {
130  char filename[MAX_QPATH];
133  qboolean alpha_sorted;
136 
137 static pbr_materials_table_t pbr_materials_table = { .num_materials = 0, .num_custom_materials = 0, .alpha_sorted = qtrue };
138 
140 {
141  return &pbr_materials_table.materials[0];
142 }
143 
145 {
147 }
148 
150 {
151  return mat->flags & MATERIAL_INDEX_MASK;
152 }
153 
154 static void MAT_Reset(pbr_material_t * mat, int mat_index)
155 {
156  mat->image_diffuse = mat->image_normals = mat->image_emissive = R_NOTEXTURE;
157  mat->bump_scale = mat->specular_scale = mat->emissive_scale = 1.0f;
158  mat->rough_override = -1.0f;
159  mat->flags = mat_index;
160  assert((mat->flags & ~MATERIAL_INDEX_MASK) == 0);
161  mat->registration_sequence = 0;
162  mat->num_frames = 1;
163  mat->next_frame = mat_index;
164 }
165 
167 {
168  table->alpha_sorted = qtrue;
169  for (int i = 1; i < table->num_materials; ++i)
170  {
171  pbr_material_t const * a = &table->materials[i - 1];
172  pbr_material_t const * b = &table->materials[i];
173  int cmp = Q_strcasecmp(a->name, b->name);
174  if (cmp == 0)
175  {
176  Com_EPrintf("duplicate material names in materials table '%s'\n", table->filename);
177  return Q_ERR_FAILURE;
178  }
179  else if (cmp > 0)
180  {
181  Com_WPrintf("materials table '%s' is not sorted - fast search disabled\n", table->filename);
182  table->alpha_sorted = qfalse;
183  }
184  }
185  return Q_ERR_SUCCESS;
186 }
187 
188 //
189 // material kinds (translations between names & bit flags)
190 //
191 
192 static struct MaterialKind {
193  char const * name;
194  uint32_t flag;
195 } materialKinds[] = {
196  {"CHROME", MATERIAL_KIND_CHROME},
197  {"GLASS", MATERIAL_KIND_GLASS},
198  {"WATER", MATERIAL_KIND_WATER},
199  {"LAVA", MATERIAL_KIND_LAVA},
200  {"SKY", MATERIAL_KIND_SKY},
201  {"SLIME", MATERIAL_KIND_SLIME},
202  {"INVISIBLE", MATERIAL_KIND_INVISIBLE},
203  {"SCREEN", MATERIAL_KIND_SCREEN},
204  {"CAMERA", MATERIAL_KIND_CAMERA},
205 };
206 
207 static int nMaterialKinds = sizeof(materialKinds) / sizeof(struct MaterialKind);
208 
209 static uint32_t getMaterialKind(char const * kindname)
210 {
211  for (int i = 0; i < nMaterialKinds; ++i)
212  if (Q_stricmp(kindname, materialKinds[i].name) == 0)
213  return materialKinds[i].flag;
214  return MATERIAL_KIND_REGULAR;
215 }
216 
217 static char const * getMaterialKindName(uint32_t flag)
218 {
219  for (int i = 0; i < nMaterialKinds; ++i)
220  if ((flag & MATERIAL_KIND_MASK) == materialKinds[i].flag)
221  return materialKinds[i].name;
222  return NULL;
223 }
224 
225 //
226 // write material table to file
227 //
228 
229 static qerror_t writeMaterialsTable(char const * filename, pbr_materials_table_t const * table)
230 {
231  char path[MAX_OSPATH];
232  qhandle_t f = FS_EasyOpenFile(path, sizeof(path), FS_MODE_WRITE | FS_FLAG_TEXT, "", filename, "");
233  if (!f) {
234  Com_EPrintf("Error opening '%s'\n", path);
235  return Q_ERR_FAILURE;
236  }
237 
238  FS_FPrintf(f, "Material,Bump Scale,Roughness Override,Specular Scale,Emissive Scale,Kind,Invisible Flag,Light Flag,Correct Albedo Flag\n");
239 
240  for (int i = 0; i < table->num_materials; ++i)
241  {
242  pbr_material_t const * mat = &table->materials[i];
243 
244  FS_FPrintf(f, "%s,", mat->name);
245 
246  FS_FPrintf(f, "%g,%g,%g,%g,", mat->bump_scale, mat->rough_override, mat->specular_scale, mat->emissive_scale);
247 
248  char const * kind = getMaterialKindName(mat->flags);
249  FS_FPrintf(f, "%s,", kind ? kind : "");
250 
251  FS_FPrintf(f, "%d,", mat->flags & MATERIAL_FLAG_LIGHT ? (mat->enable_light_styles ? 1 : 2) : 0);
252  FS_FPrintf(f, "%d\n", mat->flags & MATERIAL_FLAG_CORRECT_ALBEDO ? 1 : 0);
253  }
254 
255  FS_FCloseFile(f);
256 
257  Com_Printf("Saved '%s'\n", path);
258  return Q_ERR_SUCCESS;
259 }
260 
261 static qerror_t parseMaterialsTable(char const * filename, pbr_materials_table_t * table)
262 {
263  assert(table);
264 
265  table->num_materials = 0;
266 
267  byte * buffer = NULL; ssize_t buffer_size = 0;
268  buffer_size = FS_LoadFile(filename, (void**)&buffer);
269  if (buffer == NULL)
270  {
271  Com_EPrintf("cannot load materials table '%s'\n", filename);
272  return Q_ERR_FAILURE;
273  }
274 
275  Q_concat(table->filename, sizeof(table->filename), filename, NULL);
276 
277  int currentLine = 0;
278  char const * ptr = (char const *)buffer;
279  char linebuf[MAX_QPATH * 3];
280  while (sgets(linebuf, sizeof(linebuf), &ptr))
281  {
282  // skip first line because it contains the column names
283  if (currentLine == 0 && strncmp(linebuf, "Material", 8) == 0)
284  continue;
285 
286  pbr_material_t * mat = &table->materials[table->num_materials];
287 
288  MAT_Reset(mat, table->num_materials);
289 
290  qerror_t status = Q_ERR_SUCCESS;
291  CSV_values_t csv = { 0 };
292 
293  if (parse_CSV_line(linebuf, &csv)==Q_ERR_SUCCESS)
294  {
295  if (getStringValue(&csv, 0, mat->name) == Q_ERR_SUCCESS && mat->name[0] != '\0')
296  {
297  status |= getFloatValue(&csv, 1, &mat->bump_scale);
298  status |= getFloatValue(&csv, 2, &mat->rough_override);
299  status |= getFloatValue(&csv, 3, &mat->specular_scale);
300  status |= getFloatValue(&csv, 4, &mat->emissive_scale);
301 
302  char kindname[MAX_QPATH];
303  getStringValue(&csv, 5, kindname);
304  mat->flags |= getMaterialKind(kindname);
305 
306  int light_flag = 0;
307  status |= getIntValue(&csv, 6, &light_flag);
308  if (light_flag != 0) mat->flags |= MATERIAL_FLAG_LIGHT;
309  mat->enable_light_styles = (light_flag <= 1);
310 
311  status |= getFlagValue(&csv, 7, &mat->flags, MATERIAL_FLAG_CORRECT_ALBEDO);
312  }
313  else
314  status = Q_ERR_FAILURE;
315  }
316  if (status == Q_ERR_SUCCESS)
317  {
318  ++table->num_materials;
319  }
320  else
321  {
323  Com_EPrintf("CSV error in materials table : '%s':%d", table->filename, currentLine);
324  }
325  ++currentLine;
326  }
327 
328  qerror_t status = validateMaterialsTable(table);
329 
330  Com_Printf("Loaded '%s' (fast search = %s)\n", filename, table->alpha_sorted == qtrue ? "true" : "false");
331 
332  FS_FreeFile(buffer);
333 
334  return status;
335 }
336 
337 // load materials file from Q2 FS
338 static char const * materials_filename = "materials.csv";
339 
340 // cache materials on game start
342 {
344 }
345 
346 // update materials if the file change (dev only feature)
348 {
349  pbr_materials_table_t newtable;
350 
352  * new_table = &newtable;
353 
354  if (parseMaterialsTable(materials_filename, new_table) == Q_ERR_SUCCESS)
355  {
356  if (new_table->num_materials != old_table->num_materials)
357  {
358  Com_EPrintf("Cannot reload materials table : table has different material count, please restart the game\n");
359  return Q_ERR_FAILURE;
360  }
361 
362  if (new_table->alpha_sorted != old_table->alpha_sorted)
363  {
364  Com_EPrintf("Cannot reload materials table : table has different material keys, please check your edits\n");
365  return Q_ERR_FAILURE;
366  }
367 
368  for (int i = 0; i < old_table->num_materials; ++i)
369  {
370  pbr_material_t * old_mat = &old_table->materials[i],
371  * new_mat = &new_table->materials[i];
372 
373  if (strncmp(old_mat->name, new_mat->name, MAX_QPATH) != 0)
374  {
375  Com_EPrintf("Cannot update material '%s' : incorrect name, please check your edits\n", new_mat->name);
376  continue;
377  }
378 
379  // update CSV values
380  old_mat->bump_scale = new_mat->bump_scale;
381  old_mat->rough_override = new_mat->rough_override;
382  old_mat->specular_scale = new_mat->specular_scale;
383  old_mat->emissive_scale = new_mat->emissive_scale;
384  old_mat->flags = new_mat->flags;
385  }
386  Com_Printf("Reloaded '%s' : %d materials updated\n", materials_filename, old_table->num_materials);
387  }
388  return Q_ERR_FAILURE;
389 }
390 
392 {
394 }
395 
396 
397 qerror_t MAT_RegisterPBRMaterial(pbr_material_t * mat, image_t * image_diffuse, image_t * image_normals, image_t * image_emissive)
398 {
399  if (!mat)
400  {
401  //Com_Error(ERR_FATAL, "%s: bad pbr material", __func__);
402  return Q_ERR_FAILURE;
403  }
404 
405  // already registered ?
407  return Q_ERR_SUCCESS;
408 
410 
411  mat->image_diffuse = image_diffuse;
412  mat->image_normals = image_normals;
413  mat->image_emissive = image_emissive;
414 
415  //if (mat->image_diffuse == R_NOTEXTURE)
416  // mat->flags &= ~(MATERIAL_FLAG_VALID);
417 
418  return Q_ERR_SUCCESS;
419 }
420 
422 {
423  if (!mat)
424  return;
425 
427  if (mat->image_diffuse) mat->image_diffuse->registration_sequence = registration_sequence;
428  if (mat->image_normals) mat->image_normals->registration_sequence = registration_sequence;
429  if (mat->image_emissive) mat->image_emissive->registration_sequence = registration_sequence;
430 }
431 
432 //
433 qerror_t MAT_ResetUnused()
434 {
436 
437  for (int i = 0; i < table->num_materials + table->num_custom_materials; ++i)
438  {
439  pbr_material_t * mat = table->materials;
440 
442  continue;
443 
444  if (!mat->registration_sequence)
445  continue;
446 
447  mat->image_diffuse = R_NOTEXTURE;
448  mat->image_normals = R_NOTEXTURE;
449  mat->image_emissive = R_NOTEXTURE;
450 
451  mat->registration_sequence = 0;
452  }
453  return Q_ERR_SUCCESS;
454 }
455 
456 
458 {
460  return &pbr_materials_table.materials[index];
461  return NULL;
462 }
463 
464 
466 {
467  char name_copy[MAX_QPATH];
468  int len = truncateExtension(name, name_copy);
469  assert(len>0);
470 
472 
473  // note : key comparison must be case insensitive
474 
475  int search_start = 0;
476 
477  if (table->alpha_sorted)
478  {
479  // binary search if names are sorted in alpha order
480  int left = 0, right = table->num_materials - 1;
481 
482  while (left <= right)
483  {
484  int middle = floor((left + right) / 2);
485  pbr_material_t * mat = &table->materials[middle];
486  int cmp = Q_strcasecmp(name_copy, mat->name);
487  if (cmp < 0)
488  right = middle - 1;
489  else if (cmp > 0)
490  left = middle + 1;
491  else
492  return mat;
493  }
494 
495  search_start = pbr_materials_table.num_materials;
496  }
497 
498  // brute-force search if the table is not sorted or if the material is not found in the main table
499  for (int i = search_start; i < table->num_materials + table->num_custom_materials; ++i)
500  {
501  pbr_material_t * mat = &table->materials[i];
502  if (Q_strcasecmp(mat->name, name_copy) == 0)
503  return mat;
504  }
505 
506  // not found - create a material entry
507  int index = table->num_materials + table->num_custom_materials;
508  table->num_custom_materials++;
509  pbr_material_t * mat = &table->materials[index];
510  MAT_Reset(mat, index);
511  strcpy(mat->name, name_copy);
512  Com_Printf("Created a material entry %d for unknown material %s\n", index, name_copy);
513 
514  return mat;
515 }
516 
518 {
519  pbr_material_t const * material = MAT_FindPBRMaterial(image_diffuse->name);
520  assert(material);
521 
522  if (material->image_diffuse == image_diffuse)
523  return material;
524 
525  {
526  pbr_material_t * mat = (pbr_material_t *)material;
527  //MAT_Reset(mat, MAT_GetPBRMaterialIndex(mat));
528 
529  mat->image_diffuse = image_diffuse;
530 
531  // update registration sequence of material and its textures
532  int registration_sequence = image_diffuse->registration_sequence;
533 
534  if (mat->image_normals)
535  mat->image_normals->registration_sequence = registration_sequence;
536 
537  if (mat->image_emissive)
538  mat->image_emissive->registration_sequence = registration_sequence;
539 
541  }
542  return material;
543 }
544 
545 //
546 // prints material properties on the console
547 //
548 
550 {
551  Com_Printf("{ %s\n", mat->name);
552  Com_Printf(" image_diffuse = '%s'\n", mat->image_diffuse ? mat->image_diffuse->name : "");
553  Com_Printf(" image_normals = '%s'\n", mat->image_normals ? mat->image_normals->name : "");
554  Com_Printf(" image_emissive = '%s'\n", mat->image_emissive ? mat->image_emissive->name : "");
555  Com_Printf(" bump_scale = %f,\n", mat->bump_scale);
556  Com_Printf(" rough_override = %f,\n", mat->rough_override);
557  Com_Printf(" specular_scale = %f,\n", mat->specular_scale);
558  Com_Printf(" emissive_scale = %f,\n", mat->emissive_scale);
559  char const * kind = getMaterialKindName(mat->flags);
560  Com_Printf(" kind = '%s',\n", kind ? kind : "");
561  Com_Printf(" light = %d,\n", (mat->flags & MATERIAL_FLAG_LIGHT) ? (mat->enable_light_styles ? 1 : 2) : 0);
562  Com_Printf(" correct_albedo = %d\n", (mat->flags & MATERIAL_FLAG_CORRECT_ALBEDO) != 0);
563  Com_Printf("}\n");
564 }
565 
566 //
567 // set material attribute command
568 //
569 
570 qerror_t MAT_SetPBRMaterialAttribute(pbr_material_t * mat, char const * token, char const * value)
571 {
572  assert(mat);
573 
574  // valid token-value pairs
575 
576  enum TokenType { TOKEN_BOOL, TOKEN_FLOAT, TOKEN_STRING };
577 
578  static struct Token {
579  int index;
580  char const * name;
581  enum TokenType type;
582  } tokens[] = {
583  {0, "bump_scale", TOKEN_FLOAT},
584  {1, "roughness_override", TOKEN_FLOAT},
585  {2, "specular_scale", TOKEN_FLOAT},
586  {3, "emissive_scale", TOKEN_FLOAT},
587  {4, "kind", TOKEN_STRING},
588  {5, "light_flag", TOKEN_BOOL},
589  {6, "correct_albedo_flag", TOKEN_BOOL} };
590 
591  static int ntokens = sizeof(tokens) / sizeof(struct Token);
592 
593  if (token == NULL || value == NULL)
594  goto usage;
595 
596  struct Token const * t = NULL;
597  for (int i = 0; i < ntokens; ++i)
598  {
599  if (strcmp(token, tokens[i].name) == 0)
600  t = &tokens[i];
601  }
602  if (!t)
603  {
604  Com_EPrintf("Unknown material token '%s'\n", Cmd_Argv(1));
605  goto usage;
606  }
607 
608  float fvalue = 0.f; qboolean bvalue = qfalse; char const * svalue = NULL;
609  switch (t->type)
610  {
611  case TOKEN_BOOL: bvalue = atoi(value) == 0 ? qfalse : qtrue; break;
612  case TOKEN_FLOAT: fvalue = (float)atof(value); break;
613  case TOKEN_STRING: svalue = value; break;
614  default:
615  assert("unknown PBR MAT attribute token type");
616  }
617 
618  // set material
619 
620  switch (t->index)
621  {
622  case 0: mat->bump_scale = fvalue; break;
623  case 1: mat->rough_override = fvalue; break;
624  case 2: mat->specular_scale = fvalue; break;
625  case 3: mat->emissive_scale = fvalue; break;
626  case 4: {
627  uint32_t kind = getMaterialKind(svalue);
628  if (kind != 0)
629  mat->flags = MAT_SetKind(mat->flags, kind);
630  else
631  {
632  Com_EPrintf("Unknown material kind '%s'\n", svalue);
633  return Q_ERR_FAILURE;
634  }
635  } break;
636  case 5: mat->flags = bvalue == qtrue ? mat->flags | MATERIAL_FLAG_LIGHT : mat->flags & ~(MATERIAL_FLAG_LIGHT); break;
637  case 6: mat->flags = bvalue == qtrue ? mat->flags | MATERIAL_FLAG_CORRECT_ALBEDO : mat->flags & ~(MATERIAL_FLAG_CORRECT_ALBEDO); break;
638  }
639 
640  return Q_ERR_SUCCESS;
641 
642 usage:
643  Com_Printf("Usage : set_material <token> <value>\n");
644  for (int i = 0; i < ntokens; ++i)
645  {
646  struct Token const * t = &tokens[i];
647 
648  char const * typename = "(undefined)";
649  switch (t->type)
650  {
651  case TOKEN_BOOL: typename = "bool [0,1]"; break;
652  case TOKEN_FLOAT: typename = "float"; break;
653  case TOKEN_STRING: typename = "string"; break;
654  }
655  Com_Printf(" %s (%s)\n", t->name, typename);
656  }
657  return Q_ERR_FAILURE;
658 }
659 
660 uint32_t MAT_SetKind(uint32_t material, uint32_t kind)
661 {
662  return (material & ~MATERIAL_KIND_MASK) | kind;
663 }
664 
665 qboolean MAT_IsKind(uint32_t material, uint32_t kind)
666 {
667  return (material & MATERIAL_KIND_MASK) == kind;
668 }
parse_CSV_line
static qerror_t parse_CSV_line(char *linebuf, CSV_values_t *csv)
Definition: material.c:76
getStringValue
static qerror_t getStringValue(CSV_values_t const *csv, int index, char *dest)
Definition: material.c:42
MAT_GetNumPBRMaterials
int MAT_GetNumPBRMaterials()
Definition: material.c:144
pbr_materials_table_t
struct pbr_materials_table_s pbr_materials_table_t
FS_EasyOpenFile
qhandle_t FS_EasyOpenFile(char *buf, size_t size, unsigned mode, const char *dir, const char *name, const char *ext)
Definition: files.c:1846
MATERIAL_KIND_INVALID
#define MATERIAL_KIND_INVALID
Definition: constants.h:58
pbr_materials_table_s::alpha_sorted
qboolean alpha_sorted
Definition: material.c:133
CSV_values_s
Definition: material.c:37
pbr_material_s::name
char name[MAX_QPATH]
Definition: material.h:34
MATERIAL_FLAG_CORRECT_ALBEDO
#define MATERIAL_FLAG_CORRECT_ALBEDO
Definition: constants.h:74
validateMaterialsTable
static qerror_t validateMaterialsTable(pbr_materials_table_t *table)
Definition: material.c:166
MATERIAL_KIND_LAVA
#define MATERIAL_KIND_LAVA
Definition: constants.h:62
MAT_SavePBRMaterials
qerror_t MAT_SavePBRMaterials()
Definition: material.c:391
materialKinds
static struct MaterialKind materialKinds[]
MAT_PrintMaterialProperties
void MAT_PrintMaterialProperties(pbr_material_t const *mat)
Definition: material.c:549
pbr_material_s::next_frame
int next_frame
Definition: material.h:45
materials_filename
static const char * materials_filename
Definition: material.c:338
image_t
struct image_s image_t
Definition: material.h:27
pbr_material_s::image_normals
image_t * image_normals
Definition: material.h:36
MAT_UpdateRegistration
void MAT_UpdateRegistration(pbr_material_t *mat)
Definition: material.c:421
pbr_material_s::image_emissive
image_t * image_emissive
Definition: material.h:37
pbr_material_s::flags
uint32_t flags
Definition: material.h:42
MAT_SetPBRMaterialAttribute
qerror_t MAT_SetPBRMaterialAttribute(pbr_material_t *mat, char const *token, char const *value)
Definition: material.c:570
registration_sequence
int registration_sequence
Definition: main.c:34
FS_FPrintf
ssize_t FS_FPrintf(qhandle_t f, const char *format,...)
Definition: files.c:2039
MAT_GetPBRMaterial
pbr_material_t * MAT_GetPBRMaterial(int index)
Definition: material.c:457
MATERIAL_KIND_SKY
#define MATERIAL_KIND_SKY
Definition: constants.h:65
MATERIAL_FLAG_LIGHT
#define MATERIAL_FLAG_LIGHT
Definition: constants.h:73
MAT_UpdatePBRMaterialSkin
const pbr_material_t * MAT_UpdatePBRMaterialSkin(image_t *image_diffuse)
Definition: material.c:517
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
pbr_materials_table_s::filename
char filename[MAX_QPATH]
Definition: material.c:130
MAT_RegisterPBRMaterial
qerror_t MAT_RegisterPBRMaterial(pbr_material_t *mat, image_t *image_diffuse, image_t *image_normals, image_t *image_emissive)
Definition: material.c:397
MAX_CSV_VALUES
#define MAX_CSV_VALUES
Definition: material.c:36
writeMaterialsTable
static qerror_t writeMaterialsTable(char const *filename, pbr_materials_table_t const *table)
Definition: material.c:229
getIntValue
static qerror_t getIntValue(CSV_values_t const *csv, int index, int *dest)
Definition: material.c:59
MAT_ReloadPBRMaterials
qerror_t MAT_ReloadPBRMaterials()
Definition: material.c:347
MAT_ResetUnused
qerror_t MAT_ResetUnused()
Definition: material.c:433
pbr_material_s::specular_scale
float specular_scale
Definition: material.h:40
CSV_values_t
struct CSV_values_s CSV_values_t
pbr_material_s::emissive_scale
float emissive_scale
Definition: material.h:41
pbr_material_s::bump_scale
float bump_scale
Definition: material.h:38
pbr_material_s::num_frames
int num_frames
Definition: material.h:44
material.h
pbr_material_s
Definition: material.h:33
MATERIAL_KIND_REGULAR
#define MATERIAL_KIND_REGULAR
Definition: constants.h:59
MAT_Reset
static void MAT_Reset(pbr_material_t *mat, int mat_index)
Definition: material.c:154
MATERIAL_KIND_MASK
#define MATERIAL_KIND_MASK
Definition: constants.h:57
nMaterialKinds
static int nMaterialKinds
Definition: material.c:207
MATERIAL_KIND_CHROME
#define MATERIAL_KIND_CHROME
Definition: constants.h:60
pbr_material_s::image_diffuse
image_t * image_diffuse
Definition: material.h:35
CSV_values_s::values
char * values[MAX_CSV_VALUES]
Definition: material.c:38
MAT_GetPBRMaterialsTable
const pbr_material_t * MAT_GetPBRMaterialsTable()
Definition: material.c:139
MAT_IsKind
qboolean MAT_IsKind(uint32_t material, uint32_t kind)
Definition: material.c:665
pbr_materials_table_s::materials
pbr_material_t materials[MAX_PBR_MATERIALS]
Definition: material.c:131
pbr_materials_table_s::num_custom_materials
int num_custom_materials
Definition: material.c:134
pbr_materials_table_s
Definition: material.c:129
MaterialKind
Definition: material.c:192
pbr_material_s::enable_light_styles
int enable_light_styles
Definition: material.h:46
MAX_PBR_MATERIALS
#define MAX_PBR_MATERIALS
Definition: material.h:25
Q_strcasecmp
int Q_strcasecmp(const char *s1, const char *s2)
Definition: shared.c:666
c
statCounters_t c
Definition: main.c:30
MATERIAL_KIND_CAMERA
#define MATERIAL_KIND_CAMERA
Definition: constants.h:70
MATERIAL_KIND_SLIME
#define MATERIAL_KIND_SLIME
Definition: constants.h:63
sgets
char * sgets(char *str, int num, char const **input)
Definition: vk_util.c:26
MaterialKind::name
const char * name
Definition: material.c:193
vk_util.h
right
static vec3_t right
Definition: p_view.c:27
constants.h
pbr_materials_table_s::num_materials
int num_materials
Definition: material.c:132
pbr_material_s::registration_sequence
int registration_sequence
Definition: material.h:43
MATERIAL_KIND_SCREEN
#define MATERIAL_KIND_SCREEN
Definition: constants.h:69
pbr_materials_table
static pbr_materials_table_t pbr_materials_table
Definition: material.c:137
getMaterialKindName
static const char * getMaterialKindName(uint32_t flag)
Definition: material.c:217
FS_FCloseFile
void FS_FCloseFile(qhandle_t f)
Definition: files.c:759
Q_concat
size_t Q_concat(char *dest, size_t size,...)
Definition: shared.c:758
getFlagValue
static qerror_t getFlagValue(CSV_values_t const *csv, int index, uint32_t *flags, uint32_t mask)
Definition: material.c:67
MAT_InitializePBRmaterials
qerror_t MAT_InitializePBRmaterials()
Definition: material.c:341
MATERIAL_KIND_INVISIBLE
#define MATERIAL_KIND_INVISIBLE
Definition: constants.h:66
getMaterialKind
static uint32_t getMaterialKind(char const *kindname)
Definition: material.c:209
pbr_material_s::rough_override
float rough_override
Definition: material.h:39
MATERIAL_INDEX_MASK
#define MATERIAL_INDEX_MASK
Definition: constants.h:86
MaterialKind::flag
uint32_t flag
Definition: material.c:194
truncateExtension
static size_t truncateExtension(char const *src, char *dest)
Definition: material.c:111
MATERIAL_KIND_WATER
#define MATERIAL_KIND_WATER
Definition: constants.h:61
getFloatValue
static qerror_t getFloatValue(CSV_values_t const *csv, int index, float *dest)
Definition: material.c:50
parseMaterialsTable
static qerror_t parseMaterialsTable(char const *filename, pbr_materials_table_t *table)
Definition: material.c:261
MAT_GetPBRMaterialIndex
int MAT_GetPBRMaterialIndex(pbr_material_t const *mat)
Definition: material.c:149
MAT_SetKind
uint32_t MAT_SetKind(uint32_t material, uint32_t kind)
Definition: material.c:660
CSV_values_s::num_values
int num_values
Definition: material.c:39
MAT_FindPBRMaterial
pbr_material_t * MAT_FindPBRMaterial(char const *name)
Definition: material.c:465
MATERIAL_KIND_GLASS
#define MATERIAL_KIND_GLASS
Definition: constants.h:64