DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
model_shared.c File Reference
#include "quakedef.h"
#include "image.h"
#include "r_shadow.h"
#include "polygon.h"
+ Include dependency graph for model_shared.c:

Go to the source code of this file.

Data Structures

struct  lightmaplight_t
 
struct  lightmapsample_t
 
struct  lightmaptriangle_t
 
struct  lightmapvertex_t
 
struct  Mod_MakeSortedSurfaces_qsortsurface_t
 
struct  q3shader_data_t
 
struct  q3shader_hash_entry_t
 

Macros

#define LM_DIST_EPSILON   (1.0f / 32.0f)
 
#define MAX_LIGHTMAPSAMPLES   64
 
#define Q3SHADER_HASH_SIZE   1021
 

Typedefs

typedef void(* mod_framegroupify_parsegroups_t) (unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
 

Functions

qbool Mod_AllocLightmap_Block (mod_alloclightmap_state_t *state, int blockwidth, int blockheight, int *outx, int *outy)
 
void Mod_AllocLightmap_Free (mod_alloclightmap_state_t *state)
 
void Mod_AllocLightmap_Init (mod_alloclightmap_state_t *state, mempool_t *mempool, int width, int height)
 
void Mod_AllocLightmap_Reset (mod_alloclightmap_state_t *state)
 
void Mod_AllocSurfMesh (mempool_t *mempool, int numvertices, int numtriangles, qbool lightmapoffsets, qbool vertexcolors)
 
void Mod_BuildNormals (int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qbool areaweighting)
 
void Mod_BuildTextureVectorsFromNormals (int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qbool areaweighting)
 
void Mod_BuildVBOs (void)
 
int Mod_BuildVertexRemapTableFromElements (int numelements, const int *elements, int numvertices, int *remapvertices)
 
void Mod_ClearUsed (void)
 
int Mod_CountSkinFiles (skinfile_t *skinfile)
 
void Mod_CreateCollisionMesh (model_t *mod)
 
texture_shaderpass_tMod_CreateShaderPass (mempool_t *mempool, skinframe_t *skinframe)
 
texture_shaderpass_tMod_CreateShaderPassFromQ3ShaderLayer (mempool_t *mempool, const char *modelname, q3shaderinfo_layer_t *layer, int layerindex, int texflags, const char *texturename)
 
static void Mod_Decompile_f (cmd_state_t *cmd)
 
static void Mod_Decompile_OBJ (model_t *model, const char *filename, const char *mtlfilename, const char *originalfilename)
 
static void Mod_Decompile_SMD (model_t *model, const char *filename, int firstpose, int numposes, qbool writetriangles)
 
model_tMod_FindName (const char *name, const char *parentname)
 
static void Mod_FindPotentialDeforms (model_t *mod)
 
model_tMod_ForName (const char *name, qbool crash, qbool checkdisk, const char *parentname)
 
static void Mod_FrameGroupify (model_t *mod, const char *buf)
 
static int Mod_FrameGroupify_ParseGroups (const char *buf, mod_framegroupify_parsegroups_t cb, void *pass)
 
static void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
 
void Mod_FreeQ3Shaders (void)
 
void Mod_FreeSkinFiles (skinfile_t *skinfile)
 
static void Mod_GenerateLightmaps (model_t *model)
 
static void Mod_GenerateLightmaps_CreateLightmaps (model_t *model)
 
static void Mod_GenerateLightmaps_CreateLights (model_t *model)
 
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP (model_t *model, lightmaplight_t *lightinfo)
 
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces (const model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
 
static void Mod_GenerateLightmaps_CreateTriangleInformation (model_t *model)
 
static void Mod_GenerateLightmaps_DestroyLightmaps (model_t *model)
 
static void Mod_GenerateLightmaps_DestroyLights (model_t *model)
 
static void Mod_GenerateLightmaps_DestroyTriangleInformation (model_t *model)
 
static void Mod_GenerateLightmaps_f (cmd_state_t *cmd)
 
static void Mod_GenerateLightmaps_GridSample (const float *pos, q3dlightgrid_t *s)
 
static void Mod_GenerateLightmaps_InitSampleOffsets (model_t *model)
 
static void Mod_GenerateLightmaps_LightmapSample (const float *pos, const float *normal, unsigned char *lm_bgr, unsigned char *lm_dir)
 
static void Mod_GenerateLightmaps_LightPoint (model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
 
static void Mod_GenerateLightmaps_SamplePoint (const float *pos, const float *normal, float *sample, int numoffsets, const float *offsets)
 
static qbool Mod_GenerateLightmaps_SamplePoint_SVBSP (const svbsp_t *svbsp, const float *pos)
 
static void Mod_GenerateLightmaps_UnweldTriangles (model_t *model)
 
static void Mod_GenerateLightmaps_UpdateLightGrid (model_t *model)
 
static void Mod_GenerateLightmaps_UpdateVertexColors (model_t *model)
 
static void Mod_GenerateLightmaps_VertexSample (const float *pos, const float *normal, float *vertex_color)
 
void Mod_Init (void)
 
void Mod_LoadCustomMaterial (mempool_t *mempool, texture_t *texture, const char *name, int supercontents, int materialflags, skinframe_t *skinframe)
 
model_tMod_LoadModel (model_t *mod, qbool crash, qbool checkdisk)
 
void Mod_LoadQ3Shaders (void)
 
static int Mod_LoadQ3Shaders_EnumerateWaveFunc (const char *s)
 
skinfile_tMod_LoadSkinFiles (void)
 
qbool Mod_LoadTextureFromQ3Shader (mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qbool warnmissing, qbool fallback, int defaulttexflags, int defaultmaterialflags)
 
shader_tMod_LookupQ3Shader (const char *name)
 
void Mod_MakeSortedSurfaces (model_t *mod)
 
static int Mod_MakeSortedSurfaces_qsortfunc (const void *a, const void *b)
 
msurface_tMod_Mesh_AddSurface (model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
 
void Mod_Mesh_AddTriangle (model_t *mod, msurface_t *surf, int e0, int e1, int e2)
 
static void Mod_Mesh_ComputeBounds (model_t *mod)
 
void Mod_Mesh_Create (model_t *mod, const char *name)
 
void Mod_Mesh_Destroy (model_t *mod)
 
void Mod_Mesh_Finalize (model_t *mod)
 
texture_tMod_Mesh_GetTexture (model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
 
int Mod_Mesh_IndexForVertex (model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
 
static void Mod_Mesh_MakeSortedSurfaces (model_t *mod)
 
void Mod_Mesh_Reset (model_t *mod)
 
static void Mod_Mesh_UploadDynamicBuffers (model_t *mod)
 
void Mod_Mesh_Validate (model_t *mod)
 
static void mod_newmap (void)
 
static void Mod_Precache_f (cmd_state_t *cmd)
 
static void Mod_Print_f (cmd_state_t *cmd)
 
void Mod_PurgeUnused (void)
 
void Mod_Reload (void)
 
int Mod_RemoveDegenerateTriangles (int numtriangles, const int *inelement3i, int *outelement3i, const float *vertex3f)
 
void Mod_RenderInit (void)
 
void Mod_SetDrawSkyAndWater (model_t *mod)
 Sets the mod->DrawSky and mod->DrawAddWaterPlanes pointers conditionally based on whether surfaces in this submodel use these features called specifically by brush model loaders when generating submodels automatically called after model loader returns.
 
void Mod_ShadowMesh_AddMesh (shadowmesh_t *mesh, const float *vertex3f, int numtris, const int *element3i)
 
int Mod_ShadowMesh_AddVertex (shadowmesh_t *mesh, const float *vertex3f)
 
shadowmesh_tMod_ShadowMesh_Alloc (mempool_t *mempool, int maxverts, int maxtriangles)
 
shadowmesh_tMod_ShadowMesh_Begin (mempool_t *mempool, int maxverts, int maxtriangles)
 
void Mod_ShadowMesh_CalcBBox (shadowmesh_t *mesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius)
 
static void Mod_ShadowMesh_CreateVBOs (shadowmesh_t *mesh)
 
shadowmesh_tMod_ShadowMesh_Finish (shadowmesh_t *mesh, qbool createvbo)
 
void Mod_ShadowMesh_Free (shadowmesh_t *mesh)
 
static void mod_shutdown (void)
 
void Mod_SnapVertices (int numcomponents, int numvertices, float *vertices, float snap)
 
static void mod_start (void)
 
void Mod_UnloadCustomMaterial (texture_t *texture, qbool purgeskins)
 Removes all shaderpasses from material, and optionally deletes the textures in the skinframes.
 
void Mod_UnloadModel (model_t *mod)
 
qbool Mod_ValidateElements (int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline)
 
void Mod_VertexRangeFromElements (int numelements, const int *elements, int *firstvertexpointer, int *lastvertexpointer)
 
static void Q3Shader_AddToHash (shader_t *shader)
 
static void R_Model_Null_Draw (entity_render_t *ent)
 

Variables

float lmaxis [3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
 
static modloader_t loader []
 
model_tloadmodel
 
unsigned char * mod_base
 
cvar_t mod_generatelightmaps_borderpixels = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_borderpixels", "2", "extra space around polygons to prevent sampling artifacts"}
 
cvar_t mod_generatelightmaps_gridradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"}
 
cvar_t mod_generatelightmaps_gridsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridsamples", "64", "number of shadow tests done per lightgrid cell"}
 
static lightmaplight_tmod_generatelightmaps_lightinfo
 
cvar_t mod_generatelightmaps_lightmapradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapradius", "16", "sampling area around each lightmap pixel"}
 
cvar_t mod_generatelightmaps_lightmapsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapsamples", "16", "number of shadow tests done per lightmap pixel"}
 
lightmaptriangle_tmod_generatelightmaps_lightmaptriangles
 
static int mod_generatelightmaps_numlights
 
static int mod_generatelightmaps_numoffsets [3]
 
static float mod_generatelightmaps_offsets [3][MAX_LIGHTMAPSAMPLES][3]
 
cvar_t mod_generatelightmaps_texturesize = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_texturesize", "1024", "size of lightmap textures"}
 
cvar_t mod_generatelightmaps_unitspersample = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"}
 
cvar_t mod_generatelightmaps_vertexradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"}
 
cvar_t mod_generatelightmaps_vertexsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexsamples", "16", "number of shadow tests done per vertex"}
 
static mempool_tmod_mempool
 
cvar_t mod_obj_orientation
 
cvar_t mod_q3bsp_nolightmaps
 
static memexpandablearray_t models
 
static q3shader_data_tq3shader_data
 
static mempool_tq3shaders_mem
 
cvar_t r_mipnormalmaps = {CF_CLIENT | CF_ARCHIVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"}
 
cvar_t r_mipskins = {CF_CLIENT | CF_ARCHIVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"}
 
cvar_t r_shadow_lightattenuationdividebias
 
cvar_t r_shadow_lightattenuationlinearscale
 
qbool vid_opened
 

Macro Definition Documentation

◆ LM_DIST_EPSILON

#define LM_DIST_EPSILON   (1.0f / 32.0f)

◆ MAX_LIGHTMAPSAMPLES

#define MAX_LIGHTMAPSAMPLES   64

Definition at line 3572 of file model_shared.c.

Referenced by Mod_GenerateLightmaps_InitSampleOffsets().

◆ Q3SHADER_HASH_SIZE

#define Q3SHADER_HASH_SIZE   1021

Definition at line 76 of file model_shared.c.

Referenced by Mod_LookupQ3Shader(), and Q3Shader_AddToHash().

Typedef Documentation

◆ mod_framegroupify_parsegroups_t

typedef void(* mod_framegroupify_parsegroups_t) (unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)

Definition at line 261 of file model_shared.c.

Function Documentation

◆ Mod_AllocLightmap_Block()

qbool Mod_AllocLightmap_Block ( mod_alloclightmap_state_t * state,
int blockwidth,
int blockheight,
int * outx,
int * outy )

Definition at line 3482 of file model_shared.c.

3483{
3485 int y;
3486
3487 row = state->rows + blockheight;
3488 if ((row->rowY < 0) || (row->currentX + blockwidth > state->width))
3489 {
3490 if (state->currentY + blockheight <= state->height)
3491 {
3492 // use the current allocation position
3493 row->rowY = state->currentY;
3494 row->currentX = 0;
3495 state->currentY += blockheight;
3496 }
3497 else
3498 {
3499 // find another position
3500 for (y = blockheight;y < state->height;y++)
3501 {
3502 if ((state->rows[y].rowY >= 0) && (state->rows[y].currentX + blockwidth <= state->width))
3503 {
3504 row = state->rows + y;
3505 break;
3506 }
3507 }
3508 if (y == state->height)
3509 return false;
3510 }
3511 }
3512 *outy = row->rowY;
3513 *outx = row->currentX;
3514 row->currentX += blockwidth;
3515
3516 return true;
3517}
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622
GLint GLenum GLint GLint y
Definition glquake.h:651
mod_alloclightmap_row_t * rows

References mod_alloclightmap_row_t::currentX, mod_alloclightmap_state_t::currentY, height, mod_alloclightmap_state_t::height, mod_alloclightmap_state_t::rows, mod_alloclightmap_row_t::rowY, mod_alloclightmap_state_t::width, width, and y.

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), Mod_Q1BSP_LoadFaces(), Mod_VBSP_LoadFaces(), and R_Shadow_PrepareLights().

◆ Mod_AllocLightmap_Free()

void Mod_AllocLightmap_Free ( mod_alloclightmap_state_t * state)

Definition at line 3475 of file model_shared.c.

3476{
3477 if (state->rows)
3478 Mem_Free(state->rows);
3479 memset(state, 0, sizeof(*state));
3480}
#define Mem_Free(mem)
Definition zone.h:96

References Mem_Free, and mod_alloclightmap_state_t::rows.

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), and R_Shadow_FreeShadowMaps().

◆ Mod_AllocLightmap_Init()

void Mod_AllocLightmap_Init ( mod_alloclightmap_state_t * state,
mempool_t * mempool,
int width,
int height )

Definition at line 3449 of file model_shared.c.

3450{
3451 int y;
3452 memset(state, 0, sizeof(*state));
3453 state->width = width;
3454 state->height = height;
3455 state->currentY = 0;
3456 state->rows = (mod_alloclightmap_row_t *)Mem_Alloc(mempool, state->height * sizeof(*state->rows));
3457 for (y = 0;y < state->height;y++)
3458 {
3459 state->rows[y].currentX = 0;
3460 state->rows[y].rowY = -1;
3461 }
3462}
#define Mem_Alloc(pool, size)
Definition zone.h:92

References mod_alloclightmap_row_t::currentX, mod_alloclightmap_state_t::currentY, height, mod_alloclightmap_state_t::height, Mem_Alloc, mod_alloclightmap_state_t::rows, mod_alloclightmap_row_t::rowY, mod_alloclightmap_state_t::width, width, and y.

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), Mod_Q1BSP_LoadFaces(), Mod_VBSP_LoadFaces(), and R_Shadow_SetShadowMode().

◆ Mod_AllocLightmap_Reset()

void Mod_AllocLightmap_Reset ( mod_alloclightmap_state_t * state)

◆ Mod_AllocSurfMesh()

void Mod_AllocSurfMesh ( mempool_t * mempool,
int numvertices,
int numtriangles,
qbool lightmapoffsets,
qbool vertexcolors )

Definition at line 973 of file model_shared.c.

974{
975 unsigned char *data;
976 data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0));
977 loadmodel->surfmesh.num_vertices = numvertices;
978 loadmodel->surfmesh.num_triangles = numtriangles;
980 {
981 loadmodel->surfmesh.data_vertex3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
982 loadmodel->surfmesh.data_svector3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
983 loadmodel->surfmesh.data_tvector3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
984 loadmodel->surfmesh.data_normal3f = (float *)data, data += sizeof(float[3]) * loadmodel->surfmesh.num_vertices;
987 if (vertexcolors)
989 if (lightmapoffsets)
991 }
993 {
995 if (loadmodel->surfmesh.num_vertices <= 65536)
996 loadmodel->surfmesh.data_element3s = (unsigned short *)data, data += sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles;
997 }
998}
GLsizeiptr const GLvoid * data
Definition glquake.h:639
model_t * loadmodel
surfmesh_t surfmesh
float * data_lightmapcolor4f
float * data_svector3f
int * data_element3i
unsigned short * data_element3s
float * data_vertex3f
float * data_tvector3f
int * data_lightmapoffsets
int num_triangles
float * data_texcoordtexture2f
float * data_normal3f
float * data_texcoordlightmap2f

References data, surfmesh_t::data_element3i, surfmesh_t::data_element3s, surfmesh_t::data_lightmapcolor4f, surfmesh_t::data_lightmapoffsets, surfmesh_t::data_normal3f, surfmesh_t::data_svector3f, surfmesh_t::data_texcoordlightmap2f, surfmesh_t::data_texcoordtexture2f, surfmesh_t::data_tvector3f, surfmesh_t::data_vertex3f, loadmodel, Mem_Alloc, surfmesh_t::num_triangles, surfmesh_t::num_vertices, and model_t::surfmesh.

Referenced by Mod_Q1BSP_LoadFaces(), Mod_Q3BSP_LoadFaces(), and Mod_VBSP_LoadFaces().

◆ Mod_BuildNormals()

void Mod_BuildNormals ( int firstvertex,
int numvertices,
int numtriangles,
const float * vertex3f,
const int * elements,
float * normal3f,
qbool areaweighting )

Definition at line 806 of file model_shared.c.

807{
808 int i, j;
809 const int *element;
810 float *vectorNormal;
811 float areaNormal[3];
812 // clear the vectors
813 memset(normal3f + 3 * firstvertex, 0, numvertices * sizeof(float[3]));
814 // process each vertex of each triangle and accumulate the results
815 // use area-averaging, to make triangles with a big area have a bigger
816 // weighting on the vertex normal than triangles with a small area
817 // to do so, just add the 'normals' together (the bigger the area
818 // the greater the length of the normal is
819 element = elements;
820 for (i = 0; i < numtriangles; i++, element += 3)
821 {
823 vertex3f + element[0] * 3,
824 vertex3f + element[1] * 3,
825 vertex3f + element[2] * 3,
826 areaNormal
827 );
828
829 if (!areaweighting)
830 VectorNormalize(areaNormal);
831
832 for (j = 0;j < 3;j++)
833 {
834 vectorNormal = normal3f + element[j] * 3;
835 vectorNormal[0] += areaNormal[0];
836 vectorNormal[1] += areaNormal[1];
837 vectorNormal[2] += areaNormal[2];
838 }
839 }
840 // and just normalize the accumulated vertex normal in the end
841 vectorNormal = normal3f + 3 * firstvertex;
842 for (i = 0; i < numvertices; i++, vectorNormal += 3)
843 VectorNormalize(vectorNormal);
844}
#define VectorNormalize(v)
Definition mathlib.h:104
#define TriangleNormal(a, b, c, n)
Definition mathlib.h:126
int i

References i, TriangleNormal, and VectorNormalize.

Referenced by Mod_INTERQUAKEMODEL_Load(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), Mod_Q1BSP_LoadFaces(), Mod_VBSP_LoadFaces(), Mod_ZYMOTICMODEL_Load(), RSurf_ActiveCustomEntity(), RSurf_PrepareVerticesForBatch(), and VM_CL_R_PolygonEnd().

◆ Mod_BuildTextureVectorsFromNormals()

void Mod_BuildTextureVectorsFromNormals ( int firstvertex,
int numvertices,
int numtriangles,
const float * vertex3f,
const float * texcoord2f,
const float * normal3f,
const int * elements,
float * svector3f,
float * tvector3f,
qbool areaweighting )

Definition at line 893 of file model_shared.c.

894{
895 int i, tnum;
896 float sdir[3], tdir[3], normal[3], *svec, *tvec;
897 const float *v0, *v1, *v2, *tc0, *tc1, *tc2, *n;
898 float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
899 const int *e;
900 // clear the vectors
901 memset(svector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3]));
902 memset(tvector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3]));
903 // process each vertex of each triangle and accumulate the results
904 for (tnum = 0, e = elements;tnum < numtriangles;tnum++, e += 3)
905 {
906 v0 = vertex3f + e[0] * 3;
907 v1 = vertex3f + e[1] * 3;
908 v2 = vertex3f + e[2] * 3;
909 tc0 = texcoord2f + e[0] * 2;
910 tc1 = texcoord2f + e[1] * 2;
911 tc2 = texcoord2f + e[2] * 2;
912
913 // 79 add/sub/negate/multiply (1 cycle), 1 compare (3 cycle?), total cycles not counting load/store/exchange roughly 82 cycles
914 // 6 add, 28 subtract, 39 multiply, 1 compare, 50% chance of 6 negates
915
916 // calculate the edge directions and surface normal
917 // 6 multiply, 9 subtract
918 VectorSubtract(v1, v0, v10);
919 VectorSubtract(v2, v0, v20);
920 normal[0] = v20[1] * v10[2] - v20[2] * v10[1];
921 normal[1] = v20[2] * v10[0] - v20[0] * v10[2];
922 normal[2] = v20[0] * v10[1] - v20[1] * v10[0];
923
924 // calculate the tangents
925 // 12 multiply, 10 subtract
926 tc10[1] = tc1[1] - tc0[1];
927 tc20[1] = tc2[1] - tc0[1];
928 sdir[0] = tc10[1] * v20[0] - tc20[1] * v10[0];
929 sdir[1] = tc10[1] * v20[1] - tc20[1] * v10[1];
930 sdir[2] = tc10[1] * v20[2] - tc20[1] * v10[2];
931 tc10[0] = tc1[0] - tc0[0];
932 tc20[0] = tc2[0] - tc0[0];
933 tdir[0] = tc10[0] * v20[0] - tc20[0] * v10[0];
934 tdir[1] = tc10[0] * v20[1] - tc20[0] * v10[1];
935 tdir[2] = tc10[0] * v20[2] - tc20[0] * v10[2];
936
937 // if texture is mapped the wrong way (counterclockwise), the tangents
938 // have to be flipped, this is detected by calculating a normal from the
939 // two tangents, and seeing if it is opposite the surface normal
940 // 9 multiply, 2 add, 3 subtract, 1 compare, 50% chance of: 6 negates
941 CrossProduct(tdir, sdir, tangentcross);
942 if (DotProduct(tangentcross, normal) < 0)
943 {
944 VectorNegate(sdir, sdir);
945 VectorNegate(tdir, tdir);
946 }
947
948 if (!areaweighting)
949 {
950 VectorNormalize(sdir);
951 VectorNormalize(tdir);
952 }
953 for (i = 0;i < 3;i++)
954 {
955 VectorAdd(svector3f + e[i]*3, sdir, svector3f + e[i]*3);
956 VectorAdd(tvector3f + e[i]*3, tdir, tvector3f + e[i]*3);
957 }
958 }
959 // make the tangents completely perpendicular to the surface normal, and
960 // then normalize them
961 // 16 assignments, 2 divide, 2 sqrt, 2 negates, 14 adds, 24 multiplies
962 for (i = 0, svec = svector3f + 3 * firstvertex, tvec = tvector3f + 3 * firstvertex, n = normal3f + 3 * firstvertex;i < numvertices;i++, svec += 3, tvec += 3, n += 3)
963 {
964 f = -DotProduct(svec, n);
965 VectorMA(svec, f, n, svec);
966 VectorNormalize(svec);
967 f = -DotProduct(tvec, n);
968 VectorMA(tvec, f, n, tvec);
969 VectorNormalize(tvec);
970 }
971}
#define n(x, y)
GLfloat GLfloat GLfloat v2
Definition glquake.h:747
GLfloat v0
Definition glquake.h:739
GLfloat GLfloat v1
Definition glquake.h:743
#define VectorNegate(a, b)
Definition mathlib.h:95
#define VectorSubtract(a, b, out)
Definition mathlib.h:99
#define CrossProduct(a, b, out)
Definition mathlib.h:103
#define DotProduct(a, b)
Definition mathlib.h:98
#define VectorAdd(a, b, out)
Definition mathlib.h:100
#define VectorMA(a, scale, b, out)
Definition mathlib.h:114
float f
vec3 normal

References CrossProduct, DotProduct, f, i, n, normal, v0, v1, v2, VectorAdd, VectorMA, VectorNegate, VectorNormalize, and VectorSubtract.

Referenced by Mod_Alias_MorphMesh_CompileFrames(), Mod_DARKPLACESMODEL_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_Mesh_Finalize(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), Mod_Q1BSP_LoadFaces(), Mod_Q3BSP_LoadFaces(), Mod_VBSP_LoadFaces(), Mod_ZYMOTICMODEL_Load(), RSurf_ActiveCustomEntity(), and RSurf_PrepareVerticesForBatch().

◆ Mod_BuildVBOs()

void Mod_BuildVBOs ( void )

Definition at line 2964 of file model_shared.c.

2965{
2966 if(cls.state == ca_dedicated)
2967 return;
2968
2970 return;
2971
2973 {
2974 int i;
2975 for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
2976 {
2978 {
2979 Con_Printf(CON_WARN "Mod_BuildVBOs: element %u is incorrect (%u should be %u)\n", i, loadmodel->surfmesh.data_element3s[i], loadmodel->surfmesh.data_element3i[i]);
2981 }
2982 }
2983 }
2984
2985 // upload short indices as a buffer
2988
2989 // upload int indices as a buffer
2992
2993 // only build a vbo if one has not already been created (this is important for brush models which load specially)
2994 // we put several vertex data streams in the same buffer
2996 {
2997 int size;
2998 unsigned char *mem;
2999 size = 0;
3009 mem = (unsigned char *)Mem_Alloc(tempmempool, size);
3028 Mem_Free(mem);
3029 }
3030}
client_static_t cls
Definition cl_main.c:116
@ ca_dedicated
Definition client.h:530
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_WARN
Definition console.h:101
vector size
r_meshbuffer_t * R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qbool isindexbuffer, qbool isuniformbuffer, qbool isdynamic, qbool isindex16)
cvar_t gl_paranoid
Definition gl_backend.c:8
#define NULL
Definition qtypes.h:12
cactive_t state
Definition client.h:568
int integer
Definition cvar.h:73
char name[MAX_QPATH]
r_meshbuffer_t * data_svector3f_vertexbuffer
int data_normal3f_bufferoffset
int data_skeletalweight4ub_bufferoffset
r_meshbuffer_t * data_lightmapcolor4f_vertexbuffer
r_meshbuffer_t * data_normal3f_vertexbuffer
int data_texcoordlightmap2f_bufferoffset
int data_skeletalindex4ub_bufferoffset
int data_svector3f_bufferoffset
unsigned char * data_skeletalweight4ub
unsigned char * data_skeletalindex4ub
r_meshbuffer_t * data_texcoordtexture2f_vertexbuffer
r_meshbuffer_t * data_skeletalindex4ub_vertexbuffer
r_meshbuffer_t * data_tvector3f_vertexbuffer
r_meshbuffer_t * data_element3i_indexbuffer
int data_texcoordtexture2f_bufferoffset
int data_tvector3f_bufferoffset
r_meshbuffer_t * data_texcoordlightmap2f_vertexbuffer
r_meshbuffer_t * data_skeletalweight4ub_vertexbuffer
int data_vertex3f_bufferoffset
int data_lightmapcolor4f_bufferoffset
r_meshbuffer_t * data_element3s_indexbuffer
r_meshbuffer_t * data_vertex3f_vertexbuffer
mempool_t * tempmempool
Definition zone.c:794

References ca_dedicated, cls, Con_Printf(), CON_WARN, surfmesh_t::data_element3i, surfmesh_t::data_element3i_indexbuffer, surfmesh_t::data_element3s, surfmesh_t::data_element3s_indexbuffer, surfmesh_t::data_lightmapcolor4f, surfmesh_t::data_lightmapcolor4f_bufferoffset, surfmesh_t::data_lightmapcolor4f_vertexbuffer, surfmesh_t::data_normal3f, surfmesh_t::data_normal3f_bufferoffset, surfmesh_t::data_normal3f_vertexbuffer, surfmesh_t::data_skeletalindex4ub, surfmesh_t::data_skeletalindex4ub_bufferoffset, surfmesh_t::data_skeletalindex4ub_vertexbuffer, surfmesh_t::data_skeletalweight4ub, surfmesh_t::data_skeletalweight4ub_bufferoffset, surfmesh_t::data_skeletalweight4ub_vertexbuffer, surfmesh_t::data_svector3f, surfmesh_t::data_svector3f_bufferoffset, surfmesh_t::data_svector3f_vertexbuffer, surfmesh_t::data_texcoordlightmap2f, surfmesh_t::data_texcoordlightmap2f_bufferoffset, surfmesh_t::data_texcoordlightmap2f_vertexbuffer, surfmesh_t::data_texcoordtexture2f, surfmesh_t::data_texcoordtexture2f_bufferoffset, surfmesh_t::data_texcoordtexture2f_vertexbuffer, surfmesh_t::data_tvector3f, surfmesh_t::data_tvector3f_bufferoffset, surfmesh_t::data_tvector3f_vertexbuffer, surfmesh_t::data_vertex3f, surfmesh_t::data_vertex3f_bufferoffset, surfmesh_t::data_vertex3f_vertexbuffer, gl_paranoid, i, cvar_t::integer, loadmodel, Mem_Alloc, Mem_Free, model_t::name, NULL, surfmesh_t::num_triangles, surfmesh_t::num_vertices, R_Mesh_CreateMeshBuffer(), size, client_static_t::state, model_t::surfmesh, and tempmempool.

Referenced by Mod_LoadModel(), Mod_OBJ_Load(), Mod_Q1BSP_Load(), Mod_Q2BSP_Load(), and Mod_Q3BSP_Load().

◆ Mod_BuildVertexRemapTableFromElements()

int Mod_BuildVertexRemapTableFromElements ( int numelements,
const int * elements,
int numvertices,
int * remapvertices )

Definition at line 724 of file model_shared.c.

725{
726 int i, count;
727 unsigned char *used;
728 used = (unsigned char *)Mem_Alloc(tempmempool, numvertices);
729 memset(used, 0, numvertices);
730 for (i = 0;i < numelements;i++)
731 used[elements[i]] = 1;
732 for (i = 0, count = 0;i < numvertices;i++)
733 remapvertices[i] = used[i] ? count++ : -1;
734 Mem_Free(used);
735 return count;
736}
GLenum GLenum GLsizei count
Definition glquake.h:656

References count, i, Mem_Alloc, Mem_Free, and tempmempool.

◆ Mod_ClearUsed()

void Mod_ClearUsed ( void )

Definition at line 564 of file model_shared.c.

565{
566 int i;
567 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
568 model_t *mod;
569 for (i = 0;i < nummodels;i++)
570 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0])
571 mod->used = false;
572}
float mod(float dividend, float divisor)
static int(ZEXPORT *qz_inflate)(z_stream *strm
static memexpandablearray_t models
size_t Mem_ExpandableArray_IndexRange(const memexpandablearray_t *l)
Definition zone.c:763
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
Definition zone.c:780

References i, int(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), and models.

Referenced by CL_ParseServerInfo(), QW_CL_RequestNextDownload(), and SV_SpawnServer().

◆ Mod_CountSkinFiles()

int Mod_CountSkinFiles ( skinfile_t * skinfile)

Definition at line 2826 of file model_shared.c.

2827{
2828 int i;
2829 for (i = 0;skinfile;skinfile = skinfile->next, i++);
2830 return i;
2831}
struct skinfile_s * next

References i, and skinfile_t::next.

◆ Mod_CreateCollisionMesh()

void Mod_CreateCollisionMesh ( model_t * mod)

Definition at line 1196 of file model_shared.c.

1197{
1198 int k, numcollisionmeshtriangles;
1199 qbool usesinglecollisionmesh = false;
1200 const msurface_t *surface = NULL;
1201
1202 mempool_t *mempool = mod->mempool;
1203 if (!mempool && mod->brush.parentmodel)
1204 mempool = mod->brush.parentmodel->mempool;
1205 // make a single combined collision mesh for physics engine use
1206 // TODO rewrite this to use the collision brushes as source, to fix issues with e.g. common/caulk which creates no drawsurface
1207 numcollisionmeshtriangles = 0;
1208 for (k = mod->submodelsurfaces_start;k < mod->submodelsurfaces_end;k++)
1209 {
1210 surface = mod->data_surfaces + k;
1211 if (!strcmp(surface->texture->name, "collision") || !strcmp(surface->texture->name, "collisionconvex")) // found collision mesh
1212 {
1213 usesinglecollisionmesh = true;
1214 numcollisionmeshtriangles = surface->num_triangles;
1215 break;
1216 }
1217 if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
1218 continue;
1219 numcollisionmeshtriangles += surface->num_triangles;
1220 }
1221 mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles);
1222 if (usesinglecollisionmesh)
1223 Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
1224 else
1225 {
1226 for (k = mod->submodelsurfaces_start; k < mod->submodelsurfaces_end; k++)
1227 {
1228 surface = mod->data_surfaces + k;
1229 if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
1230 continue;
1231 Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
1232 }
1233 }
1234 mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mod->brush.collisionmesh, false);
1235}
#define SUPERCONTENTS_SOLID
Definition bspfile.h:196
shadowmesh_t * Mod_ShadowMesh_Finish(shadowmesh_t *mesh, qbool createvbo)
void Mod_ShadowMesh_AddMesh(shadowmesh_t *mesh, const float *vertex3f, int numtris, const int *element3i)
shadowmesh_t * Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles)
bool qbool
Definition qtypes.h:9
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
int num_firsttriangle
int num_triangles
range of triangles and vertices in model->surfmesh
texture_t * texture
the texture to use on the surface
char name[64]
int supercontents

References mod(), Mod_ShadowMesh_AddMesh(), Mod_ShadowMesh_Begin(), Mod_ShadowMesh_Finish(), texture_t::name, NULL, msurface_t::num_firsttriangle, msurface_t::num_triangles, texture_t::supercontents, SUPERCONTENTS_SOLID, and msurface_t::texture.

◆ Mod_CreateShaderPass()

texture_shaderpass_t * Mod_CreateShaderPass ( mempool_t * mempool,
skinframe_t * skinframe )

Definition at line 2236 of file model_shared.c.

2237{
2238 texture_shaderpass_t *shaderpass = (texture_shaderpass_t *)Mem_Alloc(mempool, sizeof(*shaderpass));
2239 shaderpass->framerate = 0.0f;
2240 shaderpass->numframes = 1;
2241 shaderpass->blendfunc[0] = GL_ONE;
2242 shaderpass->blendfunc[1] = GL_ZERO;
2243 shaderpass->rgbgen.rgbgen = Q3RGBGEN_IDENTITY;
2245 shaderpass->alphatest = false;
2246 shaderpass->tcgen.tcgen = Q3TCGEN_TEXTURE;
2247 shaderpass->skinframes[0] = skinframe;
2248 return shaderpass;
2249}
#define GL_ZERO
Definition glquake.h:73
#define GL_ONE
Definition glquake.h:74
@ Q3RGBGEN_IDENTITY
Definition r_qshader.h:69
@ Q3TCGEN_TEXTURE
Definition r_qshader.h:101
@ Q3ALPHAGEN_IDENTITY
Definition r_qshader.h:85
q3shaderinfo_layer_rgbgen_t rgbgen
Definition r_qshader.h:267
q3shaderinfo_layer_alphagen_t alphagen
Definition r_qshader.h:268
struct skinframe_s * skinframes[TEXTURE_MAXFRAMES]
Definition r_qshader.h:265
q3shaderinfo_layer_tcgen_t tcgen
Definition r_qshader.h:269

References q3shaderinfo_layer_alphagen_t::alphagen, texture_shaderpass_t::alphagen, texture_shaderpass_t::alphatest, texture_shaderpass_t::blendfunc, texture_shaderpass_t::framerate, GL_ONE, GL_ZERO, Mem_Alloc, texture_shaderpass_t::numframes, Q3ALPHAGEN_IDENTITY, Q3RGBGEN_IDENTITY, Q3TCGEN_TEXTURE, q3shaderinfo_layer_rgbgen_t::rgbgen, texture_shaderpass_t::rgbgen, texture_shaderpass_t::skinframes, q3shaderinfo_layer_tcgen_t::tcgen, and texture_shaderpass_t::tcgen.

Referenced by Mod_LoadCustomMaterial(), Mod_LoadTextureFromQ3Shader(), Mod_Q1BSP_LoadTextures(), and Mod_SpriteSetupTexture().

◆ Mod_CreateShaderPassFromQ3ShaderLayer()

texture_shaderpass_t * Mod_CreateShaderPassFromQ3ShaderLayer ( mempool_t * mempool,
const char * modelname,
q3shaderinfo_layer_t * layer,
int layerindex,
int texflags,
const char * texturename )

Definition at line 2251 of file model_shared.c.

2252{
2253 int j;
2254 texture_shaderpass_t *shaderpass = (texture_shaderpass_t *)Mem_Alloc(mempool, sizeof(*shaderpass));
2255 shaderpass->alphatest = layer->alphatest != 0;
2256 shaderpass->framerate = layer->framerate;
2257 shaderpass->numframes = layer->numframes;
2258 shaderpass->blendfunc[0] = layer->blendfunc[0];
2259 shaderpass->blendfunc[1] = layer->blendfunc[1];
2260 shaderpass->rgbgen = layer->rgbgen;
2261 shaderpass->alphagen = layer->alphagen;
2262 shaderpass->tcgen = layer->tcgen;
2263 for (j = 0; j < Q3MAXTCMODS && layer->tcmods[j].tcmod != Q3TCMOD_NONE; j++)
2264 shaderpass->tcmods[j] = layer->tcmods[j];
2265 for (j = 0; j < layer->numframes; j++)
2266 shaderpass->skinframes[j] = R_SkinFrame_LoadExternal(layer->texturename[j], texflags, false, true);
2267 return shaderpass;
2268}
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2314
GLenum GLenum GLuint GLint GLint layer
Definition glquake.h:615
#define Q3MAXTCMODS
Definition r_qshader.h:26
@ Q3TCMOD_NONE
Definition r_qshader.h:111
q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS]
Definition r_qshader.h:270

References texture_shaderpass_t::alphagen, texture_shaderpass_t::alphatest, texture_shaderpass_t::blendfunc, texture_shaderpass_t::framerate, layer, Mem_Alloc, texture_shaderpass_t::numframes, Q3MAXTCMODS, Q3TCMOD_NONE, R_SkinFrame_LoadExternal(), texture_shaderpass_t::rgbgen, texture_shaderpass_t::skinframes, texture_shaderpass_t::tcgen, and texture_shaderpass_t::tcmods.

Referenced by Mod_LoadTextureFromQ3Shader().

◆ Mod_Decompile_f()

static void Mod_Decompile_f ( cmd_state_t * cmd)
static

Definition at line 3318 of file model_shared.c.

3319{
3320 int i, j, k, l, first, count;
3321 model_t *mod;
3322 char inname[MAX_QPATH];
3323 char outname[MAX_QPATH];
3324 char mtlname[MAX_QPATH];
3325 char basename[MAX_QPATH];
3326 char animname[MAX_QPATH];
3327 char animname2[MAX_QPATH];
3328 char zymtextbuffer[16384];
3329 char dpmtextbuffer[16384];
3330 char framegroupstextbuffer[16384];
3331 int zymtextsize = 0;
3332 int dpmtextsize = 0;
3333 int framegroupstextsize = 0;
3334 char vabuf[1024];
3335
3336 if (Cmd_Argc(cmd) != 2)
3337 {
3338 Con_Print("usage: modeldecompile <filename>\n");
3339 return;
3340 }
3341
3342 dp_strlcpy(inname, Cmd_Argv(cmd, 1), sizeof(inname));
3343 FS_StripExtension(inname, basename, sizeof(basename));
3344
3345 mod = Mod_ForName(inname, false, true, inname[0] == '*' ? cl.model_name[1] : NULL);
3346 if (!mod)
3347 {
3348 Con_Print("No such model\n");
3349 return;
3350 }
3351 if (mod->brush.submodel)
3352 {
3353 // if we're decompiling a submodel, be sure to give it a proper name based on its parent
3354 FS_StripExtension(cl.model_name[1], outname, sizeof(outname));
3355 dpsnprintf(basename, sizeof(basename), "%s/%s", outname, mod->name);
3356 outname[0] = 0;
3357 }
3358 if (!mod->surfmesh.num_triangles)
3359 {
3360 Con_Print("Empty model (or sprite)\n");
3361 return;
3362 }
3363
3364 // export OBJ if possible (not on sprites)
3365 if (mod->surfmesh.num_triangles)
3366 {
3367 dpsnprintf(outname, sizeof(outname), "%s_decompiled.obj", basename);
3368 dpsnprintf(mtlname, sizeof(mtlname), "%s_decompiled.mtl", basename);
3369 Mod_Decompile_OBJ(mod, outname, mtlname, inname);
3370 }
3371
3372 // export SMD if possible (only for skeletal models)
3373 if (mod->surfmesh.num_triangles && mod->num_bones)
3374 {
3375 dpsnprintf(outname, sizeof(outname), "%s_decompiled/ref1.smd", basename);
3376 Mod_Decompile_SMD(mod, outname, 0, 1, true);
3377 l = dpsnprintf(zymtextbuffer + zymtextsize, sizeof(zymtextbuffer) - zymtextsize, "output out.zym\nscale 1\norigin 0 0 0\nmesh ref1.smd\n");
3378 if (l > 0) zymtextsize += l;
3379 l = dpsnprintf(dpmtextbuffer + dpmtextsize, sizeof(dpmtextbuffer) - dpmtextsize, "outputdir .\nmodel out\nscale 1\norigin 0 0 0\nscene ref1.smd\n");
3380 if (l > 0) dpmtextsize += l;
3381 for (i = 0;i < mod->numframes;i = j)
3382 {
3383 dp_strlcpy(animname, mod->animscenes[i].name, sizeof(animname));
3384 first = mod->animscenes[i].firstframe;
3385 if (mod->animscenes[i].framecount > 1)
3386 {
3387 // framegroup anim
3388 count = mod->animscenes[i].framecount;
3389 j = i + 1;
3390 }
3391 else
3392 {
3393 // individual frame
3394 // check for additional frames with same name
3395 for (l = 0, k = (int)strlen(animname);animname[l];l++)
3396 if(animname[l] < '0' || animname[l] > '9')
3397 k = l + 1;
3398 if(k > 0 && animname[k-1] == '_')
3399 --k;
3400 animname[k] = 0;
3401 count = mod->num_poses - first;
3402 for (j = i + 1;j < mod->numframes;j++)
3403 {
3404 dp_strlcpy(animname2, mod->animscenes[j].name, sizeof(animname2));
3405 for (l = 0, k = (int)strlen(animname2);animname2[l];l++)
3406 if(animname2[l] < '0' || animname2[l] > '9')
3407 k = l + 1;
3408 if(k > 0 && animname[k-1] == '_')
3409 --k;
3410 animname2[k] = 0;
3411 if (strcmp(animname2, animname) || mod->animscenes[j].framecount > 1)
3412 {
3413 count = mod->animscenes[j].firstframe - first;
3414 break;
3415 }
3416 }
3417 // if it's only one frame, use the original frame name
3418 if (j == i + 1)
3419 dp_strlcpy(animname, mod->animscenes[i].name, sizeof(animname));
3420
3421 }
3422 dpsnprintf(outname, sizeof(outname), "%s_decompiled/%s.smd", basename, animname);
3423 Mod_Decompile_SMD(mod, outname, first, count, false);
3424 if (zymtextsize < (int)sizeof(zymtextbuffer) - 100)
3425 {
3426 l = dpsnprintf(zymtextbuffer + zymtextsize, sizeof(zymtextbuffer) - zymtextsize, "scene %s.smd fps %g %s\n", animname, mod->animscenes[i].framerate, mod->animscenes[i].loop ? "" : " noloop");
3427 if (l > 0) zymtextsize += l;
3428 }
3429 if (dpmtextsize < (int)sizeof(dpmtextbuffer) - 100)
3430 {
3431 l = dpsnprintf(dpmtextbuffer + dpmtextsize, sizeof(dpmtextbuffer) - dpmtextsize, "scene %s.smd fps %g %s\n", animname, mod->animscenes[i].framerate, mod->animscenes[i].loop ? "" : " noloop");
3432 if (l > 0) dpmtextsize += l;
3433 }
3434 if (framegroupstextsize < (int)sizeof(framegroupstextbuffer) - 100)
3435 {
3436 l = dpsnprintf(framegroupstextbuffer + framegroupstextsize, sizeof(framegroupstextbuffer) - framegroupstextsize, "%d %d %f %d // %s\n", first, count, mod->animscenes[i].framerate, mod->animscenes[i].loop, animname);
3437 if (l > 0) framegroupstextsize += l;
3438 }
3439 }
3440 if (zymtextsize)
3441 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled/out_zym.txt", basename), zymtextbuffer, (fs_offset_t)zymtextsize);
3442 if (dpmtextsize)
3443 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled/out_dpm.txt", basename), dpmtextbuffer, (fs_offset_t)dpmtextsize);
3444 if (framegroupstextsize)
3445 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled.framegroups", basename), framegroupstextbuffer, (fs_offset_t)framegroupstextsize);
3446 }
3447}
client_state_t cl
Definition cl_main.c:117
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
qbool FS_WriteFile(const char *filename, const void *data, fs_offset_t len)
Definition fs.c:3592
void FS_StripExtension(const char *in, char *out, size_t size_out)
Definition fs.c:3611
int64_t fs_offset_t
Definition fs.h:37
GLint first
Definition glquake.h:671
float strlen(string s)
void cmd(string command,...)
model_t * Mod_ForName(const char *name, qbool crash, qbool checkdisk, const char *parentname)
static void Mod_Decompile_SMD(model_t *model, const char *filename, int firstpose, int numposes, qbool writetriangles)
static void Mod_Decompile_OBJ(model_t *model, const char *filename, const char *mtlfilename, const char *originalfilename)
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
char model_name[MAX_MODELS][MAX_QPATH]
Definition client.h:892

References cl, cmd(), Cmd_Argc(), Cmd_Argv(), Con_Print(), count, dp_strlcpy, dpsnprintf(), first, FS_StripExtension(), FS_WriteFile(), i, MAX_QPATH, mod(), Mod_Decompile_OBJ(), Mod_Decompile_SMD(), Mod_ForName(), client_state_t::model_name, NULL, strlen(), and va().

Referenced by Mod_Init().

◆ Mod_Decompile_OBJ()

static void Mod_Decompile_OBJ ( model_t * model,
const char * filename,
const char * mtlfilename,
const char * originalfilename )
static

Definition at line 3033 of file model_shared.c.

3034{
3035 int submodelindex, vertexindex, surfaceindex, triangleindex, textureindex, countvertices = 0, countsurfaces = 0, countfaces = 0, counttextures = 0;
3036 int a, b, c;
3037 const char *texname;
3038 const int *e;
3039 const float *v, *vn, *vt;
3040 size_t l;
3041 size_t outbufferpos = 0;
3042 size_t outbuffermax = 0x100000;
3043 char *outbuffer = (char *) Z_Malloc(outbuffermax), *oldbuffer;
3044 const msurface_t *surface;
3045 const int maxtextures = 256;
3046 char *texturenames = (char *) Z_Malloc(maxtextures * MAX_QPATH);
3047 model_t *submodel;
3048
3049 // construct the mtllib file
3050 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "# mtllib for %s exported by darkplaces engine\n", originalfilename);
3051 if (l > 0)
3052 outbufferpos += l;
3053 for (surfaceindex = 0, surface = model->data_surfaces;surfaceindex < model->num_surfaces;surfaceindex++, surface++)
3054 {
3055 countsurfaces++;
3056 countvertices += surface->num_vertices;
3057 countfaces += surface->num_triangles;
3058 texname = (surface->texture && surface->texture->name[0]) ? surface->texture->name : "default";
3059 for (textureindex = 0;textureindex < counttextures;textureindex++)
3060 if (!strcmp(texturenames + textureindex * MAX_QPATH, texname))
3061 break;
3062 if (textureindex < counttextures)
3063 continue; // already wrote this material entry
3064 if (textureindex >= maxtextures)
3065 continue; // just a precaution
3066 textureindex = counttextures++;
3067 dp_strlcpy(texturenames + textureindex * MAX_QPATH, texname, MAX_QPATH);
3068 if (outbufferpos >= outbuffermax >> 1)
3069 {
3070 outbuffermax *= 2;
3071 oldbuffer = outbuffer;
3072 outbuffer = (char *) Z_Malloc(outbuffermax);
3073 memcpy(outbuffer, oldbuffer, outbufferpos);
3074 Z_Free(oldbuffer);
3075 }
3076 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "newmtl %s\nNs 96.078431\nKa 0 0 0\nKd 0.64 0.64 0.64\nKs 0.5 0.5 0.5\nNi 1\nd 1\nillum 2\nmap_Kd %s%s\n\n", texname, texname, strstr(texname, ".tga") ? "" : ".tga");
3077 if (l > 0)
3078 outbufferpos += l;
3079 }
3080
3081 // write the mtllib file
3082 FS_WriteFile(mtlfilename, outbuffer, outbufferpos);
3083
3084 // construct the obj file
3085 outbufferpos = 0;
3086 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "# model exported from %s by darkplaces engine\n# %i vertices, %i faces, %i surfaces\nmtllib %s\n", originalfilename, countvertices, countfaces, countsurfaces, mtlfilename);
3087 if (l > 0)
3088 outbufferpos += l;
3089
3090 for (vertexindex = 0, v = model->surfmesh.data_vertex3f, vn = model->surfmesh.data_normal3f, vt = model->surfmesh.data_texcoordtexture2f;vertexindex < model->surfmesh.num_vertices;vertexindex++, v += 3, vn += 3, vt += 2)
3091 {
3092 if (outbufferpos >= outbuffermax >> 1)
3093 {
3094 outbuffermax *= 2;
3095 oldbuffer = outbuffer;
3096 outbuffer = (char *) Z_Malloc(outbuffermax);
3097 memcpy(outbuffer, oldbuffer, outbufferpos);
3098 Z_Free(oldbuffer);
3099 }
3101 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "v %f %f %f\nvn %f %f %f\nvt %f %f\n", v[0], v[2], v[1], vn[0], vn[2], vn[1], vt[0], 1-vt[1]);
3102 else
3103 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "v %f %f %f\nvn %f %f %f\nvt %f %f\n", v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1-vt[1]);
3104 if (l > 0)
3105 outbufferpos += l;
3106 }
3107
3108 for (submodelindex = 0;submodelindex < max(1, model->brush.numsubmodels);submodelindex++)
3109 {
3110 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "o %i\n", submodelindex);
3111 if (l > 0)
3112 outbufferpos += l;
3113 submodel = model->brush.numsubmodels ? model->brush.submodels[submodelindex] : model;
3114 for (surfaceindex = submodel->submodelsurfaces_start;surfaceindex < submodel->submodelsurfaces_end;surfaceindex++)
3115 {
3116 surface = model->data_surfaces + surfaceindex;
3117 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "usemtl %s\n", (surface->texture && surface->texture->name[0]) ? surface->texture->name : "default");
3118 if (l > 0)
3119 outbufferpos += l;
3120 for (triangleindex = 0, e = model->surfmesh.data_element3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3121 {
3122 if (outbufferpos >= outbuffermax >> 1)
3123 {
3124 outbuffermax *= 2;
3125 oldbuffer = outbuffer;
3126 outbuffer = (char *) Z_Malloc(outbuffermax);
3127 memcpy(outbuffer, oldbuffer, outbufferpos);
3128 Z_Free(oldbuffer);
3129 }
3130 a = e[0]+1;
3131 b = e[1]+1;
3132 c = e[2]+1;
3134 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", a,a,a,b,b,b,c,c,c);
3135 else
3136 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", a,a,a,c,c,c,b,b,b);
3137 if (l > 0)
3138 outbufferpos += l;
3139 }
3140 }
3141 }
3142
3143 // write the obj file
3144 FS_WriteFile(filename, outbuffer, outbufferpos);
3145
3146 // clean up
3147 Z_Free(outbuffer);
3148 Z_Free(texturenames);
3149
3150 // print some stats
3151 Con_Printf("Wrote %s (%i bytes, %i vertices, %i faces, %i surfaces with %i distinct textures)\n", filename, (int)outbufferpos, countvertices, countfaces, countsurfaces, counttextures);
3152}
string model
const GLdouble * v
Definition glquake.h:762
#define max(A, B)
Definition mathlib.h:38
cvar_t mod_obj_orientation
Definition model_brush.c:70
dp_FragColor b
ret a
model_brush_t brush
int submodelsurfaces_start
#define Z_Malloc(size)
Definition zone.h:161
#define Z_Free(data)
Definition zone.h:164

References a, b, model_t::brush, Con_Printf(), dp_strlcpy, dpsnprintf(), FS_WriteFile(), cvar_t::integer, max, MAX_QPATH, mod_obj_orientation, model, texture_t::name, msurface_t::num_firsttriangle, msurface_t::num_triangles, msurface_t::num_vertices, model_brush_t::numsubmodels, model_t::submodelsurfaces_start, msurface_t::texture, v, Z_Free, and Z_Malloc.

Referenced by Mod_Decompile_f().

◆ Mod_Decompile_SMD()

static void Mod_Decompile_SMD ( model_t * model,
const char * filename,
int firstpose,
int numposes,
qbool writetriangles )
static

Definition at line 3154 of file model_shared.c.

3155{
3156 int countnodes = 0, counttriangles = 0, countframes = 0;
3157 int surfaceindex;
3158 int triangleindex;
3159 int transformindex;
3160 int poseindex;
3161 int cornerindex;
3162 const int *e;
3163 size_t l;
3164 size_t outbufferpos = 0;
3165 size_t outbuffermax = 0x100000;
3166 char *outbuffer = (char *) Z_Malloc(outbuffermax), *oldbuffer;
3167 const msurface_t *surface;
3168 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "version 1\nnodes\n");
3169 if (l > 0)
3170 outbufferpos += l;
3171 for (transformindex = 0;transformindex < model->num_bones;transformindex++)
3172 {
3173 if (outbufferpos >= outbuffermax >> 1)
3174 {
3175 outbuffermax *= 2;
3176 oldbuffer = outbuffer;
3177 outbuffer = (char *) Z_Malloc(outbuffermax);
3178 memcpy(outbuffer, oldbuffer, outbufferpos);
3179 Z_Free(oldbuffer);
3180 }
3181 countnodes++;
3182 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i \"%s\" %3i\n", transformindex, model->data_bones[transformindex].name, model->data_bones[transformindex].parent);
3183 if (l > 0)
3184 outbufferpos += l;
3185 }
3186 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "end\nskeleton\n");
3187 if (l > 0)
3188 outbufferpos += l;
3189 for (poseindex = 0;poseindex < numposes;poseindex++)
3190 {
3191 countframes++;
3192 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "time %i\n", poseindex);
3193 if (l > 0)
3194 outbufferpos += l;
3195 for (transformindex = 0;transformindex < model->num_bones;transformindex++)
3196 {
3197 float angles[3];
3198 float mtest[4][3];
3199 matrix4x4_t posematrix;
3200 if (outbufferpos >= outbuffermax >> 1)
3201 {
3202 outbuffermax *= 2;
3203 oldbuffer = outbuffer;
3204 outbuffer = (char *) Z_Malloc(outbuffermax);
3205 memcpy(outbuffer, oldbuffer, outbufferpos);
3206 Z_Free(oldbuffer);
3207 }
3208
3209 // strangely the smd angles are for a transposed matrix, so we
3210 // have to generate a transposed matrix, then convert that...
3211 Matrix4x4_FromBonePose7s(&posematrix, model->num_posescale, model->data_poses7s + 7*(model->num_bones * poseindex + transformindex));
3212 Matrix4x4_ToArray12FloatGL(&posematrix, mtest);
3213 AnglesFromVectors(angles, mtest[0], mtest[2], false);
3214 if (angles[0] >= 180) angles[0] -= 360;
3215 if (angles[1] >= 180) angles[1] -= 360;
3216 if (angles[2] >= 180) angles[2] -= 360;
3217
3218#if 0
3219{
3220 float a = DEG2RAD(angles[ROLL]);
3221 float b = DEG2RAD(angles[PITCH]);
3222 float c = DEG2RAD(angles[YAW]);
3223 float cy, sy, cp, sp, cr, sr;
3224 float test[4][3];
3225 // smd matrix construction, for comparing
3226 sy = sin(c);
3227 cy = cos(c);
3228 sp = sin(b);
3229 cp = cos(b);
3230 sr = sin(a);
3231 cr = cos(a);
3232
3233 test[0][0] = cp*cy;
3234 test[0][1] = cp*sy;
3235 test[0][2] = -sp;
3236 test[1][0] = sr*sp*cy+cr*-sy;
3237 test[1][1] = sr*sp*sy+cr*cy;
3238 test[1][2] = sr*cp;
3239 test[2][0] = (cr*sp*cy+-sr*-sy);
3240 test[2][1] = (cr*sp*sy+-sr*cy);
3241 test[2][2] = cr*cp;
3242 test[3][0] = pose[9];
3243 test[3][1] = pose[10];
3244 test[3][2] = pose[11];
3245}
3246#endif
3247 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f\n", transformindex, mtest[3][0], mtest[3][1], mtest[3][2], DEG2RAD(angles[ROLL]), DEG2RAD(angles[PITCH]), DEG2RAD(angles[YAW]));
3248 if (l > 0)
3249 outbufferpos += l;
3250 }
3251 }
3252 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "end\n");
3253 if (l > 0)
3254 outbufferpos += l;
3255 if (writetriangles)
3256 {
3257 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "triangles\n");
3258 if (l > 0)
3259 outbufferpos += l;
3260 for (surfaceindex = 0, surface = model->data_surfaces;surfaceindex < model->num_surfaces;surfaceindex++, surface++)
3261 {
3262 for (triangleindex = 0, e = model->surfmesh.data_element3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3263 {
3264 counttriangles++;
3265 if (outbufferpos >= outbuffermax >> 1)
3266 {
3267 outbuffermax *= 2;
3268 oldbuffer = outbuffer;
3269 outbuffer = (char *) Z_Malloc(outbuffermax);
3270 memcpy(outbuffer, oldbuffer, outbufferpos);
3271 Z_Free(oldbuffer);
3272 }
3273 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%s\n", surface->texture && surface->texture->name[0] ? surface->texture->name : "default.bmp");
3274 if (l > 0)
3275 outbufferpos += l;
3276 for (cornerindex = 0;cornerindex < 3;cornerindex++)
3277 {
3278 const int index = e[2-cornerindex];
3279 const float *v = model->surfmesh.data_vertex3f + index * 3;
3280 const float *vn = model->surfmesh.data_normal3f + index * 3;
3281 const float *vt = model->surfmesh.data_texcoordtexture2f + index * 2;
3282 const int b = model->surfmesh.blends[index];
3283 if (b < model->num_bones)
3284 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f %f %f\n" , b, v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1]);
3285 else
3286 {
3287 const blendweights_t *w = model->surfmesh.data_blendweights + b - model->num_bones;
3288 const unsigned char *wi = w->index;
3289 const unsigned char *wf = w->influence;
3290 if (wf[3]) l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f %f %f 4 %i %f %i %f %i %f %i %f\n", wi[0], v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f, wi[2], wf[2]/255.0f, wi[3], wf[3]/255.0f);
3291 else if (wf[2]) l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f %f %f 3 %i %f %i %f %i %f\n" , wi[0], v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f, wi[2], wf[2]/255.0f);
3292 else if (wf[1]) l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f %f %f 2 %i %f %i %f\n" , wi[0], v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1], wi[0], wf[0]/255.0f, wi[1], wf[1]/255.0f);
3293 else l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "%3i %f %f %f %f %f %f %f %f\n" , wi[0], v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], 1 - vt[1]);
3294 }
3295 if (l > 0)
3296 outbufferpos += l;
3297 }
3298 }
3299 }
3300 l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "end\n");
3301 if (l > 0)
3302 outbufferpos += l;
3303 }
3304
3305 FS_WriteFile(filename, outbuffer, outbufferpos);
3306 Z_Free(outbuffer);
3307
3308 Con_Printf("Wrote %s (%i bytes, %i nodes, %i frames, %i triangles)\n", filename, (int)outbufferpos, countnodes, countframes, counttriangles);
3309}
vector angles
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
GLuint index
Definition glquake.h:629
void AnglesFromVectors(vec3_t angles, const vec3_t forward, const vec3_t up, qbool flippitch)
LadyHavoc: calculates pitch/yaw/roll angles from forward and up vectors.
Definition mathlib.c:650
#define DEG2RAD(a)
Definition mathlib.h:65
void Matrix4x4_FromBonePose7s(matrix4x4_t *m, float originscale, const short *pose7s)
Definition matrixlib.c:1599
void Matrix4x4_ToArray12FloatGL(const matrix4x4_t *in, float out[4][3])
Definition matrixlib.c:1321
float cos(float f)
float sin(float f)
#define YAW
Definition qtypes.h:19
#define PITCH
Definition qtypes.h:16
#define ROLL
Definition qtypes.h:22
unsigned char index[4]

References a, angles, AnglesFromVectors(), b, Con_Printf(), cos(), DEG2RAD, dpsnprintf(), FS_WriteFile(), blendweights_t::index, index, Matrix4x4_FromBonePose7s(), Matrix4x4_ToArray12FloatGL(), model, texture_t::name, msurface_t::num_firsttriangle, PITCH, ROLL, sin(), msurface_t::texture, v, w, YAW, Z_Free, and Z_Malloc.

Referenced by Mod_Decompile_f().

◆ Mod_FindName()

model_t * Mod_FindName ( const char * name,
const char * parentname )

Definition at line 595 of file model_shared.c.

596{
597 int i;
598 int nummodels;
599 model_t *mod;
600
601 if (!parentname)
602 parentname = "";
603
605
606 if (!name[0])
607 Host_Error ("Mod_ForName: empty name");
608
609 // search the currently loaded models
610 for (i = 0;i < nummodels;i++)
611 {
612 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !strcmp(mod->name, name) && ((!mod->brush.parentmodel && !parentname[0]) || (mod->brush.parentmodel && parentname[0] && !strcmp(mod->brush.parentmodel->name, parentname))))
613 {
614 mod->used = true;
615 return mod;
616 }
617 }
618
619 // no match found, create a new one
621 dp_strlcpy(mod->name, name, sizeof(mod->name));
622 if (parentname[0])
623 mod->brush.parentmodel = Mod_FindName(parentname, NULL);
624 else
625 mod->brush.parentmodel = NULL;
626 mod->loaded = false;
627 mod->used = true;
628 return mod;
629}
const GLchar * name
Definition glquake.h:601
void Host_Error(const char *error,...)
Definition host.c:85
model_t * Mod_FindName(const char *name, const char *parentname)
void * Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l)
Definition zone.c:695

References dp_strlcpy, Host_Error(), i, int(), Mem_ExpandableArray_AllocRecord(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), Mod_FindName(), models, name, and NULL.

Referenced by CL_ParseServerInfo(), Mod_FindName(), Mod_ForName(), Mod_OBJ_Load(), Mod_Q1BSP_Load(), Mod_Q2BSP_Load(), Mod_Q3BSP_Load(), QW_CL_RequestNextDownload(), SV_ModelIndex(), and VM_CL_effect().

◆ Mod_FindPotentialDeforms()

static void Mod_FindPotentialDeforms ( model_t * mod)
static

Definition at line 372 of file model_shared.c.

373{
374 int i, j;
376 mod->wantnormals = false;
377 mod->wanttangents = false;
378 for (i = 0;i < mod->num_textures;i++)
379 {
380 texture = mod->data_textures + i;
381 if (texture->materialshaderpass && texture->materialshaderpass->tcgen.tcgen == Q3TCGEN_ENVIRONMENT)
382 mod->wantnormals = true;
383 if (texture->materialshaderpass && texture->materialshaderpass->tcgen.tcgen == Q3TCGEN_ENVIRONMENT)
384 mod->wantnormals = true;
385 for (j = 0;j < Q3MAXDEFORMS;j++)
386 {
387 if (texture->deforms[j].deform == Q3DEFORM_AUTOSPRITE)
388 {
389 mod->wanttangents = true;
390 mod->wantnormals = true;
391 break;
392 }
393 if (texture->deforms[j].deform != Q3DEFORM_NONE)
394 mod->wantnormals = true;
395 }
396 }
397}
GLenum GLenum GLuint texture
Definition glquake.h:613
#define Q3MAXDEFORMS
Definition r_qshader.h:27
@ Q3DEFORM_AUTOSPRITE
Definition r_qshader.h:49
@ Q3DEFORM_NONE
Definition r_qshader.h:47
@ Q3TCGEN_ENVIRONMENT
Definition r_qshader.h:102

References i, mod(), Q3DEFORM_AUTOSPRITE, Q3DEFORM_NONE, Q3MAXDEFORMS, Q3TCGEN_ENVIRONMENT, and texture.

Referenced by Mod_LoadModel().

◆ Mod_ForName()

model_t * Mod_ForName ( const char * name,
qbool crash,
qbool checkdisk,
const char * parentname )

Definition at line 640 of file model_shared.c.

641{
642 model_t *model;
643
644 // FIXME: So we don't crash if a server is started early.
645 if(!vid_opened)
647
648 model = Mod_FindName(name, parentname);
649 if (!model->loaded || checkdisk)
650 Mod_LoadModel(model, crash, checkdisk);
651 return model;
652}
void CL_StartVideo(void)
Definition cl_main.c:2786
void crash(void)
qbool vid_opened
Definition cl_main.c:2785
model_t * Mod_LoadModel(model_t *mod, qbool crash, qbool checkdisk)

References CL_StartVideo(), crash(), Mod_FindName(), Mod_LoadModel(), model, name, and vid_opened.

Referenced by CL_BeginDownloads(), CL_ParseServerInfo(), CL_ParseServerMessage(), CL_ParseTempEntity(), Mod_Decompile_f(), Mod_Precache_f(), QW_CL_RequestNextDownload(), SV_Loadgame_f(), SV_ModelIndex(), SV_SpawnServer(), SV_Viewmodel_f(), and VM_CL_precache_model().

◆ Mod_FrameGroupify()

static void Mod_FrameGroupify ( model_t * mod,
const char * buf )
static

Definition at line 351 of file model_shared.c.

352{
353 unsigned int cnt;
354
355 // 0. count
357 if(!cnt)
358 {
359 Con_Printf("no scene found in framegroups file, aborting\n");
360 return;
361 }
362 mod->numframes = cnt;
363
364 // 1. reallocate
365 // (we do not free the previous animscenes, but model unloading will free the pool owning them, so it's okay)
366 mod->animscenes = (animscene_t *) Mem_Alloc(mod->mempool, sizeof(animscene_t) * mod->numframes);
367
368 // 2. parse
370}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
static void Mod_FrameGroupify_ParseGroups_Store(unsigned int i, int start, int len, float fps, qbool loop, const char *name, void *pass)
static int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups_t cb, void *pass)

References buf, Con_Printf(), Mem_Alloc, mod(), Mod_FrameGroupify_ParseGroups(), Mod_FrameGroupify_ParseGroups_Store(), and NULL.

Referenced by Mod_LoadModel().

◆ Mod_FrameGroupify_ParseGroups()

static int Mod_FrameGroupify_ParseGroups ( const char * buf,
mod_framegroupify_parsegroups_t cb,
void * pass )
static

Definition at line 263 of file model_shared.c.

264{
265 const char *bufptr;
266 int start, len;
267 float fps;
268 unsigned int i;
269 qbool loop;
270 char name[64];
271
272 bufptr = buf;
273 i = 0;
274 while(bufptr)
275 {
276 // an anim scene!
277
278 // REQUIRED: fetch start
279 COM_ParseToken_Simple(&bufptr, true, false, true);
280 if (!bufptr)
281 break; // end of file
282 if (!strcmp(com_token, "\n"))
283 continue; // empty line
284 start = atoi(com_token);
285
286 // REQUIRED: fetch length
287 COM_ParseToken_Simple(&bufptr, true, false, true);
288 if (!bufptr || !strcmp(com_token, "\n"))
289 {
290 Con_Printf("framegroups file: missing number of frames\n");
291 continue;
292 }
293 len = atoi(com_token);
294
295 // OPTIONAL args start
296 COM_ParseToken_Simple(&bufptr, true, false, true);
297
298 // OPTIONAL: fetch fps
299 fps = 20;
300 if (bufptr && strcmp(com_token, "\n"))
301 {
302 fps = atof(com_token);
303 COM_ParseToken_Simple(&bufptr, true, false, true);
304 }
305
306 // OPTIONAL: fetch loopflag
307 loop = true;
308 if (bufptr && strcmp(com_token, "\n"))
309 {
310 loop = (atoi(com_token) != 0);
311 COM_ParseToken_Simple(&bufptr, true, false, true);
312 }
313
314 // OPTIONAL: fetch name
315 name[0] = 0;
316 if (bufptr && strcmp(com_token, "\n"))
317 {
318 dp_strlcpy(name, com_token, sizeof(name));
319 COM_ParseToken_Simple(&bufptr, true, false, true);
320 }
321
322 // OPTIONAL: remaining unsupported tokens (eat them)
323 while (bufptr && strcmp(com_token, "\n"))
324 COM_ParseToken_Simple(&bufptr, true, false, true);
325
326 //Con_Printf("data: %d %d %d %f %d (%s)\n", i, start, len, fps, loop, name);
327
328 if(cb)
329 cb(i, start, len, fps, loop, (name[0] ? name : NULL), pass);
330 ++i;
331 }
332
333 return i;
334}
char com_token[MAX_INPUTLINE]
Definition common.c:39
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
Definition common.c:463

References buf, COM_ParseToken_Simple(), com_token, Con_Printf(), dp_strlcpy, i, name, and NULL.

Referenced by Mod_FrameGroupify().

◆ Mod_FrameGroupify_ParseGroups_Store()

static void Mod_FrameGroupify_ParseGroups_Store ( unsigned int i,
int start,
int len,
float fps,
qbool loop,
const char * name,
void * pass )
static

Definition at line 336 of file model_shared.c.

337{
338 model_t *mod = (model_t *) pass;
339 animscene_t *anim = &mod->animscenes[i];
340 if(name)
341 dp_strlcpy(anim->name, name, sizeof(anim[i].name));
342 else
343 dpsnprintf(anim->name, sizeof(anim[i].name), "groupified_%d_anim", i);
344 anim->firstframe = bound(0, start, mod->num_poses - 1);
345 anim->framecount = bound(1, len, mod->num_poses - anim->firstframe);
346 anim->framerate = max(1, fps);
347 anim->loop = !!loop;
348 //Con_Printf("frame group %d is %d %d %f %d\n", i, start, len, fps, loop);
349}
#define bound(min, num, max)
Definition mathlib.h:34
char name[32]
float framerate

References bound, dp_strlcpy, dpsnprintf(), animscene_t::firstframe, animscene_t::framecount, animscene_t::framerate, i, animscene_t::loop, max, mod(), animscene_t::name, and name.

Referenced by Mod_FrameGroupify().

◆ Mod_FreeQ3Shaders()

void Mod_FreeQ3Shaders ( void )

Definition at line 1403 of file model_shared.c.

1404{
1406}
static mempool_t * q3shaders_mem
#define Mem_FreePool(pool)
Definition zone.h:105

References Mem_FreePool, and q3shaders_mem.

Referenced by CL_BeginDownloads(), CL_SignonReply(), Mod_LoadQ3Shaders(), mod_shutdown(), and SV_SpawnServer().

◆ Mod_FreeSkinFiles()

void Mod_FreeSkinFiles ( skinfile_t * skinfile)

Definition at line 2810 of file model_shared.c.

2811{
2812 skinfile_t *next;
2813 skinfileitem_t *skinfileitem, *nextitem;
2814 for (;skinfile;skinfile = next)
2815 {
2816 next = skinfile->next;
2817 for (skinfileitem = skinfile->items;skinfileitem;skinfileitem = nextitem)
2818 {
2819 nextitem = skinfileitem->next;
2820 Mem_Free(skinfileitem);
2821 }
2822 Mem_Free(skinfile);
2823 }
2824}
skinfileitem_t * items
struct skinfileitem_s * next

References skinfile_t::items, Mem_Free, skinfile_t::next, and skinfileitem_t::next.

Referenced by Mod_DARKPLACESMODEL_Load(), Mod_IDP0_Load(), Mod_IDP2_Load(), Mod_IDP3_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), and Mod_ZYMOTICMODEL_Load().

◆ Mod_GenerateLightmaps()

static void Mod_GenerateLightmaps ( model_t * model)
static

Definition at line 4407 of file model_shared.c.

4408{
4409 //lightmaptriangle_t *lightmaptriangles = Mem_Alloc(model->mempool, model->surfmesh.num_triangles * sizeof(lightmaptriangle_t));
4410 model_t *oldloadmodel = loadmodel;
4411 loadmodel = model;
4412
4424
4425 loadmodel = oldloadmodel;
4426}
static void Mod_GenerateLightmaps_UnweldTriangles(model_t *model)
static void Mod_GenerateLightmaps_InitSampleOffsets(model_t *model)
cvar_t mod_q3bsp_nolightmaps
Definition model_brush.c:45
static void Mod_GenerateLightmaps_CreateLightmaps(model_t *model)
static void Mod_GenerateLightmaps_CreateLights(model_t *model)
static void Mod_GenerateLightmaps_DestroyLights(model_t *model)
static void Mod_GenerateLightmaps_CreateTriangleInformation(model_t *model)
static void Mod_GenerateLightmaps_DestroyLightmaps(model_t *model)
static void Mod_GenerateLightmaps_DestroyTriangleInformation(model_t *model)
static void Mod_GenerateLightmaps_UpdateVertexColors(model_t *model)
static void Mod_GenerateLightmaps_UpdateLightGrid(model_t *model)

References cvar_t::integer, loadmodel, Mod_GenerateLightmaps_CreateLightmaps(), Mod_GenerateLightmaps_CreateLights(), Mod_GenerateLightmaps_CreateTriangleInformation(), Mod_GenerateLightmaps_DestroyLightmaps(), Mod_GenerateLightmaps_DestroyLights(), Mod_GenerateLightmaps_DestroyTriangleInformation(), Mod_GenerateLightmaps_InitSampleOffsets(), Mod_GenerateLightmaps_UnweldTriangles(), Mod_GenerateLightmaps_UpdateLightGrid(), Mod_GenerateLightmaps_UpdateVertexColors(), mod_q3bsp_nolightmaps, and model.

Referenced by Mod_GenerateLightmaps_f().

◆ Mod_GenerateLightmaps_CreateLightmaps()

static void Mod_GenerateLightmaps_CreateLightmaps ( model_t * model)
static

Definition at line 4123 of file model_shared.c.

4124{
4125 msurface_t *surface;
4126 int surfaceindex;
4127 int lightmapindex;
4128 int lightmapnumber;
4129 int i;
4130 int j;
4131 int k;
4132 int x;
4133 int y;
4134 int axis;
4135 int axis1;
4136 int axis2;
4137 int retry;
4138 int pixeloffset;
4139 float trianglenormal[3];
4140 float samplecenter[3];
4141 float samplenormal[3];
4142 float temp[3];
4143 float lmiscale[2];
4144 float slopex;
4145 float slopey;
4146 float slopebase;
4147 float lmscalepixels;
4148 float lmmins;
4149 float lmmaxs;
4150 float lm_basescalepixels;
4151 int lm_borderpixels;
4152 int lm_texturesize;
4153 //int lm_maxpixels;
4154 const int *e;
4155 lightmaptriangle_t *triangle;
4156 unsigned char *lightmappixels;
4157 unsigned char *deluxemappixels;
4159 char vabuf[1024];
4160
4161 // generate lightmap projection information for all triangles
4162 if (model->texturepool == NULL)
4163 model->texturepool = R_AllocTexturePool();
4164 lm_basescalepixels = 1.0f / max(0.0001f, mod_generatelightmaps_unitspersample.value);
4166 lm_texturesize = bound(lm_borderpixels*2+1, 64, (int)vid.maxtexturesize_2d);
4167 //lm_maxpixels = lm_texturesize-(lm_borderpixels*2+1);
4168 Mod_AllocLightmap_Init(&lmstate, loadmodel->mempool, lm_texturesize, lm_texturesize);
4169 lightmapnumber = 0;
4170 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
4171 {
4172 surface = model->data_surfaces + surfaceindex;
4173 e = model->surfmesh.data_element3i + surface->num_firsttriangle*3;
4174 lmscalepixels = lm_basescalepixels;
4175 for (retry = 0;retry < 30;retry++)
4176 {
4177 // after a couple failed attempts, degrade quality to make it fit
4178 if (retry > 1)
4179 lmscalepixels *= 0.5f;
4180 for (i = 0;i < surface->num_triangles;i++)
4181 {
4183 triangle->lightmapindex = lightmapnumber;
4184 // calculate lightmap bounds in 3D pixel coordinates, limit size,
4185 // pick two planar axes for projection
4186 // lightmap coordinates here are in pixels
4187 // lightmap projections are snapped to pixel grid explicitly, such
4188 // that two neighboring triangles sharing an edge and projection
4189 // axis will have identical sample spacing along their shared edge
4190 k = 0;
4191 for (j = 0;j < 3;j++)
4192 {
4193 if (j == triangle->axis)
4194 continue;
4195 lmmins = floor(triangle->mins[j]*lmscalepixels)-lm_borderpixels;
4196 lmmaxs = floor(triangle->maxs[j]*lmscalepixels)+lm_borderpixels;
4197 triangle->lmsize[k] = (int)(lmmaxs-lmmins);
4198 triangle->lmbase[k] = lmmins/lmscalepixels;
4199 triangle->lmscale[k] = lmscalepixels;
4200 k++;
4201 }
4202 if (!Mod_AllocLightmap_Block(&lmstate, triangle->lmsize[0], triangle->lmsize[1], &triangle->lmoffset[0], &triangle->lmoffset[1]))
4203 break;
4204 }
4205 // if all fit in this texture, we're done with this surface
4206 if (i == surface->num_triangles)
4207 break;
4208 // if we haven't maxed out the lightmap size yet, we retry the
4209 // entire surface batch...
4210 if (lm_texturesize * 2 <= min(mod_generatelightmaps_texturesize.integer, (int)vid.maxtexturesize_2d))
4211 {
4212 lm_texturesize *= 2;
4213 surfaceindex = -1;
4214 lightmapnumber = 0;
4215 Mod_AllocLightmap_Free(&lmstate);
4216 Mod_AllocLightmap_Init(&lmstate, loadmodel->mempool, lm_texturesize, lm_texturesize);
4217 break;
4218 }
4219 // if we have maxed out the lightmap size, and this triangle does
4220 // not fit in the same texture as the rest of the surface, we have
4221 // to retry the entire surface in a new texture (can only use one)
4222 // with multiple retries, the lightmap quality degrades until it
4223 // fits (or gives up)
4224 if (surfaceindex > 0)
4225 lightmapnumber++;
4226 Mod_AllocLightmap_Reset(&lmstate);
4227 }
4228 }
4229 lightmapnumber++;
4230 Mod_AllocLightmap_Free(&lmstate);
4231
4232 // now put triangles together into lightmap textures, and do not allow
4233 // triangles of a surface to go into different textures (as that would
4234 // require rewriting the surface list)
4235 model->brushq3.deluxemapping_modelspace = true;
4236 model->brushq3.deluxemapping = true;
4237 model->brushq3.num_mergedlightmaps = lightmapnumber;
4238 model->brushq3.data_lightmaps = (rtexture_t **)Mem_Alloc(model->mempool, model->brushq3.num_mergedlightmaps * sizeof(rtexture_t *));
4239 model->brushq3.data_deluxemaps = (rtexture_t **)Mem_Alloc(model->mempool, model->brushq3.num_mergedlightmaps * sizeof(rtexture_t *));
4240 lightmappixels = (unsigned char *)Mem_Alloc(tempmempool, model->brushq3.num_mergedlightmaps * lm_texturesize * lm_texturesize * 4);
4241 deluxemappixels = (unsigned char *)Mem_Alloc(tempmempool, model->brushq3.num_mergedlightmaps * lm_texturesize * lm_texturesize * 4);
4242 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
4243 {
4244 surface = model->data_surfaces + surfaceindex;
4245 e = model->surfmesh.data_element3i + surface->num_firsttriangle*3;
4246 for (i = 0;i < surface->num_triangles;i++)
4247 {
4249 TriangleNormal(triangle->vertex[0], triangle->vertex[1], triangle->vertex[2], trianglenormal);
4250 VectorNormalize(trianglenormal);
4251 VectorCopy(trianglenormal, samplenormal); // FIXME: this is supposed to be interpolated per pixel from vertices
4252 axis = triangle->axis;
4253 axis1 = axis == 0 ? 1 : 0;
4254 axis2 = axis == 2 ? 1 : 2;
4255 lmiscale[0] = 1.0f / triangle->lmscale[0];
4256 lmiscale[1] = 1.0f / triangle->lmscale[1];
4257 if (trianglenormal[axis] < 0)
4258 VectorNegate(trianglenormal, trianglenormal);
4259 CrossProduct(lmaxis[axis2], trianglenormal, temp);slopex = temp[axis] / temp[axis1];
4260 CrossProduct(lmaxis[axis1], trianglenormal, temp);slopey = temp[axis] / temp[axis2];
4261 slopebase = triangle->vertex[0][axis] - triangle->vertex[0][axis1]*slopex - triangle->vertex[0][axis2]*slopey;
4262 for (j = 0;j < 3;j++)
4263 {
4264 float *t2f = model->surfmesh.data_texcoordlightmap2f + e[i*3+j]*2;
4265 t2f[0] = ((triangle->vertex[j][axis1] - triangle->lmbase[0]) * triangle->lmscale[0] + triangle->lmoffset[0]) / lm_texturesize;
4266 t2f[1] = ((triangle->vertex[j][axis2] - triangle->lmbase[1]) * triangle->lmscale[1] + triangle->lmoffset[1]) / lm_texturesize;
4267#if 0
4268 samplecenter[axis1] = (t2f[0]*lm_texturesize-triangle->lmoffset[0])*lmiscale[0] + triangle->lmbase[0];
4269 samplecenter[axis2] = (t2f[1]*lm_texturesize-triangle->lmoffset[1])*lmiscale[1] + triangle->lmbase[1];
4270 samplecenter[axis] = samplecenter[axis1]*slopex + samplecenter[axis2]*slopey + slopebase;
4271 Con_Printf("%f:%f %f:%f %f:%f = %f %f\n", triangle->vertex[j][axis1], samplecenter[axis1], triangle->vertex[j][axis2], samplecenter[axis2], triangle->vertex[j][axis], samplecenter[axis], t2f[0], t2f[1]);
4272#endif
4273 }
4274
4275#if 0
4276 switch (axis)
4277 {
4278 default:
4279 case 0:
4280 forward[0] = 0;
4281 forward[1] = 1.0f / triangle->lmscale[0];
4282 forward[2] = 0;
4283 left[0] = 0;
4284 left[1] = 0;
4285 left[2] = 1.0f / triangle->lmscale[1];
4286 up[0] = 1.0f;
4287 up[1] = 0;
4288 up[2] = 0;
4289 origin[0] = 0;
4290 origin[1] = triangle->lmbase[0];
4291 origin[2] = triangle->lmbase[1];
4292 break;
4293 case 1:
4294 forward[0] = 1.0f / triangle->lmscale[0];
4295 forward[1] = 0;
4296 forward[2] = 0;
4297 left[0] = 0;
4298 left[1] = 0;
4299 left[2] = 1.0f / triangle->lmscale[1];
4300 up[0] = 0;
4301 up[1] = 1.0f;
4302 up[2] = 0;
4303 origin[0] = triangle->lmbase[0];
4304 origin[1] = 0;
4305 origin[2] = triangle->lmbase[1];
4306 break;
4307 case 2:
4308 forward[0] = 1.0f / triangle->lmscale[0];
4309 forward[1] = 0;
4310 forward[2] = 0;
4311 left[0] = 0;
4312 left[1] = 1.0f / triangle->lmscale[1];
4313 left[2] = 0;
4314 up[0] = 0;
4315 up[1] = 0;
4316 up[2] = 1.0f;
4317 origin[0] = triangle->lmbase[0];
4318 origin[1] = triangle->lmbase[1];
4319 origin[2] = 0;
4320 break;
4321 }
4322 Matrix4x4_FromVectors(&backmatrix, forward, left, up, origin);
4323#endif
4324#define LM_DIST_EPSILON (1.0f / 32.0f)
4325 for (y = 0;y < triangle->lmsize[1];y++)
4326 {
4327 pixeloffset = ((triangle->lightmapindex * lm_texturesize + y + triangle->lmoffset[1]) * lm_texturesize + triangle->lmoffset[0]) * 4;
4328 for (x = 0;x < triangle->lmsize[0];x++, pixeloffset += 4)
4329 {
4330 samplecenter[axis1] = (x+0.5f)*lmiscale[0] + triangle->lmbase[0];
4331 samplecenter[axis2] = (y+0.5f)*lmiscale[1] + triangle->lmbase[1];
4332 samplecenter[axis] = samplecenter[axis1]*slopex + samplecenter[axis2]*slopey + slopebase;
4333 VectorMA(samplecenter, 0.125f, samplenormal, samplecenter);
4334 Mod_GenerateLightmaps_LightmapSample(samplecenter, samplenormal, lightmappixels + pixeloffset, deluxemappixels + pixeloffset);
4335 }
4336 }
4337 }
4338 }
4339
4340 for (lightmapindex = 0;lightmapindex < model->brushq3.num_mergedlightmaps;lightmapindex++)
4341 {
4342 model->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va(vabuf, sizeof(vabuf), "lightmap%i", lightmapindex), lm_texturesize, lm_texturesize, lightmappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
4343 model->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va(vabuf, sizeof(vabuf), "deluxemap%i", lightmapindex), lm_texturesize, lm_texturesize, deluxemappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
4344 }
4345
4346 if (lightmappixels)
4347 Mem_Free(lightmappixels);
4348 if (deluxemappixels)
4349 Mem_Free(deluxemappixels);
4350
4351 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
4352 {
4353 surface = model->data_surfaces + surfaceindex;
4354 if (!surface->num_triangles)
4355 continue;
4357 surface->lightmaptexture = model->brushq3.data_lightmaps[lightmapindex];
4358 surface->deluxemaptexture = model->brushq3.data_deluxemaps[lightmapindex];
4359 surface->lightmapinfo = NULL;
4360 }
4361
4362 model->brush.LightPoint = Mod_GenerateLightmaps_LightPoint;
4363 model->brushq1.lightdata = NULL;
4364 model->brushq1.lightmapupdateflags = NULL;
4365 model->brushq1.firstrender = false;
4366 model->brushq1.num_lightstyles = 0;
4367 model->brushq1.data_lightstyleinfo = NULL;
4368 for (i = 0;i < model->brush.numsubmodels;i++)
4369 {
4370 model->brush.submodels[i]->brushq1.lightmapupdateflags = NULL;
4371 model->brush.submodels[i]->brushq1.firstrender = false;
4372 model->brush.submodels[i]->brushq1.num_lightstyles = 0;
4373 model->brush.submodels[i]->brushq1.data_lightstyleinfo = NULL;
4374 }
4375}
vector origin
rtexturepool_t * R_AllocTexturePool(void)
rtexture_t * R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
GLint GLenum GLint x
Definition glquake.h:651
#define min(A, B)
Definition mathlib.h:37
#define VectorCopy(in, out)
Definition mathlib.h:101
void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
Definition matrixlib.c:970
float floor(float f)
void Mod_AllocLightmap_Reset(mod_alloclightmap_state_t *state)
cvar_t mod_generatelightmaps_borderpixels
void Mod_AllocLightmap_Init(mod_alloclightmap_state_t *state, mempool_t *mempool, int width, int height)
void Mod_AllocLightmap_Free(mod_alloclightmap_state_t *state)
static void Mod_GenerateLightmaps_LightPoint(model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
cvar_t mod_generatelightmaps_texturesize
qbool Mod_AllocLightmap_Block(mod_alloclightmap_state_t *state, int blockwidth, int blockheight, int *outx, int *outy)
static void Mod_GenerateLightmaps_LightmapSample(const float *pos, const float *normal, unsigned char *lm_bgr, unsigned char *lm_dir)
lightmaptriangle_t * mod_generatelightmaps_lightmaptriangles
cvar_t mod_generatelightmaps_unitspersample
float lmaxis[3][3]
#define TEXF_FORCELINEAR
Definition r_textures.h:19
@ TEXTYPE_BGRA
Definition r_textures.h:53
float value
Definition cvar.h:74
struct mempool_s * mempool
msurface_lightmapinfo_t * lightmapinfo
lightmaptexture rebuild information not used in q3bsp
struct rtexture_s * deluxemaptexture
the lighting direction texture fragment to use on the rendering mesh
struct rtexture_s * lightmaptexture
the lightmap texture fragment to use on the rendering mesh
unsigned int maxtexturesize_2d
Definition vid.h:83
static vec3_t forward
Definition sv_user.c:305
static vec3_t up
Definition sv_user.c:305
viddef_t vid
global video state
Definition vid_shared.c:64

References lightmaptriangle_t::axis, bound, Con_Printf(), CrossProduct, msurface_t::deluxemaptexture, floor(), forward, i, int(), cvar_t::integer, lightmaptriangle_t::lightmapindex, msurface_t::lightmapinfo, msurface_t::lightmaptexture, lmaxis, lightmaptriangle_t::lmbase, lightmaptriangle_t::lmoffset, lightmaptriangle_t::lmscale, lightmaptriangle_t::lmsize, loadmodel, Matrix4x4_FromVectors(), max, lightmaptriangle_t::maxs, viddef_t::maxtexturesize_2d, Mem_Alloc, Mem_Free, model_t::mempool, min, lightmaptriangle_t::mins, Mod_AllocLightmap_Block(), Mod_AllocLightmap_Free(), Mod_AllocLightmap_Init(), Mod_AllocLightmap_Reset(), mod_generatelightmaps_borderpixels, Mod_GenerateLightmaps_LightmapSample(), mod_generatelightmaps_lightmaptriangles, Mod_GenerateLightmaps_LightPoint(), mod_generatelightmaps_texturesize, mod_generatelightmaps_unitspersample, model, NULL, msurface_t::num_firsttriangle, msurface_t::num_triangles, origin, R_AllocTexturePool(), R_LoadTexture2D(), tempmempool, TEXF_FORCELINEAR, TEXTYPE_BGRA, TriangleNormal, up, va(), cvar_t::value, VectorCopy, VectorMA, VectorNegate, VectorNormalize, lightmaptriangle_t::vertex, vid, x, and y.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_CreateLights()

static void Mod_GenerateLightmaps_CreateLights ( model_t * model)
static

Definition at line 3716 of file model_shared.c.

3717{
3718 int index;
3719 int result;
3720 lightmaplight_t *lightinfo;
3721 float origin[3];
3722 float radius;
3723 float color[3];
3725 for (index = 0;;index++)
3726 {
3727 result = R_Shadow_GetRTLightInfo(index, origin, &radius, color);
3728 if (result < 0)
3729 break;
3730 if (result > 0)
3732 }
3734 {
3737 for (index = 0;;index++)
3738 {
3739 result = R_Shadow_GetRTLightInfo(index, lightinfo->origin, &lightinfo->radius, lightinfo->color);
3740 if (result < 0)
3741 break;
3742 if (result > 0)
3743 lightinfo++;
3744 }
3745 }
3747 {
3748 lightinfo->iradius = 1.0f / lightinfo->radius;
3749 lightinfo->radius2 = lightinfo->radius * lightinfo->radius;
3750 // TODO: compute svbsp
3752 }
3753}
vector color
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(model_t *model, lightmaplight_t *lightinfo)
static lightmaplight_t * mod_generatelightmaps_lightinfo
static int mod_generatelightmaps_numlights
int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color)
Definition r_shadow.c:4777

References color, lightmaplight_t::color, index, lightmaplight_t::iradius, Mem_Alloc, Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(), mod_generatelightmaps_lightinfo, mod_generatelightmaps_numlights, model, lightmaplight_t::origin, origin, R_Shadow_GetRTLightInfo(), lightmaplight_t::radius, lightmaplight_t::radius2, and tempmempool.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_CreateLights_ComputeSVBSP()

static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP ( model_t * model,
lightmaplight_t * lightinfo )
static

Definition at line 3677 of file model_shared.c.

3678{
3679 int maxnodes = 1<<14;
3680 svbsp_node_t *nodes;
3681 float origin[3];
3682 float mins[3];
3683 float maxs[3];
3684 svbsp_t svbsp;
3685 VectorSet(mins, lightinfo->origin[0] - lightinfo->radius, lightinfo->origin[1] - lightinfo->radius, lightinfo->origin[2] - lightinfo->radius);
3686 VectorSet(maxs, lightinfo->origin[0] + lightinfo->radius, lightinfo->origin[1] + lightinfo->radius, lightinfo->origin[2] + lightinfo->radius);
3687 VectorCopy(lightinfo->origin, origin);
3688 nodes = (svbsp_node_t *)Mem_Alloc(tempmempool, maxnodes * sizeof(*nodes));
3689 for (;;)
3690 {
3691 SVBSP_Init(&svbsp, origin, maxnodes, nodes);
3693 if (svbsp.ranoutofnodes)
3694 {
3695 maxnodes *= 16;
3696 if (maxnodes > 1<<22)
3697 {
3698 Mem_Free(nodes);
3699 return;
3700 }
3701 Mem_Free(nodes);
3702 nodes = (svbsp_node_t *)Mem_Alloc(tempmempool, maxnodes * sizeof(*nodes));
3703 }
3704 else
3705 break;
3706 }
3707 if (svbsp.numnodes > 0)
3708 {
3709 svbsp.nodes = (svbsp_node_t *)Mem_Alloc(tempmempool, svbsp.numnodes * sizeof(*nodes));
3710 memcpy(svbsp.nodes, nodes, svbsp.numnodes * sizeof(*nodes));
3711 lightinfo->svbsp = svbsp;
3712 }
3713 Mem_Free(nodes);
3714}
vector mins
vector maxs
#define VectorSet(vec, x, y, z)
Definition mathlib.h:96
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
int numnodes
Definition svbsp.h:26
int ranoutofnodes
Definition svbsp.h:32
svbsp_node_t * nodes
Definition svbsp.h:30
void SVBSP_Init(svbsp_t *b, const float *origin, int maxnodes, svbsp_node_t *nodes)
Definition svbsp.c:99

References maxs, Mem_Alloc, Mem_Free, mins, Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(), model, svbsp_t::nodes, svbsp_t::numnodes, lightmaplight_t::origin, origin, lightmaplight_t::radius, svbsp_t::ranoutofnodes, lightmaplight_t::svbsp, SVBSP_Init(), tempmempool, VectorCopy, and VectorSet.

Referenced by Mod_GenerateLightmaps_CreateLights().

◆ Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces()

static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces ( const model_t * model,
svbsp_t * svbsp,
const float * mins,
const float * maxs )
static

Definition at line 3651 of file model_shared.c.

3652{
3653 int surfaceindex;
3654 int triangleindex;
3655 const msurface_t *surface;
3656 const float *vertex3f = model->surfmesh.data_vertex3f;
3657 const int *element3i = model->surfmesh.data_element3i;
3658 const int *e;
3659 float v2[3][3];
3660 for (surfaceindex = model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
3661 {
3662 surface = model->data_surfaces + surfaceindex;
3663 if (!BoxesOverlap(surface->mins, surface->maxs, mins, maxs))
3664 continue;
3666 continue;
3667 for (triangleindex = 0, e = element3i + 3*surface->num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
3668 {
3669 VectorCopy(vertex3f + 3*e[0], v2[0]);
3670 VectorCopy(vertex3f + 3*e[1], v2[1]);
3671 VectorCopy(vertex3f + 3*e[2], v2[2]);
3672 SVBSP_AddPolygon(svbsp, 3, v2[0], true, NULL, NULL, 0);
3673 }
3674 }
3675}
#define BoxesOverlap(a, b, c, d)
Definition mathlib.h:122
#define MATERIALFLAG_NOSHADOW
vec3_t mins
bounding box for onscreen checks
int basematerialflags
int SVBSP_AddPolygon(svbsp_t *b, int numpoints, const float *points, int insertoccluder, void(*fragmentcallback)(void *fragmentcallback_pointer1, int fragmentcallback_number1, svbsp_t *b, int numpoints, const float *points), void *fragmentcallback_pointer1, int fragmentcallback_number1)
Definition svbsp.c:403

References texture_t::basematerialflags, BoxesOverlap, MATERIALFLAG_NOSHADOW, maxs, msurface_t::maxs, mins, msurface_t::mins, model, NULL, msurface_t::num_firsttriangle, SVBSP_AddPolygon(), msurface_t::texture, v2, and VectorCopy.

Referenced by Mod_GenerateLightmaps_CreateLights_ComputeSVBSP().

◆ Mod_GenerateLightmaps_CreateTriangleInformation()

static void Mod_GenerateLightmaps_CreateTriangleInformation ( model_t * model)
static

Definition at line 4072 of file model_shared.c.

4073{
4074 msurface_t *surface;
4075 int surfaceindex;
4076 int i;
4077 int axis;
4078 float normal[3];
4079 const int *e;
4080 lightmaptriangle_t *triangle;
4081 // generate lightmap triangle structs
4083 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
4084 {
4085 surface = model->data_surfaces + surfaceindex;
4086 e = model->surfmesh.data_element3i + surface->num_firsttriangle*3;
4087 for (i = 0;i < surface->num_triangles;i++)
4088 {
4090 triangle->triangleindex = surface->num_firsttriangle+i;
4091 triangle->surfaceindex = surfaceindex;
4092 VectorCopy(model->surfmesh.data_vertex3f + 3*e[i*3+0], triangle->vertex[0]);
4093 VectorCopy(model->surfmesh.data_vertex3f + 3*e[i*3+1], triangle->vertex[1]);
4094 VectorCopy(model->surfmesh.data_vertex3f + 3*e[i*3+2], triangle->vertex[2]);
4095 // calculate bounds of triangle
4096 triangle->mins[0] = min(triangle->vertex[0][0], min(triangle->vertex[1][0], triangle->vertex[2][0]));
4097 triangle->mins[1] = min(triangle->vertex[0][1], min(triangle->vertex[1][1], triangle->vertex[2][1]));
4098 triangle->mins[2] = min(triangle->vertex[0][2], min(triangle->vertex[1][2], triangle->vertex[2][2]));
4099 triangle->maxs[0] = max(triangle->vertex[0][0], max(triangle->vertex[1][0], triangle->vertex[2][0]));
4100 triangle->maxs[1] = max(triangle->vertex[0][1], max(triangle->vertex[1][1], triangle->vertex[2][1]));
4101 triangle->maxs[2] = max(triangle->vertex[0][2], max(triangle->vertex[1][2], triangle->vertex[2][2]));
4102 // pick an axial projection based on the triangle normal
4103 TriangleNormal(triangle->vertex[0], triangle->vertex[1], triangle->vertex[2], normal);
4104 axis = 0;
4105 if (fabs(normal[1]) > fabs(normal[axis]))
4106 axis = 1;
4107 if (fabs(normal[2]) > fabs(normal[axis]))
4108 axis = 2;
4109 triangle->axis = axis;
4110 }
4111 }
4112}
float fabs(float f)

References lightmaptriangle_t::axis, fabs(), i, max, lightmaptriangle_t::maxs, Mem_Alloc, min, lightmaptriangle_t::mins, mod_generatelightmaps_lightmaptriangles, model, normal, msurface_t::num_firsttriangle, msurface_t::num_triangles, lightmaptriangle_t::surfaceindex, lightmaptriangle_t::triangleindex, TriangleNormal, VectorCopy, and lightmaptriangle_t::vertex.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_DestroyLightmaps()

static void Mod_GenerateLightmaps_DestroyLightmaps ( model_t * model)
static

Definition at line 3940 of file model_shared.c.

3941{
3942 msurface_t *surface;
3943 int surfaceindex;
3944 int i;
3945 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
3946 {
3947 surface = model->data_surfaces + surfaceindex;
3948 surface->lightmaptexture = NULL;
3949 surface->deluxemaptexture = NULL;
3950 }
3951 if (model->brushq3.data_lightmaps)
3952 {
3953 for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
3954 if (model->brushq3.data_lightmaps[i])
3955 R_FreeTexture(model->brushq3.data_lightmaps[i]);
3956 Mem_Free(model->brushq3.data_lightmaps);
3957 model->brushq3.data_lightmaps = NULL;
3958 }
3959 if (model->brushq3.data_deluxemaps)
3960 {
3961 for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
3962 if (model->brushq3.data_deluxemaps[i])
3963 R_FreeTexture(model->brushq3.data_deluxemaps[i]);
3964 Mem_Free(model->brushq3.data_deluxemaps);
3965 model->brushq3.data_deluxemaps = NULL;
3966 }
3967}
void R_FreeTexture(rtexture_t *rt)

References msurface_t::deluxemaptexture, i, msurface_t::lightmaptexture, Mem_Free, model, NULL, and R_FreeTexture().

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_DestroyLights()

static void Mod_GenerateLightmaps_DestroyLights ( model_t * model)
static

◆ Mod_GenerateLightmaps_DestroyTriangleInformation()

static void Mod_GenerateLightmaps_DestroyTriangleInformation ( model_t * model)
static

◆ Mod_GenerateLightmaps_f()

static void Mod_GenerateLightmaps_f ( cmd_state_t * cmd)
static

Definition at line 4428 of file model_shared.c.

4429{
4430 if (Cmd_Argc(cmd) != 1)
4431 {
4432 Con_Printf("usage: mod_generatelightmaps\n");
4433 return;
4434 }
4435 if (!cl.worldmodel)
4436 {
4437 Con_Printf("no worldmodel loaded\n");
4438 return;
4439 }
4441}
static void Mod_GenerateLightmaps(model_t *model)
struct model_s * worldmodel
Definition client.h:934

References cl, cmd(), Cmd_Argc(), Con_Printf(), Mod_GenerateLightmaps(), and client_state_t::worldmodel.

Referenced by Mod_Init().

◆ Mod_GenerateLightmaps_GridSample()

static void Mod_GenerateLightmaps_GridSample ( const float * pos,
q3dlightgrid_t * s )
static

Definition at line 3888 of file model_shared.c.

3889{
3890 float sample[5*3];
3891 float ambient[3];
3892 float diffuse[3];
3893 float dir[3];
3895 // calculate the direction we'll use to reduce the sample to a directional light source
3896 VectorCopy(sample + 12, dir);
3897 //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
3899 // extract the diffuse color along the chosen direction and scale it
3900 diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]) * 127.5f;
3901 diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]) * 127.5f;
3902 diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]) * 127.5f;
3903 // scale the ambient from 0-2 to 0-255 and subtract some of diffuse
3904 VectorScale(sample, 127.5f, ambient);
3905 VectorMA(ambient, -0.333f, diffuse, ambient);
3906 // encode to the grid format
3907 s->ambientrgb[0] = (unsigned char)bound(0.0f, ambient[0], 255.0f);
3908 s->ambientrgb[1] = (unsigned char)bound(0.0f, ambient[1], 255.0f);
3909 s->ambientrgb[2] = (unsigned char)bound(0.0f, ambient[2], 255.0f);
3910 s->diffusergb[0] = (unsigned char)bound(0.0f, diffuse[0], 255.0f);
3911 s->diffusergb[1] = (unsigned char)bound(0.0f, diffuse[1], 255.0f);
3912 s->diffusergb[2] = (unsigned char)bound(0.0f, diffuse[2], 255.0f);
3913 if (dir[2] >= 0.99f) {s->diffusepitch = 0;s->diffuseyaw = 0;}
3914 else if (dir[2] <= -0.99f) {s->diffusepitch = 128;s->diffuseyaw = 0;}
3915 else {s->diffusepitch = (unsigned char)(acos(dir[2]) * (127.5f/M_PI));s->diffuseyaw = (unsigned char)(atan2(dir[1], dir[0]) * (127.5f/M_PI));}
3916}
#define VectorScale(in, scale, out)
Definition mathlib.h:111
#define M_PI
Definition mathlib.h:28
static void Mod_GenerateLightmaps_SamplePoint(const float *pos, const float *normal, float *sample, int numoffsets, const float *offsets)
static float mod_generatelightmaps_offsets[3][MAX_LIGHTMAPSAMPLES][3]
static int mod_generatelightmaps_numoffsets[3]
vec2 dir
unsigned char diffusergb[3]
unsigned char ambientrgb[3]
unsigned char diffuseyaw
unsigned char diffusepitch

References q3dlightgrid_t::ambientrgb, bound, q3dlightgrid_t::diffusepitch, q3dlightgrid_t::diffusergb, q3dlightgrid_t::diffuseyaw, dir, M_PI, mod_generatelightmaps_numoffsets, mod_generatelightmaps_offsets, Mod_GenerateLightmaps_SamplePoint(), NULL, VectorCopy, VectorMA, VectorNormalize, and VectorScale.

Referenced by Mod_GenerateLightmaps_UpdateLightGrid().

◆ Mod_GenerateLightmaps_InitSampleOffsets()

static void Mod_GenerateLightmaps_InitSampleOffsets ( model_t * model)
static

Definition at line 3918 of file model_shared.c.

3919{
3920 float radius[3];
3921 float temp[3];
3922 int i, j;
3930 for (i = 0;i < 3;i++)
3931 {
3932 for (j = 1;j < mod_generatelightmaps_numoffsets[i];j++)
3933 {
3934 VectorRandom(temp);
3935 VectorScale(temp, radius[i], mod_generatelightmaps_offsets[i][j]);
3936 }
3937 }
3938}
#define VectorRandom(v)
Definition mathlib.h:119
cvar_t mod_generatelightmaps_gridsamples
#define MAX_LIGHTMAPSAMPLES
cvar_t mod_generatelightmaps_lightmapradius
cvar_t mod_generatelightmaps_vertexsamples
cvar_t mod_generatelightmaps_lightmapsamples
cvar_t mod_generatelightmaps_vertexradius
cvar_t mod_generatelightmaps_gridradius

References i, cvar_t::integer, MAX_LIGHTMAPSAMPLES, min, mod_generatelightmaps_gridradius, mod_generatelightmaps_gridsamples, mod_generatelightmaps_lightmapradius, mod_generatelightmaps_lightmapsamples, mod_generatelightmaps_numoffsets, mod_generatelightmaps_offsets, mod_generatelightmaps_vertexradius, mod_generatelightmaps_vertexsamples, cvar_t::value, VectorRandom, and VectorScale.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_LightmapSample()

static void Mod_GenerateLightmaps_LightmapSample ( const float * pos,
const float * normal,
unsigned char * lm_bgr,
unsigned char * lm_dir )
static

Definition at line 3854 of file model_shared.c.

3855{
3856 float sample[5*3];
3857 float color[3];
3858 float dir[3];
3859 float f;
3861 //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
3862 VectorCopy(sample + 12, dir);
3864 //VectorAdd(dir, normal, dir);
3865 //VectorNormalize(dir);
3866 f = DotProduct(dir, normal);
3867 f = max(0, f) * 255.0f;
3868 VectorScale(sample, f, color);
3869 //VectorCopy(normal, dir);
3870 VectorSet(dir, (dir[0]+1.0f)*127.5f, (dir[1]+1.0f)*127.5f, (dir[2]+1.0f)*127.5f);
3871 lm_bgr[0] = (unsigned char)bound(0.0f, color[2], 255.0f);
3872 lm_bgr[1] = (unsigned char)bound(0.0f, color[1], 255.0f);
3873 lm_bgr[2] = (unsigned char)bound(0.0f, color[0], 255.0f);
3874 lm_bgr[3] = 255;
3875 lm_dir[0] = (unsigned char)dir[2];
3876 lm_dir[1] = (unsigned char)dir[1];
3877 lm_dir[2] = (unsigned char)dir[0];
3878 lm_dir[3] = 255;
3879}

References bound, color, dir, DotProduct, f, max, mod_generatelightmaps_numoffsets, mod_generatelightmaps_offsets, Mod_GenerateLightmaps_SamplePoint(), normal, VectorCopy, VectorNormalize, VectorScale, and VectorSet.

Referenced by Mod_GenerateLightmaps_CreateLightmaps().

◆ Mod_GenerateLightmaps_LightPoint()

static void Mod_GenerateLightmaps_LightPoint ( model_t * model,
const vec3_t pos,
vec3_t ambient,
vec3_t diffuse,
vec3_t lightdir )
static

Definition at line 3582 of file model_shared.c.

3583{
3584 int i;
3585 int index;
3586 int result;
3587 float relativepoint[3];
3588 float color[3];
3589 float dir[3];
3590 float dist;
3591 float dist2;
3592 float intensity;
3593 float sample[5*3];
3594 float lightorigin[3];
3595 float lightradius;
3596 float lightradius2;
3597 float lightiradius;
3598 float lightcolor[3];
3599 trace_t trace;
3600 for (i = 0;i < 5*3;i++)
3601 sample[i] = 0.0f;
3602 for (index = 0;;index++)
3603 {
3604 result = R_Shadow_GetRTLightInfo(index, lightorigin, &lightradius, lightcolor);
3605 if (result < 0)
3606 break;
3607 if (result == 0)
3608 continue;
3609 lightradius2 = lightradius * lightradius;
3610 VectorSubtract(lightorigin, pos, relativepoint);
3611 dist2 = VectorLength2(relativepoint);
3612 if (dist2 >= lightradius2)
3613 continue;
3614 lightiradius = 1.0f / lightradius;
3615 dist = sqrt(dist2) * lightiradius;
3617 if (intensity <= 0.0f)
3618 continue;
3619 if (model && model->TraceLine)
3620 {
3621 model->TraceLine(model, NULL, NULL, &trace, pos, lightorigin, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT | MATERIALFLAG_NOSHADOW);
3622 if (trace.fraction < 1)
3623 continue;
3624 }
3625 // scale down intensity to add to both ambient and diffuse
3626 //intensity *= 0.5f;
3627 VectorNormalize(relativepoint);
3628 VectorScale(lightcolor, intensity, color);
3629 VectorMA(sample , 0.5f , color, sample );
3630 VectorMA(sample + 3, relativepoint[0], color, sample + 3);
3631 VectorMA(sample + 6, relativepoint[1], color, sample + 6);
3632 VectorMA(sample + 9, relativepoint[2], color, sample + 9);
3633 // calculate a weighted average light direction as well
3635 VectorMA(sample + 12, intensity, relativepoint, sample + 12);
3636 }
3637 // calculate the direction we'll use to reduce the sample to a directional light source
3638 VectorCopy(sample + 12, dir);
3639 //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
3641 // extract the diffuse color along the chosen direction and scale it
3642 diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]);
3643 diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]);
3644 diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]);
3645 // subtract some of diffuse from ambient
3646 VectorMA(sample, -0.333f, diffuse, ambient);
3647 // store the normalized lightdir
3648 VectorCopy(dir, lightdir);
3649}
#define VectorLength(a)
Definition mathlib.h:109
#define VectorLength2(a)
Definition mathlib.h:110
float sqrt(float f)
#define MATERIALFLAGMASK_TRANSLUCENT
cvar_t r_shadow_lightattenuationdividebias
Definition r_shadow.c:153
cvar_t r_shadow_lightattenuationlinearscale
Definition r_shadow.c:154
float intensity
Definition snd_mix.c:314
double fraction
Definition collision.h:40

References color, dir, trace_t::fraction, i, index, intensity, MATERIALFLAG_NOSHADOW, MATERIALFLAGMASK_TRANSLUCENT, model, NULL, R_Shadow_GetRTLightInfo(), r_shadow_lightattenuationdividebias, r_shadow_lightattenuationlinearscale, sqrt(), SUPERCONTENTS_SOLID, cvar_t::value, VectorCopy, VectorLength, VectorLength2, VectorMA, VectorNormalize, VectorScale, and VectorSubtract.

Referenced by Mod_GenerateLightmaps_CreateLightmaps().

◆ Mod_GenerateLightmaps_SamplePoint()

static void Mod_GenerateLightmaps_SamplePoint ( const float * pos,
const float * normal,
float * sample,
int numoffsets,
const float * offsets )
static

Definition at line 3782 of file model_shared.c.

3783{
3784 int i;
3785 float relativepoint[3];
3786 float color[3];
3787 float offsetpos[3];
3788 float dist;
3789 float dist2;
3790 float intensity;
3791 int offsetindex;
3792 int hits;
3793 int tests;
3794 const lightmaplight_t *lightinfo;
3795 trace_t trace;
3796 for (i = 0;i < 5*3;i++)
3797 sample[i] = 0.0f;
3798 for (i = 0, lightinfo = mod_generatelightmaps_lightinfo;i < mod_generatelightmaps_numlights;i++, lightinfo++)
3799 {
3800 //R_SampleRTLights(pos, sample, numoffsets, offsets);
3801 VectorSubtract(lightinfo->origin, pos, relativepoint);
3802 // don't accept light from behind a surface, it causes bad shading
3803 if (normal && DotProduct(relativepoint, normal) <= 0)
3804 continue;
3805 dist2 = VectorLength2(relativepoint);
3806 if (dist2 >= lightinfo->radius2)
3807 continue;
3808 dist = sqrt(dist2) * lightinfo->iradius;
3809 intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
3810 if (intensity <= 0)
3811 continue;
3812 if (cl.worldmodel && cl.worldmodel->TraceLine && numoffsets > 0)
3813 {
3814 hits = 0;
3815 tests = 1;
3816 if (Mod_GenerateLightmaps_SamplePoint_SVBSP(&lightinfo->svbsp, pos))
3817 hits++;
3818 for (offsetindex = 1;offsetindex < numoffsets;offsetindex++)
3819 {
3820 VectorAdd(pos, offsets + 3*offsetindex, offsetpos);
3821 if (!normal)
3822 {
3823 // for light grid we'd better check visibility of the offset point
3825 if (trace.fraction < 1)
3826 VectorLerp(pos, trace.fraction, offsetpos, offsetpos);
3827 }
3828 tests++;
3829 if (Mod_GenerateLightmaps_SamplePoint_SVBSP(&lightinfo->svbsp, offsetpos))
3830 hits++;
3831 }
3832 if (!hits)
3833 continue;
3834 // scale intensity according to how many rays succeeded
3835 // we know one test is valid, half of the rest will fail...
3836 //if (normal && tests > 1)
3837 // intensity *= (tests - 1.0f) / tests;
3838 intensity *= (float)hits / tests;
3839 }
3840 // scale down intensity to add to both ambient and diffuse
3841 //intensity *= 0.5f;
3842 VectorNormalize(relativepoint);
3843 VectorScale(lightinfo->color, intensity, color);
3844 VectorMA(sample , 0.5f , color, sample );
3845 VectorMA(sample + 3, relativepoint[0], color, sample + 3);
3846 VectorMA(sample + 6, relativepoint[1], color, sample + 6);
3847 VectorMA(sample + 9, relativepoint[2], color, sample + 9);
3848 // calculate a weighted average light direction as well
3850 VectorMA(sample + 12, intensity, relativepoint, sample + 12);
3851 }
3852}
static vec3_t offsets[NUMOFFSETS]
Definition cl_input.c:838
#define VectorLerp(v1, lerp, v2, out)
Definition mathlib.h:120
static qbool Mod_GenerateLightmaps_SamplePoint_SVBSP(const svbsp_t *svbsp, const float *pos)
precision highp float
Definition shader_glsl.h:53

References cl, color, lightmaplight_t::color, DotProduct, float, trace_t::fraction, i, intensity, lightmaplight_t::iradius, MATERIALFLAG_NOSHADOW, MATERIALFLAGMASK_TRANSLUCENT, mod_generatelightmaps_lightinfo, mod_generatelightmaps_numlights, Mod_GenerateLightmaps_SamplePoint_SVBSP(), normal, NULL, offsets, lightmaplight_t::origin, r_shadow_lightattenuationdividebias, r_shadow_lightattenuationlinearscale, lightmaplight_t::radius2, sqrt(), SUPERCONTENTS_SOLID, lightmaplight_t::svbsp, cvar_t::value, VectorAdd, VectorLength, VectorLength2, VectorLerp, VectorMA, VectorNormalize, VectorScale, VectorSubtract, and client_state_t::worldmodel.

Referenced by Mod_GenerateLightmaps_GridSample(), Mod_GenerateLightmaps_LightmapSample(), and Mod_GenerateLightmaps_VertexSample().

◆ Mod_GenerateLightmaps_SamplePoint_SVBSP()

static qbool Mod_GenerateLightmaps_SamplePoint_SVBSP ( const svbsp_t * svbsp,
const float * pos )
static

Definition at line 3769 of file model_shared.c.

3770{
3771 const svbsp_node_t *node;
3772 const svbsp_node_t *nodes = svbsp->nodes;
3773 int num = 0;
3774 while (num >= 0)
3775 {
3776 node = nodes + num;
3777 num = node->children[DotProduct(node->plane, pos) < node->plane[3]];
3778 }
3779 return num == -1; // true if empty, false if solid (shadowed)
3780}
int children[2]
Definition svbsp.h:15
float plane[4]
Definition svbsp.h:17

References svbsp_node_t::children, DotProduct, svbsp_t::nodes, and svbsp_node_t::plane.

Referenced by Mod_GenerateLightmaps_SamplePoint().

◆ Mod_GenerateLightmaps_UnweldTriangles()

static void Mod_GenerateLightmaps_UnweldTriangles ( model_t * model)
static

Definition at line 3969 of file model_shared.c.

3970{
3971 msurface_t *surface;
3972 int surfaceindex;
3973 int vertexindex;
3974 int outvertexindex;
3975 int i;
3976 const int *e;
3977 surfmesh_t oldsurfmesh;
3978 size_t size;
3979 unsigned char *data;
3980 oldsurfmesh = model->surfmesh;
3981 model->surfmesh.num_triangles = oldsurfmesh.num_triangles;
3982 model->surfmesh.num_vertices = oldsurfmesh.num_triangles * 3;
3983 size = 0;
3984 size += model->surfmesh.num_vertices * sizeof(float[3]);
3985 size += model->surfmesh.num_vertices * sizeof(float[3]);
3986 size += model->surfmesh.num_vertices * sizeof(float[3]);
3987 size += model->surfmesh.num_vertices * sizeof(float[3]);
3988 size += model->surfmesh.num_vertices * sizeof(float[2]);
3989 size += model->surfmesh.num_vertices * sizeof(float[2]);
3990 size += model->surfmesh.num_vertices * sizeof(float[4]);
3991 data = (unsigned char *)Mem_Alloc(model->mempool, size);
3992 model->surfmesh.data_vertex3f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[3]);
3993 model->surfmesh.data_normal3f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[3]);
3994 model->surfmesh.data_svector3f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[3]);
3995 model->surfmesh.data_tvector3f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[3]);
3996 model->surfmesh.data_texcoordtexture2f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[2]);
3997 model->surfmesh.data_texcoordlightmap2f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[2]);
3998 model->surfmesh.data_lightmapcolor4f = (float *)data;data += model->surfmesh.num_vertices * sizeof(float[4]);
3999 if (model->surfmesh.num_vertices > 65536)
4000 model->surfmesh.data_element3s = NULL;
4001
4002 if (model->surfmesh.data_element3i_indexbuffer && !model->surfmesh.data_element3i_indexbuffer->isdynamic)
4003 R_Mesh_DestroyMeshBuffer(model->surfmesh.data_element3i_indexbuffer);
4004 model->surfmesh.data_element3i_indexbuffer = NULL;
4005 if (model->surfmesh.data_element3s_indexbuffer && !model->surfmesh.data_element3s_indexbuffer->isdynamic)
4006 R_Mesh_DestroyMeshBuffer(model->surfmesh.data_element3s_indexbuffer);
4007 model->surfmesh.data_element3s_indexbuffer = NULL;
4008 if (model->surfmesh.data_vertex3f_vertexbuffer && !model->surfmesh.data_vertex3f_vertexbuffer->isdynamic)
4009 R_Mesh_DestroyMeshBuffer(model->surfmesh.data_vertex3f_vertexbuffer);
4010 model->surfmesh.data_vertex3f_vertexbuffer = NULL;
4011 model->surfmesh.data_svector3f_vertexbuffer = NULL;
4012 model->surfmesh.data_tvector3f_vertexbuffer = NULL;
4013 model->surfmesh.data_normal3f_vertexbuffer = NULL;
4014 model->surfmesh.data_texcoordtexture2f_vertexbuffer = NULL;
4015 model->surfmesh.data_texcoordlightmap2f_vertexbuffer = NULL;
4016 model->surfmesh.data_lightmapcolor4f_vertexbuffer = NULL;
4017 model->surfmesh.data_skeletalindex4ub_vertexbuffer = NULL;
4018 model->surfmesh.data_skeletalweight4ub_vertexbuffer = NULL;
4019
4020 // convert all triangles to unique vertex data
4021 outvertexindex = 0;
4022 for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
4023 {
4024 surface = model->data_surfaces + surfaceindex;
4025 surface->num_firstvertex = outvertexindex;
4026 surface->num_vertices = surface->num_triangles*3;
4027 e = oldsurfmesh.data_element3i + surface->num_firsttriangle*3;
4028 for (i = 0;i < surface->num_triangles*3;i++)
4029 {
4030 vertexindex = e[i];
4031 model->surfmesh.data_vertex3f[outvertexindex*3+0] = oldsurfmesh.data_vertex3f[vertexindex*3+0];
4032 model->surfmesh.data_vertex3f[outvertexindex*3+1] = oldsurfmesh.data_vertex3f[vertexindex*3+1];
4033 model->surfmesh.data_vertex3f[outvertexindex*3+2] = oldsurfmesh.data_vertex3f[vertexindex*3+2];
4034 model->surfmesh.data_normal3f[outvertexindex*3+0] = oldsurfmesh.data_normal3f[vertexindex*3+0];
4035 model->surfmesh.data_normal3f[outvertexindex*3+1] = oldsurfmesh.data_normal3f[vertexindex*3+1];
4036 model->surfmesh.data_normal3f[outvertexindex*3+2] = oldsurfmesh.data_normal3f[vertexindex*3+2];
4037 model->surfmesh.data_svector3f[outvertexindex*3+0] = oldsurfmesh.data_svector3f[vertexindex*3+0];
4038 model->surfmesh.data_svector3f[outvertexindex*3+1] = oldsurfmesh.data_svector3f[vertexindex*3+1];
4039 model->surfmesh.data_svector3f[outvertexindex*3+2] = oldsurfmesh.data_svector3f[vertexindex*3+2];
4040 model->surfmesh.data_tvector3f[outvertexindex*3+0] = oldsurfmesh.data_tvector3f[vertexindex*3+0];
4041 model->surfmesh.data_tvector3f[outvertexindex*3+1] = oldsurfmesh.data_tvector3f[vertexindex*3+1];
4042 model->surfmesh.data_tvector3f[outvertexindex*3+2] = oldsurfmesh.data_tvector3f[vertexindex*3+2];
4043 model->surfmesh.data_texcoordtexture2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+0];
4044 model->surfmesh.data_texcoordtexture2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+1];
4045 if (oldsurfmesh.data_texcoordlightmap2f)
4046 {
4047 model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+0];
4048 model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+1];
4049 }
4050 if (oldsurfmesh.data_lightmapcolor4f)
4051 {
4052 model->surfmesh.data_lightmapcolor4f[outvertexindex*4+0] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+0];
4053 model->surfmesh.data_lightmapcolor4f[outvertexindex*4+1] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+1];
4054 model->surfmesh.data_lightmapcolor4f[outvertexindex*4+2] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+2];
4055 model->surfmesh.data_lightmapcolor4f[outvertexindex*4+3] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+3];
4056 }
4057 else
4058 Vector4Set(model->surfmesh.data_lightmapcolor4f + 4*outvertexindex, 1, 1, 1, 1);
4059 model->surfmesh.data_element3i[surface->num_firsttriangle*3+i] = outvertexindex;
4060 outvertexindex++;
4061 }
4062 }
4063 if (model->surfmesh.data_element3s)
4064 for (i = 0;i < model->surfmesh.num_triangles*3;i++)
4065 model->surfmesh.data_element3s[i] = model->surfmesh.data_element3i[i];
4066
4067 // find and update all submodels to use this new surfmesh data
4068 for (i = 0;i < model->brush.numsubmodels;i++)
4069 model->brush.submodels[i]->surfmesh = model->surfmesh;
4070}
void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
#define Vector4Set(vec, r, g, b, a)
Definition mathlib.h:86
int num_firstvertex

References data, surfmesh_t::data_element3i, surfmesh_t::data_lightmapcolor4f, surfmesh_t::data_normal3f, surfmesh_t::data_svector3f, surfmesh_t::data_texcoordlightmap2f, surfmesh_t::data_texcoordtexture2f, surfmesh_t::data_tvector3f, surfmesh_t::data_vertex3f, i, Mem_Alloc, model, NULL, msurface_t::num_firsttriangle, msurface_t::num_firstvertex, msurface_t::num_triangles, surfmesh_t::num_triangles, msurface_t::num_vertices, R_Mesh_DestroyMeshBuffer(), size, and Vector4Set.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_UpdateLightGrid()

static void Mod_GenerateLightmaps_UpdateLightGrid ( model_t * model)
static

Definition at line 4384 of file model_shared.c.

4385{
4386 int x;
4387 int y;
4388 int z;
4389 int index = 0;
4390 float pos[3];
4391 for (z = 0;z < model->brushq3.num_lightgrid_isize[2];z++)
4392 {
4393 pos[2] = (model->brushq3.num_lightgrid_imins[2] + z + 0.5f) * model->brushq3.num_lightgrid_cellsize[2];
4394 for (y = 0;y < model->brushq3.num_lightgrid_isize[1];y++)
4395 {
4396 pos[1] = (model->brushq3.num_lightgrid_imins[1] + y + 0.5f) * model->brushq3.num_lightgrid_cellsize[1];
4397 for (x = 0;x < model->brushq3.num_lightgrid_isize[0];x++, index++)
4398 {
4399 pos[0] = (model->brushq3.num_lightgrid_imins[0] + x + 0.5f) * model->brushq3.num_lightgrid_cellsize[0];
4400 Mod_GenerateLightmaps_GridSample(pos, model->brushq3.data_lightgrid + index);
4401 }
4402 }
4403 }
4404}
GLubyte GLubyte GLubyte z
Definition glquake.h:782
static void Mod_GenerateLightmaps_GridSample(const float *pos, q3dlightgrid_t *s)

References index, Mod_GenerateLightmaps_GridSample(), model, x, y, and z.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_UpdateVertexColors()

static void Mod_GenerateLightmaps_UpdateVertexColors ( model_t * model)
static

Definition at line 4377 of file model_shared.c.

4378{
4379 int i;
4380 for (i = 0;i < model->surfmesh.num_vertices;i++)
4381 Mod_GenerateLightmaps_VertexSample(model->surfmesh.data_vertex3f + 3*i, model->surfmesh.data_normal3f + 3*i, model->surfmesh.data_lightmapcolor4f + 4*i);
4382}
static void Mod_GenerateLightmaps_VertexSample(const float *pos, const float *normal, float *vertex_color)

References i, Mod_GenerateLightmaps_VertexSample(), and model.

Referenced by Mod_GenerateLightmaps().

◆ Mod_GenerateLightmaps_VertexSample()

static void Mod_GenerateLightmaps_VertexSample ( const float * pos,
const float * normal,
float * vertex_color )
static

◆ Mod_Init()

void Mod_Init ( void )

Definition at line 178 of file model_shared.c.

179{
180 mod_mempool = Mem_AllocPool("modelinfo", 0, NULL);
182
186
192
199
200 Cmd_AddCommand(CF_CLIENT, "modellist", Mod_Print_f, "prints a list of loaded models");
201 Cmd_AddCommand(CF_CLIENT, "modelprecache", Mod_Precache_f, "load a model");
202 Cmd_AddCommand(CF_CLIENT, "modeldecompile", Mod_Decompile_f, "exports a model in several formats for editing purposes");
203 Cmd_AddCommand(CF_CLIENT, "mod_generatelightmaps", Mod_GenerateLightmaps_f, "rebuilds lighting on current worldmodel");
204}
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
void Mod_AliasInit(void)
void Mod_BrushInit(void)
Definition model_brush.c:80
static void Mod_Print_f(cmd_state_t *cmd)
cvar_t r_mipnormalmaps
static void Mod_GenerateLightmaps_f(cmd_state_t *cmd)
static void Mod_Decompile_f(cmd_state_t *cmd)
cvar_t r_mipskins
static mempool_t * mod_mempool
static void Mod_Precache_f(cmd_state_t *cmd)
void Mod_SpriteInit(void)
void Mem_ExpandableArray_NewArray(memexpandablearray_t *l, mempool_t *mempool, size_t recordsize, int numrecordsperarray)
Definition zone.c:675
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104

References CF_CLIENT, Cmd_AddCommand(), Cvar_RegisterVariable(), Mem_AllocPool, Mem_ExpandableArray_NewArray(), Mod_AliasInit(), Mod_BrushInit(), Mod_Decompile_f(), mod_generatelightmaps_borderpixels, Mod_GenerateLightmaps_f(), mod_generatelightmaps_gridradius, mod_generatelightmaps_gridsamples, mod_generatelightmaps_lightmapradius, mod_generatelightmaps_lightmapsamples, mod_generatelightmaps_texturesize, mod_generatelightmaps_unitspersample, mod_generatelightmaps_vertexradius, mod_generatelightmaps_vertexsamples, mod_mempool, Mod_Precache_f(), Mod_Print_f(), Mod_SpriteInit(), models, NULL, r_mipnormalmaps, and r_mipskins.

Referenced by Host_Init().

◆ Mod_LoadCustomMaterial()

void Mod_LoadCustomMaterial ( mempool_t * mempool,
texture_t * texture,
const char * name,
int supercontents,
int materialflags,
skinframe_t * skinframe )

Definition at line 2653 of file model_shared.c.

2654{
2655 if (!(materialflags & (MATERIALFLAG_WALL | MATERIALFLAG_SKY)))
2656 Con_DPrintf("^1Custom texture ^3\"%s\" does not have MATERIALFLAG_WALL set\n", texture->name);
2657
2658 dp_strlcpy(texture->name, name, sizeof(texture->name));
2659 texture->basealpha = 1.0f;
2660 texture->basematerialflags = materialflags;
2661 texture->supercontents = supercontents;
2662
2664 texture->offsetscale = 1;
2665 texture->offsetbias = 0;
2666 texture->specularscalemod = 1;
2667 texture->specularpowermod = 1;
2668 texture->rtlightambient = 0;
2669 texture->transparentsort = TRANSPARENTSORT_DISTANCE;
2670 // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
2671 // JUST GREP FOR "specularscalemod = 1".
2672
2674 Con_DPrintf("^1Custom texture ^3\"%s\"\n", texture->name);
2675 if (skinframe)
2676 texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(mempool, skinframe);
2677
2678 // init the animation variables
2679 texture->currentmaterialflags = texture->basematerialflags;
2680 texture->currentframe = texture;
2681 texture->currentskinframe = skinframe;
2682 texture->backgroundcurrentskinframe = NULL;
2683}
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
cvar_t developer_extra
Definition host.c:49
cvar_t mod_noshader_default_offsetmapping
Definition model_brush.c:51
#define MATERIALFLAG_SKY
Definition model_brush.h:92
#define MATERIALFLAG_WALL
Definition model_brush.h:89
texture_shaderpass_t * Mod_CreateShaderPass(mempool_t *mempool, skinframe_t *skinframe)
@ TRANSPARENTSORT_DISTANCE
Definition r_qshader.h:194
@ OFFSETMAPPING_DEFAULT
Definition r_qshader.h:186
@ OFFSETMAPPING_OFF
Definition r_qshader.h:185

References Con_DPrintf(), developer_extra, dp_strlcpy, cvar_t::integer, MATERIALFLAG_SKY, MATERIALFLAG_WALL, Mod_CreateShaderPass(), mod_noshader_default_offsetmapping, name, NULL, OFFSETMAPPING_DEFAULT, OFFSETMAPPING_OFF, texture, TRANSPARENTSORT_DISTANCE, and cvar_t::value.

Referenced by CL_Beams_SetupBuiltinTexture(), Mod_BuildAliasSkinsFromSkinFiles(), Mod_IDP0_Load(), and Mod_IDP2_Load().

◆ Mod_LoadModel()

model_t * Mod_LoadModel ( model_t * mod,
qbool crash,
qbool checkdisk )

Definition at line 406 of file model_shared.c.

407{
408 unsigned int crc;
409 void *buf;
410 fs_offset_t filesize = 0;
411 char vabuf[1024];
412
413 mod->used = true;
414
415 if (mod->name[0] == '*') // submodel
416 return mod;
417
418 if (!strcmp(mod->name, "null"))
419 {
420 if(mod->loaded)
421 return mod;
422
423 if (mod->loaded || mod->mempool)
425
427 Con_Printf("loading model %s\n", mod->name);
428
429 mod->used = true;
430 mod->crc = (unsigned int)-1;
431 mod->loaded = false;
432
433 VectorClear(mod->normalmins);
434 VectorClear(mod->normalmaxs);
435 VectorClear(mod->yawmins);
436 VectorClear(mod->yawmaxs);
437 VectorClear(mod->rotatedmins);
438 VectorClear(mod->rotatedmaxs);
439
440 mod->modeldatatypestring = "null";
441 mod->type = mod_null;
442 mod->Draw = R_Model_Null_Draw;
443 mod->numframes = 2;
444 mod->numskins = 1;
445
446 // no fatal errors occurred, so this model is ready to use.
447 mod->loaded = true;
448
449 return mod;
450 }
451
452 crc = 0;
453 buf = NULL;
454
455 // even if the model is loaded it still may need reloading...
456
457 // if it is not loaded or checkdisk is true we need to calculate the crc
458 if (!mod->loaded || checkdisk)
459 {
460 if (checkdisk && mod->loaded)
461 Con_DPrintf("checking model %s\n", mod->name);
462 buf = FS_LoadFile (mod->name, tempmempool, false, &filesize);
463 if (buf)
464 {
465 crc = CRC_Block((unsigned char *)buf, filesize);
466 // we need to reload the model if the crc does not match
467 if (mod->crc != crc)
468 mod->loaded = false;
469 }
470 }
471
472 // if the model is already loaded and checks passed, just return
473 if (mod->loaded)
474 {
475 if (buf)
476 Mem_Free(buf);
477 return mod;
478 }
479
481 Con_Printf("loading model %s\n", mod->name);
482
483 SCR_PushLoadingScreen(mod->name, 1);
484
485 // LadyHavoc: unload the existing model in this slot (if there is one)
486 if (mod->loaded || mod->mempool)
488
489 // load the model
490 mod->used = true;
491 mod->crc = crc;
492 // errors can prevent the corresponding mod->loaded = true;
493 mod->loaded = false;
494
495 // default lightmap scale
496 mod->lightmapscale = 1;
497
498 // default model radius and bounding box (mainly for missing models)
499 mod->radius = 16;
500 VectorSet(mod->normalmins, -mod->radius, -mod->radius, -mod->radius);
501 VectorSet(mod->normalmaxs, mod->radius, mod->radius, mod->radius);
502 VectorSet(mod->yawmins, -mod->radius, -mod->radius, -mod->radius);
503 VectorSet(mod->yawmaxs, mod->radius, mod->radius, mod->radius);
504 VectorSet(mod->rotatedmins, -mod->radius, -mod->radius, -mod->radius);
505 VectorSet(mod->rotatedmaxs, mod->radius, mod->radius, mod->radius);
506
507 if (!q3shaders_mem)
508 {
509 // load q3 shaders for the first time, or after a level change
511 }
512
513 if (buf)
514 {
515 int i;
516 const char *ext = FS_FileExtension(mod->name);
517 char *bufend = (char *)buf + filesize;
518 // all models use memory, so allocate a memory pool
519 mod->mempool = Mem_AllocPool(mod->name, 0, NULL);
520
521 // We need to have a reference to the base model in case we're parsing submodels
522 loadmodel = mod;
523
524 // Call the appropriate loader. Try matching magic bytes.
525 for (i = 0; loader[i].Load; i++)
526 {
527 // Headerless formats can just load based on extension. Otherwise match the magic string.
528 if((loader[i].extension && !strcasecmp(ext, loader[i].extension) && !loader[i].header) ||
529 (loader[i].header && !memcmp(buf, loader[i].header, loader[i].headersize)))
530 {
531 // Matched. Load it.
532 loader[i].Load(mod, buf, bufend);
533 Mem_Free(buf);
534
536
537 buf = FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.framegroups", mod->name), tempmempool, false, &filesize);
538 if(buf)
539 {
540 Mod_FrameGroupify(mod, (const char *)buf);
541 Mem_Free(buf);
542 }
543
546 break;
547 }
548 }
549 if(!loader[i].Load)
550 Con_Printf(CON_ERROR "Mod_LoadModel: model \"%s\" is of unknown/unsupported type\n", mod->name);
551 }
552 else if (crash)
553 // LadyHavoc: Sys_Error was *ANNOYING*
554 Con_Printf (CON_ERROR "Mod_LoadModel: %s not found\n", mod->name);
555
556 // no fatal errors occurred, so this model is ready to use.
557 mod->loaded = true;
558
560
561 return mod;
562}
void SCR_PopLoadingScreen(qbool redraw)
Definition cl_screen.c:1899
void SCR_PushLoadingScreen(const char *msg, float len_in_parent)
Definition cl_screen.c:1873
unsigned short CRC_Block(const unsigned char *data, size_t size)
Definition com_crc16.c:75
#define CON_ERROR
Definition console.h:102
const char * FS_FileExtension(const char *in)
Definition fs.c:1403
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
cvar_t developer_loading
Definition host.c:52
#define VectorClear(a)
Definition mathlib.h:97
static void R_Model_Null_Draw(entity_render_t *ent)
static void Mod_FindPotentialDeforms(model_t *mod)
static modloader_t loader[]
void Mod_BuildVBOs(void)
void Mod_UnloadModel(model_t *mod)
void Mod_LoadQ3Shaders(void)
static void Mod_FrameGroupify(model_t *mod, const char *buf)
void Mod_SetDrawSkyAndWater(model_t *mod)
Sets the mod->DrawSky and mod->DrawAddWaterPlanes pointers conditionally based on whether surfaces in...
@ mod_null
void(* Load)(model_t *, void *, void *)

References buf, Con_DPrintf(), CON_ERROR, Con_Printf(), crash(), CRC_Block(), developer_loading, FS_FileExtension(), FS_LoadFile(), i, int(), cvar_t::integer, modloader_t::Load, loader, loadmodel, Mem_AllocPool, Mem_Free, mod(), Mod_BuildVBOs(), Mod_FindPotentialDeforms(), Mod_FrameGroupify(), Mod_LoadQ3Shaders(), mod_null, Mod_SetDrawSkyAndWater(), Mod_UnloadModel(), NULL, q3shaders_mem, R_Model_Null_Draw(), SCR_PopLoadingScreen(), SCR_PushLoadingScreen(), tempmempool, va(), VectorClear, and VectorSet.

Referenced by Mod_ForName(), Mod_Reload(), and mod_start().

◆ Mod_LoadQ3Shaders()

void Mod_LoadQ3Shaders ( void )

Definition at line 1466 of file model_shared.c.

1467{
1468 int j;
1469 int fileindex;
1470 fssearch_t *search;
1471 char *f;
1472 const char *text;
1473 shader_t shader;
1475 int numparameters;
1476 char parameter[TEXTURE_MAXFRAMES + 4][Q3PATHLENGTH];
1477 char *custsurfaceparmnames[256]; // VorteX: q3map2 has 64 but well, someone will need more
1478 unsigned long custsurfaceflags[256];
1479 int numcustsurfaceflags;
1480 qbool dpshaderkill;
1481
1483
1484 q3shaders_mem = Mem_AllocPool("q3shaders", 0, NULL);
1486 sizeof (q3shader_data_t));
1488 q3shaders_mem, sizeof (q3shader_hash_entry_t), 256);
1490 q3shaders_mem, sizeof (char**), 256);
1491
1492 // parse custinfoparms.txt
1493 numcustsurfaceflags = 0;
1494 if ((text = f = (char *)FS_LoadFile("scripts/custinfoparms.txt", tempmempool, false, NULL)) != NULL)
1495 {
1496 if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
1497 Con_DPrintf("scripts/custinfoparms.txt: contentflags section parsing error - expected \"{\", found \"%s\"\n", com_token);
1498 else
1499 {
1500 while (COM_ParseToken_QuakeC(&text, false))
1501 if (!strcasecmp(com_token, "}"))
1502 break;
1503 // custom surfaceflags section
1504 if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
1505 Con_DPrintf("scripts/custinfoparms.txt: surfaceflags section parsing error - expected \"{\", found \"%s\"\n", com_token);
1506 else
1507 {
1508 while(COM_ParseToken_QuakeC(&text, false))
1509 {
1510 if (!strcasecmp(com_token, "}"))
1511 break;
1512 // register surfaceflag
1513 if (numcustsurfaceflags >= 256)
1514 {
1515 Con_Printf("scripts/custinfoparms.txt: surfaceflags section parsing error - max 256 surfaceflags exceeded\n");
1516 break;
1517 }
1518 // name
1519 j = (int)strlen(com_token)+1;
1520 custsurfaceparmnames[numcustsurfaceflags] = (char *)Mem_Alloc(tempmempool, j);
1521 dp_strlcpy(custsurfaceparmnames[numcustsurfaceflags], com_token, j+1);
1522 // value
1523 if (COM_ParseToken_QuakeC(&text, false))
1524 custsurfaceflags[numcustsurfaceflags] = strtol(com_token, NULL, 0);
1525 else
1526 custsurfaceflags[numcustsurfaceflags] = 0;
1527 numcustsurfaceflags++;
1528 }
1529 }
1530 }
1531 Mem_Free(f);
1532 }
1533
1534 // parse shaders
1535 search = FS_Search("scripts/*.shader", true, false, NULL);
1536 if (!search)
1537 return;
1538 for (fileindex = 0;fileindex < search->numfilenames;fileindex++)
1539 {
1540 text = f = (char *)FS_LoadFile(search->filenames[fileindex], tempmempool, false, NULL);
1541 if (!f)
1542 continue;
1543 while (COM_ParseToken_QuakeC(&text, false))
1544 {
1545 memset (&shader, 0, sizeof(shader));
1546 shader.name[0] = 0;
1547 shader.surfaceparms = 0;
1548 shader.surfaceflags = 0;
1549 shader.textureflags = 0;
1550 shader.numlayers = 0;
1551 shader.lighting = false;
1552 shader.vertexalpha = false;
1553 shader.textureblendalpha = false;
1554 shader.skyboxname[0] = 0;
1555 shader.deforms[0].deform = Q3DEFORM_NONE;
1556 shader.dpnortlight = false;
1557 shader.dpshadow = false;
1558 shader.dpnoshadow = false;
1559 shader.dpmeshcollisions = false;
1560 shader.dpshaderkill = false;
1561 shader.dpreflectcube[0] = 0;
1562 shader.reflectmin = 0;
1563 shader.reflectmax = 1;
1564 shader.refractfactor = 1;
1565 Vector4Set(shader.refractcolor4f, 1, 1, 1, 1);
1566 shader.reflectfactor = 1;
1567 Vector4Set(shader.reflectcolor4f, 1, 1, 1, 1);
1568 shader.r_water_wateralpha = 1;
1569 shader.r_water_waterscroll[0] = 0;
1570 shader.r_water_waterscroll[1] = 0;
1577 shader.specularscalemod = 1;
1578 shader.specularpowermod = 1;
1579 shader.rtlightambient = 0;
1580 // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
1581 // JUST GREP FOR "specularscalemod = 1".
1582
1583 dp_strlcpy(shader.name, com_token, sizeof(shader.name));
1584 if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
1585 {
1586 Con_DPrintf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[fileindex], com_token);
1587 break;
1588 }
1589 while (COM_ParseToken_QuakeC(&text, false))
1590 {
1591 if (!strcasecmp(com_token, "}"))
1592 break;
1593 if (!strcasecmp(com_token, "{"))
1594 {
1595 static q3shaderinfo_layer_t dummy;
1596 if (shader.numlayers < Q3SHADER_MAXLAYERS)
1597 {
1598 layer = shader.layers + shader.numlayers++;
1599 }
1600 else
1601 {
1602 // parse and process it anyway, just don't store it (so a map $lightmap or such stuff still is found)
1603 memset(&dummy, 0, sizeof(dummy));
1604 layer = &dummy;
1605 }
1606 layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITY;
1607 layer->alphagen.alphagen = Q3ALPHAGEN_IDENTITY;
1608 layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
1609 layer->blendfunc[0] = GL_ONE;
1610 layer->blendfunc[1] = GL_ZERO;
1611 while (COM_ParseToken_QuakeC(&text, false))
1612 {
1613 if (!strcasecmp(com_token, "}"))
1614 break;
1615 if (!strcasecmp(com_token, "\n"))
1616 continue;
1617 numparameters = 0;
1618 for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
1619 {
1620 if (j < TEXTURE_MAXFRAMES + 4)
1621 {
1622 // remap dp_water to dpwater, dp_reflect to dpreflect, etc.
1623 if(j == 0 && !strncasecmp(com_token, "dp_", 3))
1624 dpsnprintf(parameter[j], sizeof(parameter[j]), "dp%s", &com_token[3]);
1625 else
1626 dp_strlcpy(parameter[j], com_token, sizeof(parameter[j]));
1627 numparameters = j + 1;
1628 }
1629 if (!COM_ParseToken_QuakeC(&text, true))
1630 break;
1631 }
1632 //for (j = numparameters;j < TEXTURE_MAXFRAMES + 4;j++)
1633 // parameter[j][0] = 0;
1635 {
1636 Con_DPrintf("%s %i: ", shader.name, shader.numlayers - 1);
1637 for (j = 0;j < numparameters;j++)
1638 Con_DPrintf(" %s", parameter[j]);
1639 Con_DPrint("\n");
1640 }
1641 if (numparameters >= 2 && !strcasecmp(parameter[0], "blendfunc"))
1642 {
1643 if (numparameters == 2)
1644 {
1645 if (!strcasecmp(parameter[1], "add"))
1646 {
1647 layer->blendfunc[0] = GL_ONE;
1648 layer->blendfunc[1] = GL_ONE;
1649 }
1650 else if (!strcasecmp(parameter[1], "addalpha"))
1651 {
1652 layer->blendfunc[0] = GL_SRC_ALPHA;
1653 layer->blendfunc[1] = GL_ONE;
1654 }
1655 else if (!strcasecmp(parameter[1], "filter"))
1656 {
1657 layer->blendfunc[0] = GL_DST_COLOR;
1658 layer->blendfunc[1] = GL_ZERO;
1659 }
1660 else if (!strcasecmp(parameter[1], "blend"))
1661 {
1662 layer->blendfunc[0] = GL_SRC_ALPHA;
1663 layer->blendfunc[1] = GL_ONE_MINUS_SRC_ALPHA;
1664 }
1665 }
1666 else if (numparameters == 3)
1667 {
1668 int k;
1669 for (k = 0;k < 2;k++)
1670 {
1671 if (!strcasecmp(parameter[k+1], "GL_ONE"))
1672 layer->blendfunc[k] = GL_ONE;
1673 else if (!strcasecmp(parameter[k+1], "GL_ZERO"))
1674 layer->blendfunc[k] = GL_ZERO;
1675 else if (!strcasecmp(parameter[k+1], "GL_SRC_COLOR"))
1676 layer->blendfunc[k] = GL_SRC_COLOR;
1677 else if (!strcasecmp(parameter[k+1], "GL_SRC_ALPHA"))
1678 layer->blendfunc[k] = GL_SRC_ALPHA;
1679 else if (!strcasecmp(parameter[k+1], "GL_DST_COLOR"))
1680 layer->blendfunc[k] = GL_DST_COLOR;
1681 else if (!strcasecmp(parameter[k+1], "GL_DST_ALPHA"))
1682 layer->blendfunc[k] = GL_DST_ALPHA;
1683 else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_COLOR"))
1684 layer->blendfunc[k] = GL_ONE_MINUS_SRC_COLOR;
1685 else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_ALPHA"))
1686 layer->blendfunc[k] = GL_ONE_MINUS_SRC_ALPHA;
1687 else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_DST_COLOR"))
1688 layer->blendfunc[k] = GL_ONE_MINUS_DST_COLOR;
1689 else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_DST_ALPHA"))
1690 layer->blendfunc[k] = GL_ONE_MINUS_DST_ALPHA;
1691 else
1692 layer->blendfunc[k] = GL_ONE; // default in case of parsing error
1693 }
1694 }
1695 }
1696 if (numparameters >= 2 && !strcasecmp(parameter[0], "alphafunc"))
1697 layer->alphatest = true;
1698 if (numparameters >= 2 && (!strcasecmp(parameter[0], "map") || !strcasecmp(parameter[0], "clampmap")))
1699 {
1700 if (!strcasecmp(parameter[0], "clampmap"))
1701 layer->clampmap = true;
1702 layer->numframes = 1;
1703 layer->framerate = 1;
1704 layer->texturename = (char**)Mem_ExpandableArray_AllocRecord (
1706 layer->texturename[0] = Mem_strdup (q3shaders_mem, parameter[1]);
1707 if (!strcasecmp(parameter[1], "$lightmap"))
1708 shader.lighting = true;
1709 }
1710 else if (numparameters >= 3 && (!strcasecmp(parameter[0], "animmap") || !strcasecmp(parameter[0], "animclampmap")))
1711 {
1712 int i;
1713 layer->numframes = min(numparameters - 2, TEXTURE_MAXFRAMES);
1714 layer->framerate = atof(parameter[1]);
1715 layer->texturename = (char **) Mem_Alloc (q3shaders_mem, sizeof (char*) * layer->numframes);
1716 for (i = 0;i < layer->numframes;i++)
1717 layer->texturename[i] = Mem_strdup (q3shaders_mem, parameter[i + 2]);
1718 }
1719 else if (numparameters >= 2 && !strcasecmp(parameter[0], "rgbgen"))
1720 {
1721 int i;
1722 for (i = 0;i < numparameters - 2 && i < Q3RGBGEN_MAXPARMS;i++)
1723 layer->rgbgen.parms[i] = atof(parameter[i+2]);
1724 if (!strcasecmp(parameter[1], "identity")) layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITY;
1725 else if (!strcasecmp(parameter[1], "const")) layer->rgbgen.rgbgen = Q3RGBGEN_CONST;
1726 else if (!strcasecmp(parameter[1], "entity")) layer->rgbgen.rgbgen = Q3RGBGEN_ENTITY;
1727 else if (!strcasecmp(parameter[1], "exactvertex")) layer->rgbgen.rgbgen = Q3RGBGEN_EXACTVERTEX;
1728 else if (!strcasecmp(parameter[1], "identitylighting")) layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITYLIGHTING;
1729 else if (!strcasecmp(parameter[1], "lightingdiffuse")) layer->rgbgen.rgbgen = Q3RGBGEN_LIGHTINGDIFFUSE;
1730 else if (!strcasecmp(parameter[1], "oneminusentity")) layer->rgbgen.rgbgen = Q3RGBGEN_ONEMINUSENTITY;
1731 else if (!strcasecmp(parameter[1], "oneminusvertex")) layer->rgbgen.rgbgen = Q3RGBGEN_ONEMINUSVERTEX;
1732 else if (!strcasecmp(parameter[1], "vertex")) layer->rgbgen.rgbgen = Q3RGBGEN_VERTEX;
1733 else if (!strcasecmp(parameter[1], "wave"))
1734 {
1735 layer->rgbgen.rgbgen = Q3RGBGEN_WAVE;
1736 layer->rgbgen.wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
1737 for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
1738 layer->rgbgen.waveparms[i] = atof(parameter[i+3]);
1739 }
1740 else Con_DPrintf("%s parsing warning: unknown rgbgen %s\n", search->filenames[fileindex], parameter[1]);
1741 }
1742 else if (numparameters >= 2 && !strcasecmp(parameter[0], "alphagen"))
1743 {
1744 int i;
1745 for (i = 0;i < numparameters - 2 && i < Q3ALPHAGEN_MAXPARMS;i++)
1746 layer->alphagen.parms[i] = atof(parameter[i+2]);
1747 if (!strcasecmp(parameter[1], "identity")) layer->alphagen.alphagen = Q3ALPHAGEN_IDENTITY;
1748 else if (!strcasecmp(parameter[1], "const")) layer->alphagen.alphagen = Q3ALPHAGEN_CONST;
1749 else if (!strcasecmp(parameter[1], "entity")) layer->alphagen.alphagen = Q3ALPHAGEN_ENTITY;
1750 else if (!strcasecmp(parameter[1], "lightingspecular")) layer->alphagen.alphagen = Q3ALPHAGEN_LIGHTINGSPECULAR;
1751 else if (!strcasecmp(parameter[1], "oneminusentity")) layer->alphagen.alphagen = Q3ALPHAGEN_ONEMINUSENTITY;
1752 else if (!strcasecmp(parameter[1], "oneminusvertex")) layer->alphagen.alphagen = Q3ALPHAGEN_ONEMINUSVERTEX;
1753 else if (!strcasecmp(parameter[1], "portal")) layer->alphagen.alphagen = Q3ALPHAGEN_PORTAL;
1754 else if (!strcasecmp(parameter[1], "vertex")) layer->alphagen.alphagen = Q3ALPHAGEN_VERTEX;
1755 else if (!strcasecmp(parameter[1], "wave"))
1756 {
1757 layer->alphagen.alphagen = Q3ALPHAGEN_WAVE;
1758 layer->alphagen.wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
1759 for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
1760 layer->alphagen.waveparms[i] = atof(parameter[i+3]);
1761 }
1762 else Con_DPrintf("%s parsing warning: unknown alphagen %s\n", search->filenames[fileindex], parameter[1]);
1763 }
1764 else if (numparameters >= 2 && (!strcasecmp(parameter[0], "texgen") || !strcasecmp(parameter[0], "tcgen")))
1765 {
1766 int i;
1767 // observed values: tcgen environment
1768 // no other values have been observed in real shaders
1769 for (i = 0;i < numparameters - 2 && i < Q3TCGEN_MAXPARMS;i++)
1770 layer->tcgen.parms[i] = atof(parameter[i+2]);
1771 if (!strcasecmp(parameter[1], "base")) layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
1772 else if (!strcasecmp(parameter[1], "texture")) layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
1773 else if (!strcasecmp(parameter[1], "environment")) layer->tcgen.tcgen = Q3TCGEN_ENVIRONMENT;
1774 else if (!strcasecmp(parameter[1], "lightmap")) layer->tcgen.tcgen = Q3TCGEN_LIGHTMAP;
1775 else if (!strcasecmp(parameter[1], "vector")) layer->tcgen.tcgen = Q3TCGEN_VECTOR;
1776 else Con_DPrintf("%s parsing warning: unknown tcgen mode %s\n", search->filenames[fileindex], parameter[1]);
1777 }
1778 else if (numparameters >= 2 && !strcasecmp(parameter[0], "tcmod"))
1779 {
1780 int i, tcmodindex;
1781 // observed values:
1782 // tcmod rotate #
1783 // tcmod scale # #
1784 // tcmod scroll # #
1785 // tcmod stretch sin # # # #
1786 // tcmod stretch triangle # # # #
1787 // tcmod transform # # # # # #
1788 // tcmod turb # # # #
1789 // tcmod turb sin # # # # (this is bogus)
1790 // no other values have been observed in real shaders
1791 for (tcmodindex = 0;tcmodindex < Q3MAXTCMODS;tcmodindex++)
1792 if (!layer->tcmods[tcmodindex].tcmod)
1793 break;
1794 if (tcmodindex < Q3MAXTCMODS)
1795 {
1796 for (i = 0;i < numparameters - 2 && i < Q3TCMOD_MAXPARMS;i++)
1797 layer->tcmods[tcmodindex].parms[i] = atof(parameter[i+2]);
1798 if (!strcasecmp(parameter[1], "entitytranslate")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_ENTITYTRANSLATE;
1799 else if (!strcasecmp(parameter[1], "rotate")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_ROTATE;
1800 else if (!strcasecmp(parameter[1], "scale")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCALE;
1801 else if (!strcasecmp(parameter[1], "scroll")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCROLL;
1802 else if (!strcasecmp(parameter[1], "page")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_PAGE;
1803 else if (!strcasecmp(parameter[1], "stretch"))
1804 {
1805 layer->tcmods[tcmodindex].tcmod = Q3TCMOD_STRETCH;
1806 layer->tcmods[tcmodindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
1807 for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
1808 layer->tcmods[tcmodindex].waveparms[i] = atof(parameter[i+3]);
1809 }
1810 else if (!strcasecmp(parameter[1], "transform")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_TRANSFORM;
1811 else if (!strcasecmp(parameter[1], "turb")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_TURBULENT;
1812 else Con_DPrintf("%s parsing warning: unknown tcmod mode %s\n", search->filenames[fileindex], parameter[1]);
1813 }
1814 else
1815 Con_DPrintf("%s parsing warning: too many tcmods on one layer\n", search->filenames[fileindex]);
1816 }
1817 // break out a level if it was a closing brace (not using the character here to not confuse vim)
1818 if (!strcasecmp(com_token, "}"))
1819 break;
1820 }
1821 if (layer->rgbgen.rgbgen == Q3RGBGEN_LIGHTINGDIFFUSE || layer->rgbgen.rgbgen == Q3RGBGEN_VERTEX)
1822 shader.lighting = true;
1823 if (layer->alphagen.alphagen == Q3ALPHAGEN_VERTEX)
1824 {
1825 if (layer == shader.layers + 0)
1826 {
1827 // vertex controlled transparency
1828 shader.vertexalpha = true;
1829 }
1830 else
1831 {
1832 // multilayer terrain shader or similar
1833 shader.textureblendalpha = true;
1835 shader.layers[0].dptexflags |= TEXF_ALPHA;
1836 }
1837 }
1838
1840 {
1841 // for a long while, DP treated GL_ONE GL_ONE as GL_SRC_ALPHA GL_ONE
1842 // this cvar brings back this behaviour
1843 if(layer->blendfunc[0] == GL_ONE && layer->blendfunc[1] == GL_ONE)
1844 layer->blendfunc[0] = GL_SRC_ALPHA;
1845 }
1846
1847 layer->dptexflags = 0;
1848 if (layer->alphatest)
1849 layer->dptexflags |= TEXF_ALPHA;
1850 switch(layer->blendfunc[0])
1851 {
1852 case GL_SRC_ALPHA:
1854 layer->dptexflags |= TEXF_ALPHA;
1855 break;
1856 }
1857 switch(layer->blendfunc[1])
1858 {
1859 case GL_SRC_ALPHA:
1861 layer->dptexflags |= TEXF_ALPHA;
1862 break;
1863 }
1864 if (!(shader.surfaceparms & Q3SURFACEPARM_NOMIPMAPS))
1865 layer->dptexflags |= TEXF_MIPMAP;
1866 if (!(shader.textureflags & Q3TEXTUREFLAG_NOPICMIP))
1867 layer->dptexflags |= TEXF_PICMIP | TEXF_COMPRESS;
1868 if (layer->clampmap)
1869 layer->dptexflags |= TEXF_CLAMP;
1870 continue;
1871 }
1872 numparameters = 0;
1873 for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
1874 {
1875 if (j < TEXTURE_MAXFRAMES + 4)
1876 {
1877 // remap dp_water to dpwater, dp_reflect to dpreflect, etc.
1878 if(j == 0 && !strncasecmp(com_token, "dp_", 3))
1879 dpsnprintf(parameter[j], sizeof(parameter[j]), "dp%s", &com_token[3]);
1880 else
1881 dp_strlcpy(parameter[j], com_token, sizeof(parameter[j]));
1882 numparameters = j + 1;
1883 }
1884 if (!COM_ParseToken_QuakeC(&text, true))
1885 break;
1886 }
1887 //for (j = numparameters;j < TEXTURE_MAXFRAMES + 4;j++)
1888 // parameter[j][0] = 0;
1889 if (fileindex == 0 && !strcasecmp(com_token, "}"))
1890 break;
1892 {
1893 Con_DPrintf("%s: ", shader.name);
1894 for (j = 0;j < numparameters;j++)
1895 Con_DPrintf(" %s", parameter[j]);
1896 Con_DPrint("\n");
1897 }
1898 if (numparameters < 1)
1899 continue;
1900 if (!strcasecmp(parameter[0], "surfaceparm") && numparameters >= 2)
1901 {
1902 if (!strcasecmp(parameter[1], "alphashadow"))
1904 else if (!strcasecmp(parameter[1], "areaportal"))
1906 else if (!strcasecmp(parameter[1], "botclip"))
1908 else if (!strcasecmp(parameter[1], "clusterportal"))
1910 else if (!strcasecmp(parameter[1], "detail"))
1912 else if (!strcasecmp(parameter[1], "donotenter"))
1914 else if (!strcasecmp(parameter[1], "dust"))
1916 else if (!strcasecmp(parameter[1], "hint"))
1918 else if (!strcasecmp(parameter[1], "fog"))
1920 else if (!strcasecmp(parameter[1], "lava"))
1922 else if (!strcasecmp(parameter[1], "lightfilter"))
1924 else if (!strcasecmp(parameter[1], "lightgrid"))
1926 else if (!strcasecmp(parameter[1], "metalsteps"))
1928 else if (!strcasecmp(parameter[1], "nodamage"))
1930 else if (!strcasecmp(parameter[1], "nodlight"))
1932 else if (!strcasecmp(parameter[1], "nodraw"))
1934 else if (!strcasecmp(parameter[1], "nodrop"))
1936 else if (!strcasecmp(parameter[1], "noimpact"))
1938 else if (!strcasecmp(parameter[1], "nolightmap"))
1940 else if (!strcasecmp(parameter[1], "nomarks"))
1942 else if (!strcasecmp(parameter[1], "nomipmaps"))
1944 else if (!strcasecmp(parameter[1], "nonsolid"))
1946 else if (!strcasecmp(parameter[1], "origin"))
1948 else if (!strcasecmp(parameter[1], "playerclip"))
1950 else if (!strcasecmp(parameter[1], "sky"))
1952 else if (!strcasecmp(parameter[1], "slick"))
1954 else if (!strcasecmp(parameter[1], "slime"))
1956 else if (!strcasecmp(parameter[1], "structural"))
1958 else if (!strcasecmp(parameter[1], "trans"))
1960 else if (!strcasecmp(parameter[1], "water"))
1962 else if (!strcasecmp(parameter[1], "pointlight"))
1964 else if (!strcasecmp(parameter[1], "antiportal"))
1966 else if (!strcasecmp(parameter[1], "skip"))
1967 ; // shader.surfaceparms |= Q3SURFACEPARM_SKIP; FIXME we don't have enough #defines for this any more, and the engine doesn't need this one anyway
1968 else
1969 {
1970 // try custom surfaceparms
1971 for (j = 0; j < numcustsurfaceflags; j++)
1972 {
1973 if (!strcasecmp(custsurfaceparmnames[j], parameter[1]))
1974 {
1975 shader.surfaceflags |= custsurfaceflags[j];
1976 break;
1977 }
1978 }
1979 // failed all
1980 if (j == numcustsurfaceflags)
1981 Con_DPrintf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]);
1982 }
1983 }
1984 else if (!strcasecmp(parameter[0], "dpshadow"))
1985 shader.dpshadow = true;
1986 else if (!strcasecmp(parameter[0], "dpnoshadow"))
1987 shader.dpnoshadow = true;
1988 else if (!strcasecmp(parameter[0], "dpnortlight"))
1989 shader.dpnortlight = true;
1990 else if (!strcasecmp(parameter[0], "dpreflectcube"))
1991 dp_strlcpy(shader.dpreflectcube, parameter[1], sizeof(shader.dpreflectcube));
1992 else if (!strcasecmp(parameter[0], "dpmeshcollisions"))
1993 shader.dpmeshcollisions = true;
1994 // this sets dpshaderkill to true if dpshaderkillifcvarzero was used, and to false if dpnoshaderkillifcvarzero was used
1995 else if (((dpshaderkill = !strcasecmp(parameter[0], "dpshaderkillifcvarzero")) || !strcasecmp(parameter[0], "dpnoshaderkillifcvarzero")) && numparameters >= 2)
1996 {
1997 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) == 0.0f)
1998 shader.dpshaderkill = dpshaderkill;
1999 }
2000 // this sets dpshaderkill to true if dpshaderkillifcvar was used, and to false if dpnoshaderkillifcvar was used
2001 else if (((dpshaderkill = !strcasecmp(parameter[0], "dpshaderkillifcvar")) || !strcasecmp(parameter[0], "dpnoshaderkillifcvar")) && numparameters >= 2)
2002 {
2003 const char *op = NULL;
2004 if (numparameters >= 3)
2005 op = parameter[2];
2006 if(!op)
2007 {
2008 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) != 0.0f)
2009 shader.dpshaderkill = dpshaderkill;
2010 }
2011 else if (numparameters >= 4 && !strcmp(op, "=="))
2012 {
2013 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) == atof(parameter[3]))
2014 shader.dpshaderkill = dpshaderkill;
2015 }
2016 else if (numparameters >= 4 && !strcmp(op, "!="))
2017 {
2018 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) != atof(parameter[3]))
2019 shader.dpshaderkill = dpshaderkill;
2020 }
2021 else if (numparameters >= 4 && !strcmp(op, ">"))
2022 {
2023 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) > atof(parameter[3]))
2024 shader.dpshaderkill = dpshaderkill;
2025 }
2026 else if (numparameters >= 4 && !strcmp(op, "<"))
2027 {
2028 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) < atof(parameter[3]))
2029 shader.dpshaderkill = dpshaderkill;
2030 }
2031 else if (numparameters >= 4 && !strcmp(op, ">="))
2032 {
2033 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) >= atof(parameter[3]))
2034 shader.dpshaderkill = dpshaderkill;
2035 }
2036 else if (numparameters >= 4 && !strcmp(op, "<="))
2037 {
2038 if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) <= atof(parameter[3]))
2039 shader.dpshaderkill = dpshaderkill;
2040 }
2041 else
2042 {
2043 Con_DPrintf("%s parsing warning: unknown dpshaderkillifcvar op \"%s\", or not enough arguments\n", search->filenames[fileindex], op);
2044 }
2045 }
2046 else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
2047 {
2048 // some q3 skies don't have the sky parm set
2050 dp_strlcpy(shader.skyboxname, parameter[1], sizeof(shader.skyboxname));
2051 }
2052 else if (!strcasecmp(parameter[0], "skyparms") && numparameters >= 2)
2053 {
2054 // some q3 skies don't have the sky parm set
2056 if (!atoi(parameter[1]) && strcasecmp(parameter[1], "-"))
2057 dp_strlcpy(shader.skyboxname, parameter[1], sizeof(shader.skyboxname));
2058 }
2059 else if (!strcasecmp(parameter[0], "cull") && numparameters >= 2)
2060 {
2061 if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "twosided"))
2063 }
2064 else if (!strcasecmp(parameter[0], "nomipmaps"))
2066 else if (!strcasecmp(parameter[0], "nopicmip"))
2068 else if (!strcasecmp(parameter[0], "polygonoffset"))
2070 else if (!strcasecmp(parameter[0], "dppolygonoffset"))
2071 {
2073 if(numparameters >= 2)
2074 {
2075 shader.biaspolygonfactor = atof(parameter[1]);
2076 if(numparameters >= 3)
2077 shader.biaspolygonoffset = atof(parameter[2]);
2078 else
2079 shader.biaspolygonoffset = 0;
2080 }
2081 }
2082 else if (!strcasecmp(parameter[0], "dptransparentsort") && numparameters >= 2)
2083 {
2085 if (!strcasecmp(parameter[1], "sky"))
2087 else if (!strcasecmp(parameter[1], "distance"))
2089 else if (!strcasecmp(parameter[1], "hud"))
2091 else
2092 Con_DPrintf("%s parsing warning: unknown dptransparentsort category \"%s\", or not enough arguments\n", search->filenames[fileindex], parameter[1]);
2093 }
2094 else if (!strcasecmp(parameter[0], "dprefract") && numparameters >= 5)
2095 {
2097 shader.refractfactor = atof(parameter[1]);
2098 Vector4Set(shader.refractcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), 1);
2099 }
2100 else if (!strcasecmp(parameter[0], "dpreflect") && numparameters >= 6)
2101 {
2103 shader.reflectfactor = atof(parameter[1]);
2104 Vector4Set(shader.reflectcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), atof(parameter[5]));
2105 }
2106 else if (!strcasecmp(parameter[0], "dpcamera"))
2107 {
2109 }
2110 else if (!strcasecmp(parameter[0], "dpwater") && numparameters >= 12)
2111 {
2113 shader.reflectmin = atof(parameter[1]);
2114 shader.reflectmax = atof(parameter[2]);
2115 shader.refractfactor = atof(parameter[3]);
2116 shader.reflectfactor = atof(parameter[4]);
2117 Vector4Set(shader.refractcolor4f, atof(parameter[5]), atof(parameter[6]), atof(parameter[7]), 1);
2118 Vector4Set(shader.reflectcolor4f, atof(parameter[8]), atof(parameter[9]), atof(parameter[10]), 1);
2119 shader.r_water_wateralpha = atof(parameter[11]);
2120 }
2121 else if (!strcasecmp(parameter[0], "dpwaterscroll") && numparameters >= 3)
2122 {
2123 shader.r_water_waterscroll[0] = 1/atof(parameter[1]);
2124 shader.r_water_waterscroll[1] = 1/atof(parameter[2]);
2125 }
2126 else if (!strcasecmp(parameter[0], "dpglossintensitymod") && numparameters >= 2)
2127 {
2128 shader.specularscalemod = atof(parameter[1]);
2129 }
2130 else if (!strcasecmp(parameter[0], "dpglossexponentmod") && numparameters >= 2)
2131 {
2132 shader.specularpowermod = atof(parameter[1]);
2133 }
2134 else if (!strcasecmp(parameter[0], "dprtlightambient") && numparameters >= 2)
2135 {
2136 shader.rtlightambient = atof(parameter[1]);
2137 }
2138 else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 2)
2139 {
2140 if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "off"))
2142 else if (!strcasecmp(parameter[1], "default") || !strcasecmp(parameter[1], "normal"))
2144 else if (!strcasecmp(parameter[1], "linear"))
2146 else if (!strcasecmp(parameter[1], "relief"))
2148 if (numparameters >= 3)
2149 shader.offsetscale = atof(parameter[2]);
2150 if (numparameters >= 5)
2151 {
2152 if(!strcasecmp(parameter[3], "bias"))
2153 shader.offsetbias = atof(parameter[4]);
2154 else if(!strcasecmp(parameter[3], "match"))
2155 shader.offsetbias = 1.0f - atof(parameter[4]);
2156 else if(!strcasecmp(parameter[3], "match8"))
2157 shader.offsetbias = 1.0f - atof(parameter[4]) / 255.0f;
2158 else if(!strcasecmp(parameter[3], "match16"))
2159 shader.offsetbias = 1.0f - atof(parameter[4]) / 65535.0f;
2160 }
2161 }
2162 else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
2163 {
2164 int i, deformindex;
2165 for (deformindex = 0;deformindex < Q3MAXDEFORMS;deformindex++)
2166 if (!shader.deforms[deformindex].deform)
2167 break;
2168 if (deformindex < Q3MAXDEFORMS)
2169 {
2170 for (i = 0;i < numparameters - 2 && i < Q3DEFORM_MAXPARMS;i++)
2171 shader.deforms[deformindex].parms[i] = atof(parameter[i+2]);
2172 if (!strcasecmp(parameter[1], "projectionshadow")) shader.deforms[deformindex].deform = Q3DEFORM_PROJECTIONSHADOW;
2173 else if (!strcasecmp(parameter[1], "autosprite" )) shader.deforms[deformindex].deform = Q3DEFORM_AUTOSPRITE;
2174 else if (!strcasecmp(parameter[1], "autosprite2" )) shader.deforms[deformindex].deform = Q3DEFORM_AUTOSPRITE2;
2175 else if (!strcasecmp(parameter[1], "text0" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT0;
2176 else if (!strcasecmp(parameter[1], "text1" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT1;
2177 else if (!strcasecmp(parameter[1], "text2" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT2;
2178 else if (!strcasecmp(parameter[1], "text3" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT3;
2179 else if (!strcasecmp(parameter[1], "text4" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT4;
2180 else if (!strcasecmp(parameter[1], "text5" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT5;
2181 else if (!strcasecmp(parameter[1], "text6" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT6;
2182 else if (!strcasecmp(parameter[1], "text7" )) shader.deforms[deformindex].deform = Q3DEFORM_TEXT7;
2183 else if (!strcasecmp(parameter[1], "bulge" )) shader.deforms[deformindex].deform = Q3DEFORM_BULGE;
2184 else if (!strcasecmp(parameter[1], "normal" )) shader.deforms[deformindex].deform = Q3DEFORM_NORMAL;
2185 else if (!strcasecmp(parameter[1], "wave" ))
2186 {
2187 shader.deforms[deformindex].deform = Q3DEFORM_WAVE;
2188 shader.deforms[deformindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[3]);
2189 for (i = 0;i < numparameters - 4 && i < Q3WAVEPARMS;i++)
2190 shader.deforms[deformindex].waveparms[i] = atof(parameter[i+4]);
2191 }
2192 else if (!strcasecmp(parameter[1], "move" ))
2193 {
2194 shader.deforms[deformindex].deform = Q3DEFORM_MOVE;
2195 shader.deforms[deformindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[5]);
2196 for (i = 0;i < numparameters - 6 && i < Q3WAVEPARMS;i++)
2197 shader.deforms[deformindex].waveparms[i] = atof(parameter[i+6]);
2198 }
2199 }
2200 }
2201 }
2202 // hide this shader if a cvar said it should be killed
2203 if (shader.dpshaderkill)
2204 shader.numlayers = 0;
2205 // fix up multiple reflection types
2208
2209 Q3Shader_AddToHash (&shader);
2210 }
2211 Mem_Free(f);
2212 }
2213 FS_FreeSearch(search);
2214 // free custinfoparm values
2215 for (j = 0; j < numcustsurfaceflags; j++)
2216 Mem_Free(custsurfaceparmnames[j]);
2217}
qbool COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline)
Definition common.c:581
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
Definition console.c:1531
float Cvar_VariableValue(cvar_state_t *cvars, const char *var_name, unsigned neededflags)
Definition cvar.c:129
cvar_state_t cvars_all
Definition cvar.c:28
void FS_FreeSearch(fssearch_t *search)
Definition fs.c:3963
fssearch_t * FS_Search(const char *pattern, int caseinsensitive, int quiet, const char *packfile)
Definition fs.c:3756
#define GL_ONE_MINUS_DST_ALPHA
Definition glquake.h:82
#define GL_ONE_MINUS_DST_COLOR
Definition glquake.h:78
#define GL_SRC_ALPHA
Definition glquake.h:79
#define GL_SRC_COLOR
Definition glquake.h:75
#define GL_ONE_MINUS_SRC_ALPHA
Definition glquake.h:80
#define GL_DST_ALPHA
Definition glquake.h:81
#define GL_DST_COLOR
Definition glquake.h:77
#define GL_ONE_MINUS_SRC_COLOR
Definition glquake.h:76
cvar_t developer_insane
Definition host.c:50
cvar_t mod_q3shader_force_addalpha
Definition model_brush.c:58
cvar_t mod_q3shader_default_polygonfactor
Definition model_brush.c:55
cvar_t mod_q3shader_default_offsetmapping_scale
Definition model_brush.c:53
cvar_t mod_q3shader_default_polygonoffset
Definition model_brush.c:56
cvar_t mod_q3shader_default_offsetmapping_bias
Definition model_brush.c:54
cvar_t mod_q3shader_default_offsetmapping
Definition model_brush.c:52
cvar_t mod_q3shader_force_terrain_alphaflag
Definition model_brush.c:59
#define Q3SURFACEPARM_PLAYERCLIP
#define Q3SURFACEPARM_NOIMPACT
#define Q3SURFACEPARM_STRUCTURAL
#define Q3SURFACEPARM_NONSOLID
#define Q3SURFACEPARM_TRANS
#define Q3SURFACEPARM_FOG
#define Q3SURFACEPARM_NODROP
#define Q3SURFACEPARM_NOMIPMAPS
#define Q3SURFACEPARM_CLUSTERPORTAL
#define Q3SURFACEPARM_NODAMAGE
#define Q3SURFACEPARM_SLICK
#define Q3SURFACEPARM_METALSTEPS
#define Q3SURFACEPARM_NODRAW
#define Q3SURFACEPARM_NOLIGHTMAP
#define Q3SURFACEPARM_LAVA
#define Q3SURFACEPARM_SLIME
#define Q3SURFACEPARM_SKY
#define Q3SURFACEPARM_LIGHTFILTER
#define Q3SURFACEPARM_ANTIPORTAL
#define Q3SURFACEPARM_NOMARKS
#define Q3SURFACEPARM_ORIGIN
#define Q3SURFACEPARM_ALPHASHADOW
#define Q3SURFACEPARM_BOTCLIP
#define Q3SURFACEPARM_DUST
#define Q3SURFACEPARM_WATER
#define Q3SURFACEPARM_DETAIL
#define Q3SURFACEPARM_POINTLIGHT
#define Q3SURFACEPARM_DONOTENTER
#define Q3SURFACEPARM_AREAPORTAL
#define Q3SURFACEPARM_NODLIGHT
#define Q3SURFACEPARM_LIGHTGRID
#define Q3SURFACEPARM_HINT
static void Q3Shader_AddToHash(shader_t *shader)
static q3shader_data_t * q3shader_data
static int Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s)
void Mod_FreeQ3Shaders(void)
#define Q3TEXTUREFLAG_WATERSHADER
Definition r_qshader.h:13
#define Q3PATHLENGTH
Definition r_qshader.h:17
#define Q3TCMOD_MAXPARMS
Definition r_qshader.h:25
#define Q3TEXTUREFLAG_NOPICMIP
Definition r_qshader.h:9
#define TEXTURE_MAXFRAMES
Definition r_qshader.h:18
#define Q3WAVEPARMS
Definition r_qshader.h:19
#define Q3ALPHAGEN_MAXPARMS
Definition r_qshader.h:23
#define Q3RGBGEN_MAXPARMS
Definition r_qshader.h:22
@ Q3RGBGEN_VERTEX
Definition r_qshader.h:77
@ Q3RGBGEN_LIGHTINGDIFFUSE
Definition r_qshader.h:74
@ Q3RGBGEN_CONST
Definition r_qshader.h:70
@ Q3RGBGEN_WAVE
Definition r_qshader.h:78
@ Q3RGBGEN_IDENTITYLIGHTING
Definition r_qshader.h:73
@ Q3RGBGEN_ONEMINUSENTITY
Definition r_qshader.h:75
@ Q3RGBGEN_ONEMINUSVERTEX
Definition r_qshader.h:76
@ Q3RGBGEN_ENTITY
Definition r_qshader.h:71
@ Q3RGBGEN_EXACTVERTEX
Definition r_qshader.h:72
#define Q3TEXTUREFLAG_POLYGONOFFSET
Definition r_qshader.h:10
@ Q3DEFORM_NORMAL
Definition r_qshader.h:61
@ Q3DEFORM_TEXT3
Definition r_qshader.h:54
@ Q3DEFORM_TEXT5
Definition r_qshader.h:56
@ Q3DEFORM_TEXT0
Definition r_qshader.h:51
@ Q3DEFORM_PROJECTIONSHADOW
Definition r_qshader.h:48
@ Q3DEFORM_WAVE
Definition r_qshader.h:60
@ Q3DEFORM_TEXT1
Definition r_qshader.h:52
@ Q3DEFORM_TEXT2
Definition r_qshader.h:53
@ Q3DEFORM_AUTOSPRITE2
Definition r_qshader.h:50
@ Q3DEFORM_TEXT7
Definition r_qshader.h:58
@ Q3DEFORM_MOVE
Definition r_qshader.h:62
@ Q3DEFORM_TEXT6
Definition r_qshader.h:57
@ Q3DEFORM_TEXT4
Definition r_qshader.h:55
@ Q3DEFORM_BULGE
Definition r_qshader.h:59
#define Q3SHADER_MAXLAYERS
Definition r_qshader.h:21
@ TRANSPARENTSORT_SKY
Definition r_qshader.h:193
@ TRANSPARENTSORT_HUD
Definition r_qshader.h:195
#define Q3TEXTUREFLAG_TRANSPARENTSORT
Definition r_qshader.h:15
@ Q3TCMOD_SCALE
Definition r_qshader.h:114
@ Q3TCMOD_ROTATE
Definition r_qshader.h:113
@ Q3TCMOD_ENTITYTRANSLATE
Definition r_qshader.h:112
@ Q3TCMOD_TRANSFORM
Definition r_qshader.h:117
@ Q3TCMOD_SCROLL
Definition r_qshader.h:115
@ Q3TCMOD_PAGE
Definition r_qshader.h:119
@ Q3TCMOD_TURBULENT
Definition r_qshader.h:118
@ Q3TCMOD_STRETCH
Definition r_qshader.h:116
@ OFFSETMAPPING_LINEAR
Definition r_qshader.h:187
@ OFFSETMAPPING_RELIEF
Definition r_qshader.h:188
@ Q3TCGEN_VECTOR
Definition r_qshader.h:104
@ Q3TCGEN_LIGHTMAP
Definition r_qshader.h:103
#define Q3TEXTUREFLAG_CAMERA
Definition r_qshader.h:14
#define Q3TCGEN_MAXPARMS
Definition r_qshader.h:24
@ Q3ALPHAGEN_LIGHTINGSPECULAR
Definition r_qshader.h:88
@ Q3ALPHAGEN_ONEMINUSENTITY
Definition r_qshader.h:89
@ Q3ALPHAGEN_WAVE
Definition r_qshader.h:93
@ Q3ALPHAGEN_ONEMINUSVERTEX
Definition r_qshader.h:90
@ Q3ALPHAGEN_VERTEX
Definition r_qshader.h:92
@ Q3ALPHAGEN_PORTAL
Definition r_qshader.h:91
@ Q3ALPHAGEN_CONST
Definition r_qshader.h:86
@ Q3ALPHAGEN_ENTITY
Definition r_qshader.h:87
#define Q3DEFORM_MAXPARMS
Definition r_qshader.h:20
#define Q3TEXTUREFLAG_REFLECTION
Definition r_qshader.h:12
#define Q3TEXTUREFLAG_TWOSIDED
Definition r_qshader.h:8
#define Q3TEXTUREFLAG_REFRACTION
Definition r_qshader.h:11
#define TEXF_PICMIP
Definition r_textures.h:21
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_MIPMAP
Definition r_textures.h:11
#define TEXF_COMPRESS
Definition r_textures.h:23
#define TEXF_CLAMP
Definition r_textures.h:15
char ** filenames
Definition fs.h:117
int numfilenames
Definition fs.h:116
memexpandablearray_t char_ptrs
memexpandablearray_t hash_entries
q3wavefunc_t wavefunc
Definition r_qshader.h:178
float parms[Q3DEFORM_MAXPARMS]
Definition r_qshader.h:177
float waveparms[Q3WAVEPARMS]
Definition r_qshader.h:179
qbool dpnortlight
Definition r_qshader.h:216
char name[Q3PATHLENGTH]
Definition r_qshader.h:200
float r_water_waterscroll[2]
Definition r_qshader.h:237
float biaspolygonfactor
Definition r_qshader.h:245
qbool dpnoshadow
Definition r_qshader.h:218
qbool vertexalpha
Definition r_qshader.h:207
q3shaderinfo_layer_t layers[Q3SHADER_MAXLAYERS]
Definition r_qshader.h:209
float offsetscale
Definition r_qshader.h:241
dptransparentsortcategory_t transparentsort
Definition r_qshader.h:248
vec4_t refractcolor4f
Definition r_qshader.h:233
q3shaderinfo_deform_t deforms[Q3MAXDEFORMS]
Definition r_qshader.h:211
float r_water_wateralpha
Definition r_qshader.h:236
char skyboxname[Q3PATHLENGTH]
Definition r_qshader.h:210
qbool dpshadow
Definition r_qshader.h:217
qbool lighting
Definition r_qshader.h:206
float reflectmin
Definition r_qshader.h:230
float reflectfactor
Definition r_qshader.h:234
dpoffsetmapping_technique_t offsetmapping
Definition r_qshader.h:240
char dpreflectcube[Q3PATHLENGTH]
Definition r_qshader.h:227
float specularscalemod
Definition r_qshader.h:251
qbool dpmeshcollisions
Definition r_qshader.h:221
float offsetbias
Definition r_qshader.h:242
vec4_t reflectcolor4f
Definition r_qshader.h:235
int textureflags
Definition r_qshader.h:204
qbool dpshaderkill
Definition r_qshader.h:224
int numlayers
Definition r_qshader.h:205
float specularpowermod
Definition r_qshader.h:252
int surfaceflags
Definition r_qshader.h:203
qbool textureblendalpha
Definition r_qshader.h:208
float refractfactor
Definition r_qshader.h:232
int surfaceparms
Definition r_qshader.h:202
float biaspolygonoffset
Definition r_qshader.h:245
float reflectmax
Definition r_qshader.h:231
float rtlightambient
Definition r_qshader.h:255
#define Mem_strdup(pool, s)
Definition zone.h:97

References shader_t::biaspolygonfactor, shader_t::biaspolygonoffset, q3shader_data_t::char_ptrs, COM_ParseToken_QuakeC(), com_token, Con_DPrint(), Con_DPrintf(), Con_Printf(), Cvar_VariableValue(), cvars_all, q3shaderinfo_deform_t::deform, shader_t::deforms, developer_insane, dp_strlcpy, shader_t::dpmeshcollisions, shader_t::dpnortlight, shader_t::dpnoshadow, shader_t::dpreflectcube, shader_t::dpshaderkill, shader_t::dpshadow, dpsnprintf(), q3shaderinfo_layer_t::dptexflags, f, fssearch_t::filenames, FS_FreeSearch(), FS_LoadFile(), FS_Search(), GL_DST_ALPHA, GL_DST_COLOR, GL_ONE, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_COLOR, GL_ZERO, q3shader_data_t::hash_entries, i, int(), cvar_t::integer, layer, shader_t::layers, shader_t::lighting, Mem_Alloc, Mem_AllocPool, Mem_ExpandableArray_AllocRecord(), Mem_ExpandableArray_NewArray(), Mem_Free, Mem_strdup, min, Mod_FreeQ3Shaders(), Mod_LoadQ3Shaders_EnumerateWaveFunc(), mod_q3shader_default_offsetmapping, mod_q3shader_default_offsetmapping_bias, mod_q3shader_default_offsetmapping_scale, mod_q3shader_default_polygonfactor, mod_q3shader_default_polygonoffset, mod_q3shader_force_addalpha, mod_q3shader_force_terrain_alphaflag, shader_t::name, NULL, fssearch_t::numfilenames, shader_t::numlayers, shader_t::offsetbias, shader_t::offsetmapping, OFFSETMAPPING_DEFAULT, OFFSETMAPPING_LINEAR, OFFSETMAPPING_OFF, OFFSETMAPPING_RELIEF, shader_t::offsetscale, q3shaderinfo_deform_t::parms, Q3ALPHAGEN_CONST, Q3ALPHAGEN_ENTITY, Q3ALPHAGEN_IDENTITY, Q3ALPHAGEN_LIGHTINGSPECULAR, Q3ALPHAGEN_MAXPARMS, Q3ALPHAGEN_ONEMINUSENTITY, Q3ALPHAGEN_ONEMINUSVERTEX, Q3ALPHAGEN_PORTAL, Q3ALPHAGEN_VERTEX, Q3ALPHAGEN_WAVE, Q3DEFORM_AUTOSPRITE, Q3DEFORM_AUTOSPRITE2, Q3DEFORM_BULGE, Q3DEFORM_MAXPARMS, Q3DEFORM_MOVE, Q3DEFORM_NONE, Q3DEFORM_NORMAL, Q3DEFORM_PROJECTIONSHADOW, Q3DEFORM_TEXT0, Q3DEFORM_TEXT1, Q3DEFORM_TEXT2, Q3DEFORM_TEXT3, Q3DEFORM_TEXT4, Q3DEFORM_TEXT5, Q3DEFORM_TEXT6, Q3DEFORM_TEXT7, Q3DEFORM_WAVE, Q3MAXDEFORMS, Q3MAXTCMODS, Q3PATHLENGTH, Q3RGBGEN_CONST, Q3RGBGEN_ENTITY, Q3RGBGEN_EXACTVERTEX, Q3RGBGEN_IDENTITY, Q3RGBGEN_IDENTITYLIGHTING, Q3RGBGEN_LIGHTINGDIFFUSE, Q3RGBGEN_MAXPARMS, Q3RGBGEN_ONEMINUSENTITY, Q3RGBGEN_ONEMINUSVERTEX, Q3RGBGEN_VERTEX, Q3RGBGEN_WAVE, Q3Shader_AddToHash(), q3shader_data, Q3SHADER_MAXLAYERS, q3shaders_mem, Q3SURFACEPARM_ALPHASHADOW, Q3SURFACEPARM_ANTIPORTAL, Q3SURFACEPARM_AREAPORTAL, Q3SURFACEPARM_BOTCLIP, Q3SURFACEPARM_CLUSTERPORTAL, Q3SURFACEPARM_DETAIL, Q3SURFACEPARM_DONOTENTER, Q3SURFACEPARM_DUST, Q3SURFACEPARM_FOG, Q3SURFACEPARM_HINT, Q3SURFACEPARM_LAVA, Q3SURFACEPARM_LIGHTFILTER, Q3SURFACEPARM_LIGHTGRID, Q3SURFACEPARM_METALSTEPS, Q3SURFACEPARM_NODAMAGE, Q3SURFACEPARM_NODLIGHT, Q3SURFACEPARM_NODRAW, Q3SURFACEPARM_NODROP, Q3SURFACEPARM_NOIMPACT, Q3SURFACEPARM_NOLIGHTMAP, Q3SURFACEPARM_NOMARKS, Q3SURFACEPARM_NOMIPMAPS, Q3SURFACEPARM_NONSOLID, Q3SURFACEPARM_ORIGIN, Q3SURFACEPARM_PLAYERCLIP, Q3SURFACEPARM_POINTLIGHT, Q3SURFACEPARM_SKY, Q3SURFACEPARM_SLICK, Q3SURFACEPARM_SLIME, Q3SURFACEPARM_STRUCTURAL, Q3SURFACEPARM_TRANS, Q3SURFACEPARM_WATER, Q3TCGEN_ENVIRONMENT, Q3TCGEN_LIGHTMAP, Q3TCGEN_MAXPARMS, Q3TCGEN_TEXTURE, Q3TCGEN_VECTOR, Q3TCMOD_ENTITYTRANSLATE, Q3TCMOD_MAXPARMS, Q3TCMOD_PAGE, Q3TCMOD_ROTATE, Q3TCMOD_SCALE, Q3TCMOD_SCROLL, Q3TCMOD_STRETCH, Q3TCMOD_TRANSFORM, Q3TCMOD_TURBULENT, Q3TEXTUREFLAG_CAMERA, Q3TEXTUREFLAG_NOPICMIP, Q3TEXTUREFLAG_POLYGONOFFSET, Q3TEXTUREFLAG_REFLECTION, Q3TEXTUREFLAG_REFRACTION, Q3TEXTUREFLAG_TRANSPARENTSORT, Q3TEXTUREFLAG_TWOSIDED, Q3TEXTUREFLAG_WATERSHADER, Q3WAVEPARMS, shader_t::r_water_wateralpha, shader_t::r_water_waterscroll, shader_t::reflectcolor4f, shader_t::reflectfactor, shader_t::reflectmax, shader_t::reflectmin, shader_t::refractcolor4f, shader_t::refractfactor, shader_t::rtlightambient, shader_t::skyboxname, shader_t::specularpowermod, shader_t::specularscalemod, strlen(), shader_t::surfaceflags, shader_t::surfaceparms, tempmempool, TEXF_ALPHA, TEXF_CLAMP, TEXF_COMPRESS, TEXF_MIPMAP, TEXF_PICMIP, TEXTURE_MAXFRAMES, shader_t::textureblendalpha, shader_t::textureflags, shader_t::transparentsort, TRANSPARENTSORT_DISTANCE, TRANSPARENTSORT_HUD, TRANSPARENTSORT_SKY, cvar_t::value, Vector4Set, shader_t::vertexalpha, q3shaderinfo_deform_t::wavefunc, and q3shaderinfo_deform_t::waveparms.

Referenced by Mod_LoadModel(), and Mod_LookupQ3Shader().

◆ Mod_LoadQ3Shaders_EnumerateWaveFunc()

static int Mod_LoadQ3Shaders_EnumerateWaveFunc ( const char * s)
static

Definition at line 1381 of file model_shared.c.

1382{
1383 int offset = 0;
1384 if (!strncasecmp(s, "user", 4)) // parse stuff like "user1sin", always user<n>func
1385 {
1386 offset = bound(0, s[4] - '0', 9);
1388 s += 4;
1389 if(*s)
1390 ++s;
1391 }
1392 if (!strcasecmp(s, "sin")) return offset | Q3WAVEFUNC_SIN;
1393 if (!strcasecmp(s, "square")) return offset | Q3WAVEFUNC_SQUARE;
1394 if (!strcasecmp(s, "triangle")) return offset | Q3WAVEFUNC_TRIANGLE;
1395 if (!strcasecmp(s, "sawtooth")) return offset | Q3WAVEFUNC_SAWTOOTH;
1396 if (!strcasecmp(s, "inversesawtooth")) return offset | Q3WAVEFUNC_INVERSESAWTOOTH;
1397 if (!strcasecmp(s, "noise")) return offset | Q3WAVEFUNC_NOISE;
1398 if (!strcasecmp(s, "none")) return offset | Q3WAVEFUNC_NONE;
1399 Con_DPrintf("Mod_LoadQ3Shaders: unknown wavefunc %s\n", s);
1400 return offset | Q3WAVEFUNC_NONE;
1401}
GLuint GLuint GLintptr offset
Definition glquake.h:632
#define Q3WAVEFUNC_USER_SHIFT
Definition r_qshader.h:43
@ Q3WAVEFUNC_INVERSESAWTOOTH
Definition r_qshader.h:32
@ Q3WAVEFUNC_SAWTOOTH
Definition r_qshader.h:34
@ Q3WAVEFUNC_TRIANGLE
Definition r_qshader.h:37
@ Q3WAVEFUNC_NOISE
Definition r_qshader.h:33
@ Q3WAVEFUNC_NONE
Definition r_qshader.h:31
@ Q3WAVEFUNC_SIN
Definition r_qshader.h:35
@ Q3WAVEFUNC_SQUARE
Definition r_qshader.h:36

References bound, Con_DPrintf(), offset, Q3WAVEFUNC_INVERSESAWTOOTH, Q3WAVEFUNC_NOISE, Q3WAVEFUNC_NONE, Q3WAVEFUNC_SAWTOOTH, Q3WAVEFUNC_SIN, Q3WAVEFUNC_SQUARE, Q3WAVEFUNC_TRIANGLE, and Q3WAVEFUNC_USER_SHIFT.

Referenced by Mod_LoadQ3Shaders().

◆ Mod_LoadSkinFiles()

skinfile_t * Mod_LoadSkinFiles ( void )

Definition at line 2705 of file model_shared.c.

2706{
2707 int i, words, line, wordsoverflow;
2708 char *text;
2709 const char *data;
2710 skinfile_t *skinfile = NULL, *first = NULL;
2711 skinfileitem_t *skinfileitem;
2712 char word[10][MAX_QPATH];
2713 char vabuf[1024];
2714
2715/*
2716sample file:
2717U_bodyBox,models/players/Legoman/BikerA2.tga
2718U_RArm,models/players/Legoman/BikerA1.tga
2719U_LArm,models/players/Legoman/BikerA1.tga
2720U_armor,common/nodraw
2721U_sword,common/nodraw
2722U_shield,common/nodraw
2723U_homb,common/nodraw
2724U_backpack,common/nodraw
2725U_colcha,common/nodraw
2726tag_head,
2727tag_weapon,
2728tag_torso,
2729*/
2730 memset(word, 0, sizeof(word));
2731 for (i = 0;i < 256 && (data = text = (char *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s_%i.skin", loadmodel->name, i), tempmempool, true, NULL));i++)
2732 {
2733 // If it's the first file we parse
2734 if (skinfile == NULL)
2735 {
2736 skinfile = (skinfile_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfile_t));
2737 first = skinfile;
2738 }
2739 else
2740 {
2741 skinfile->next = (skinfile_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfile_t));
2742 skinfile = skinfile->next;
2743 }
2744 skinfile->next = NULL;
2745
2746 for(line = 0;;line++)
2747 {
2748 // parse line
2749 if (!COM_ParseToken_QuakeC(&data, true))
2750 break;
2751 if (!strcmp(com_token, "\n"))
2752 continue;
2753 words = 0;
2754 wordsoverflow = false;
2755 do
2756 {
2757 if (words < 10)
2758 dp_strlcpy(word[words++], com_token, sizeof (word[0]));
2759 else
2760 wordsoverflow = true;
2761 }
2762 while (COM_ParseToken_QuakeC(&data, true) && strcmp(com_token, "\n"));
2763 if (wordsoverflow)
2764 {
2765 Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: line with too many statements, skipping\n", loadmodel->name, i, line);
2766 continue;
2767 }
2768 // words is always >= 1
2769 if (!strcmp(word[0], "replace"))
2770 {
2771 if (words == 3)
2772 {
2774 Con_Printf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
2775 skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
2776 skinfileitem->next = skinfile->items;
2777 skinfile->items = skinfileitem;
2778 dp_strlcpy (skinfileitem->name, word[1], sizeof (skinfileitem->name));
2779 dp_strlcpy (skinfileitem->replacement, word[2], sizeof (skinfileitem->replacement));
2780 }
2781 else
2782 Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: wrong number of parameters to command \"%s\", see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n", loadmodel->name, i, line, word[0]);
2783 }
2784 else if (words >= 2 && !strncmp(word[0], "tag_", 4))
2785 {
2786 // tag name, like "tag_weapon,"
2787 // not used for anything (not even in Quake3)
2788 }
2789 else if (words >= 2 && !strcmp(word[1], ","))
2790 {
2791 // mesh shader name, like "U_RArm,models/players/Legoman/BikerA1.tga"
2793 Con_Printf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
2794 skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
2795 skinfileitem->next = skinfile->items;
2796 skinfile->items = skinfileitem;
2797 dp_strlcpy (skinfileitem->name, word[0], sizeof (skinfileitem->name));
2798 dp_strlcpy (skinfileitem->replacement, word[2], sizeof (skinfileitem->replacement));
2799 }
2800 else
2801 Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: does not look like tag or mesh specification, or replace command, see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n", loadmodel->name, i, line);
2802 }
2803 Mem_Free(text);
2804 }
2805 if (i)
2806 loadmodel->numskins = i;
2807 return first;
2808}
char name[MAX_QPATH]
char replacement[MAX_QPATH]

References COM_ParseToken_QuakeC(), com_token, Con_Printf(), data, developer_loading, dp_strlcpy, first, FS_LoadFile(), i, cvar_t::integer, skinfile_t::items, loadmodel, MAX_QPATH, Mem_Alloc, Mem_Free, model_t::mempool, model_t::name, skinfileitem_t::name, skinfile_t::next, skinfileitem_t::next, NULL, model_t::numskins, skinfileitem_t::replacement, tempmempool, and va().

Referenced by Mod_DARKPLACESMODEL_Load(), Mod_IDP0_Load(), Mod_IDP2_Load(), Mod_IDP3_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), and Mod_ZYMOTICMODEL_Load().

◆ Mod_LoadTextureFromQ3Shader()

qbool Mod_LoadTextureFromQ3Shader ( mempool_t * mempool,
const char * modelname,
texture_t * texture,
const char * name,
qbool warnmissing,
qbool fallback,
int defaulttexflags,
int defaultmaterialflags )

Definition at line 2270 of file model_shared.c.

2271{
2272 int texflagsmask, texflagsor;
2273 qbool success = true;
2274 shader_t *shader;
2275 if (!name)
2276 name = "";
2277 dp_strlcpy(texture->name, name, sizeof(texture->name));
2278 texture->basealpha = 1.0f;
2279 shader = name[0] ? Mod_LookupQ3Shader(name) : NULL;
2280
2281 // allow disabling of picmip or compression by defaulttexflags
2282 texflagsmask = ~0;
2283 if(!(defaulttexflags & TEXF_PICMIP))
2284 texflagsmask &= ~TEXF_PICMIP;
2285 if(!(defaulttexflags & TEXF_COMPRESS))
2286 texflagsmask &= ~TEXF_COMPRESS;
2287 texflagsor = 0;
2288 if(defaulttexflags & TEXF_ISWORLD)
2289 texflagsor |= TEXF_ISWORLD;
2290 if(defaulttexflags & TEXF_ISSPRITE)
2291 texflagsor |= TEXF_ISSPRITE;
2292 // unless later loaded from the shader
2294 texture->offsetscale = 1;
2295 texture->offsetbias = 0;
2296 texture->specularscalemod = 1;
2297 texture->specularpowermod = 1;
2298 texture->rtlightambient = 0;
2299 texture->transparentsort = TRANSPARENTSORT_DISTANCE;
2300 // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
2301 // JUST GREP FOR "specularscalemod = 1".
2302
2303 if (shader)
2304 {
2306 Con_Printf("%s: loaded shader for %s\n", modelname, name);
2307
2308 if (shader->surfaceparms & Q3SURFACEPARM_SKY)
2309 {
2310 texture->basematerialflags = MATERIALFLAG_SKY;
2311 if (shader->skyboxname[0] && loadmodel)
2312 {
2313 // quake3 seems to append a _ to the skybox name, so this must do so as well
2314 dpsnprintf(loadmodel->brush.skybox, sizeof(loadmodel->brush.skybox), "%s_", shader->skyboxname);
2315 }
2316 }
2317 else if ((texture->surfaceflags & Q3SURFACEFLAG_NODRAW) || shader->numlayers == 0)
2318 texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
2319 else
2320 texture->basematerialflags = MATERIALFLAG_WALL;
2321
2322 if (shader->layers[0].alphatest)
2327 {
2328 texture->biaspolygonoffset += shader->biaspolygonoffset;
2329 texture->biaspolygonfactor += shader->biaspolygonfactor;
2330 }
2332 texture->basematerialflags |= MATERIALFLAG_REFRACTION;
2334 texture->basematerialflags |= MATERIALFLAG_REFLECTION;
2336 texture->basematerialflags |= MATERIALFLAG_WATERSHADER;
2337 if (shader->textureflags & Q3TEXTUREFLAG_CAMERA)
2338 texture->basematerialflags |= MATERIALFLAG_CAMERA;
2339 texture->customblendfunc[0] = GL_ONE;
2340 texture->customblendfunc[1] = GL_ZERO;
2341 texture->transparentsort = shader->transparentsort;
2342 if (shader->numlayers > 0)
2343 {
2344 texture->customblendfunc[0] = shader->layers[0].blendfunc[0];
2345 texture->customblendfunc[1] = shader->layers[0].blendfunc[1];
2346/*
2347Q3 shader blendfuncs actually used in the game (* = supported by DP)
2348* additive GL_ONE GL_ONE
2349additive weird GL_ONE GL_SRC_ALPHA
2350additive weird 2 GL_ONE GL_ONE_MINUS_SRC_ALPHA
2351* alpha GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
2352alpha inverse GL_ONE_MINUS_SRC_ALPHA GL_SRC_ALPHA
2353brighten GL_DST_COLOR GL_ONE
2354brighten GL_ONE GL_SRC_COLOR
2355brighten weird GL_DST_COLOR GL_ONE_MINUS_DST_ALPHA
2356brighten weird 2 GL_DST_COLOR GL_SRC_ALPHA
2357* modulate GL_DST_COLOR GL_ZERO
2358* modulate GL_ZERO GL_SRC_COLOR
2359modulate inverse GL_ZERO GL_ONE_MINUS_SRC_COLOR
2360modulate inverse alpha GL_ZERO GL_SRC_ALPHA
2361modulate weird inverse GL_ONE_MINUS_DST_COLOR GL_ZERO
2362* modulate x2 GL_DST_COLOR GL_SRC_COLOR
2363* no blend GL_ONE GL_ZERO
2364nothing GL_ZERO GL_ONE
2365*/
2366 // if not opaque, figure out what blendfunc to use
2367 if (shader->layers[0].blendfunc[0] != GL_ONE || shader->layers[0].blendfunc[1] != GL_ZERO)
2368 {
2369 if (shader->layers[0].blendfunc[0] == GL_ONE && shader->layers[0].blendfunc[1] == GL_ONE)
2371 else if (shader->layers[0].blendfunc[0] == GL_SRC_ALPHA && shader->layers[0].blendfunc[1] == GL_ONE)
2373 else if (shader->layers[0].blendfunc[0] == GL_SRC_ALPHA && shader->layers[0].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA)
2375 else
2377 }
2378 }
2379 if (!shader->lighting)
2380 texture->basematerialflags |= MATERIALFLAG_FULLBRIGHT;
2381
2382 // here be dragons: convert quake3 shaders to material
2383 if (shader->numlayers > 0)
2384 {
2385 int i;
2386 int terrainbackgroundlayer = -1;
2387 int lightmaplayer = -1;
2388 int alphagenspecularlayer = -1;
2389 int rgbgenvertexlayer = -1;
2390 int rgbgendiffuselayer = -1;
2391 int materiallayer = -1;
2392 int endofprelayers = 0;
2393 int firstpostlayer = 0;
2394 int shaderpassindex = 0;
2395 for (i = 0; i < shader->numlayers; i++)
2396 {
2397 if (shader->layers[i].texturename != NULL && !strcasecmp(shader->layers[i].texturename[0], "$lightmap"))
2398 lightmaplayer = i;
2399 if (shader->layers[i].rgbgen.rgbgen == Q3RGBGEN_VERTEX)
2400 rgbgenvertexlayer = i;
2402 rgbgendiffuselayer = i;
2404 alphagenspecularlayer = i;
2405 }
2406 if (shader->numlayers >= 2
2407 && shader->layers[1].alphagen.alphagen == Q3ALPHAGEN_VERTEX
2408 && (shader->layers[0].blendfunc[0] == GL_ONE && shader->layers[0].blendfunc[1] == GL_ZERO && !shader->layers[0].alphatest)
2409 && ((shader->layers[1].blendfunc[0] == GL_SRC_ALPHA && shader->layers[1].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA)
2410 || (shader->layers[1].blendfunc[0] == GL_ONE && shader->layers[1].blendfunc[1] == GL_ZERO && shader->layers[1].alphatest)))
2411 {
2412 // terrain blend or certain other effects involving alphatest over a regular layer
2413 terrainbackgroundlayer = 0;
2414 materiallayer = 1;
2415 // terrain may be vertex lit (in which case both layers are rgbGen vertex) or lightmapped (in which ase the third layer is lightmap)
2416 firstpostlayer = lightmaplayer >= 0 ? lightmaplayer + 1 : materiallayer + 1;
2417 }
2418 else if (lightmaplayer == 0)
2419 {
2420 // ordinary texture but with $lightmap before diffuse
2421 materiallayer = 1;
2422 firstpostlayer = lightmaplayer + 2;
2423 }
2424 else if (lightmaplayer >= 1)
2425 {
2426 // ordinary texture - we don't properly apply lighting to the prelayers, but oh well...
2427 endofprelayers = lightmaplayer - 1;
2428 materiallayer = lightmaplayer - 1;
2429 firstpostlayer = lightmaplayer + 1;
2430 }
2431 else if (rgbgenvertexlayer >= 0)
2432 {
2433 // map models with baked lighting
2434 materiallayer = rgbgenvertexlayer;
2435 endofprelayers = rgbgenvertexlayer;
2436 firstpostlayer = rgbgenvertexlayer + 1;
2437 // special case for rgbgen vertex if MATERIALFLAG_VERTEXCOLOR is expected on this material
2438 if (defaultmaterialflags & MATERIALFLAG_VERTEXCOLOR)
2440 }
2441 else if (rgbgendiffuselayer >= 0)
2442 {
2443 // entity models with dynamic lighting
2444 materiallayer = rgbgendiffuselayer;
2445 endofprelayers = rgbgendiffuselayer;
2446 firstpostlayer = rgbgendiffuselayer + 1;
2447 // player models often have specular as a pass after diffuse - we don't currently make use of that specular texture (would need to meld it into the skinframe)...
2448 if (alphagenspecularlayer >= 0)
2449 firstpostlayer = alphagenspecularlayer + 1;
2450 }
2451 else
2452 {
2453 // special effects shaders - treat first as primary layer and do everything else as post
2454 endofprelayers = 0;
2455 materiallayer = 0;
2456 firstpostlayer = 1;
2457 }
2458 // convert the main material layer
2459 // FIXME: if alphagenspecularlayer is used, we should pass a specular texture name to R_SkinFrame_LoadExternal and have it load that texture instead of the assumed name for _gloss texture
2460 if (materiallayer >= 0)
2461 texture->materialshaderpass = texture->shaderpasses[shaderpassindex++] = Mod_CreateShaderPassFromQ3ShaderLayer(mempool, modelname, &shader->layers[materiallayer], materiallayer, (shader->layers[materiallayer].dptexflags & texflagsmask) | texflagsor, texture->name);
2462 // convert the terrain background blend layer (if any)
2463 if (terrainbackgroundlayer >= 0)
2464 texture->backgroundshaderpass = texture->shaderpasses[shaderpassindex++] = Mod_CreateShaderPassFromQ3ShaderLayer(mempool, modelname, &shader->layers[terrainbackgroundlayer], terrainbackgroundlayer, (shader->layers[terrainbackgroundlayer].dptexflags & texflagsmask) | texflagsor, texture->name);
2465 // convert the prepass layers (if any)
2466 texture->startpreshaderpass = shaderpassindex;
2467 for (i = 0; i < endofprelayers; i++)
2468 texture->shaderpasses[shaderpassindex++] = Mod_CreateShaderPassFromQ3ShaderLayer(mempool, modelname, &shader->layers[i], i, (shader->layers[i].dptexflags & texflagsmask) | texflagsor, texture->name);
2469 texture->endpreshaderpass = shaderpassindex;
2470 texture->startpostshaderpass = shaderpassindex;
2471 // convert the postpass layers (if any)
2472 for (i = firstpostlayer; i < shader->numlayers; i++)
2473 texture->shaderpasses[shaderpassindex++] = Mod_CreateShaderPassFromQ3ShaderLayer(mempool, modelname, &shader->layers[i], i, (shader->layers[i].dptexflags & texflagsmask) | texflagsor, texture->name);
2474 texture->startpostshaderpass = shaderpassindex;
2475 }
2476
2477 if (shader->dpshadow)
2478 texture->basematerialflags &= ~MATERIALFLAG_NOSHADOW;
2479 if (shader->dpnoshadow)
2480 texture->basematerialflags |= MATERIALFLAG_NOSHADOW;
2481 if (shader->dpnortlight)
2482 texture->basematerialflags |= MATERIALFLAG_NORTLIGHT;
2483 if (shader->vertexalpha)
2484 texture->basematerialflags |= MATERIALFLAG_ALPHAGEN_VERTEX;
2485 memcpy(texture->deforms, shader->deforms, sizeof(texture->deforms));
2486 texture->reflectmin = shader->reflectmin;
2487 texture->reflectmax = shader->reflectmax;
2488 texture->refractfactor = shader->refractfactor;
2489 Vector4Copy(shader->refractcolor4f, texture->refractcolor4f);
2490 texture->reflectfactor = shader->reflectfactor;
2491 Vector4Copy(shader->reflectcolor4f, texture->reflectcolor4f);
2492 texture->r_water_wateralpha = shader->r_water_wateralpha;
2493 Vector2Copy(shader->r_water_waterscroll, texture->r_water_waterscroll);
2494 texture->offsetmapping = shader->offsetmapping;
2495 texture->offsetscale = shader->offsetscale;
2496 texture->offsetbias = shader->offsetbias;
2497 texture->specularscalemod = shader->specularscalemod;
2498 texture->specularpowermod = shader->specularpowermod;
2499 texture->rtlightambient = shader->rtlightambient;
2501 if (shader->dpreflectcube[0])
2502 texture->reflectcubetexture = R_GetCubemap(shader->dpreflectcube);
2503
2504 // set up default supercontents (on q3bsp this is overridden by the q3bsp loader)
2506 if (shader->surfaceparms & Q3SURFACEPARM_LAVA ) texture->supercontents = SUPERCONTENTS_LAVA ;
2507 if (shader->surfaceparms & Q3SURFACEPARM_SLIME ) texture->supercontents = SUPERCONTENTS_SLIME ;
2508 if (shader->surfaceparms & Q3SURFACEPARM_WATER ) texture->supercontents = SUPERCONTENTS_WATER ;
2509 if (shader->surfaceparms & Q3SURFACEPARM_NONSOLID ) texture->supercontents = 0 ;
2511 if (shader->surfaceparms & Q3SURFACEPARM_BOTCLIP ) texture->supercontents = SUPERCONTENTS_MONSTERCLIP ;
2512 if (shader->surfaceparms & Q3SURFACEPARM_SKY ) texture->supercontents = SUPERCONTENTS_SKY ;
2513
2514 // if (shader->surfaceparms & Q3SURFACEPARM_ALPHASHADOW ) texture->supercontents |= SUPERCONTENTS_ALPHASHADOW ;
2515 // if (shader->surfaceparms & Q3SURFACEPARM_AREAPORTAL ) texture->supercontents |= SUPERCONTENTS_AREAPORTAL ;
2516 // if (shader->surfaceparms & Q3SURFACEPARM_CLUSTERPORTAL) texture->supercontents |= SUPERCONTENTS_CLUSTERPORTAL;
2517 // if (shader->surfaceparms & Q3SURFACEPARM_DETAIL ) texture->supercontents |= SUPERCONTENTS_DETAIL ;
2518 if (shader->surfaceparms & Q3SURFACEPARM_DONOTENTER ) texture->supercontents |= SUPERCONTENTS_DONOTENTER ;
2519 // if (shader->surfaceparms & Q3SURFACEPARM_FOG ) texture->supercontents |= SUPERCONTENTS_FOG ;
2520 if (shader->surfaceparms & Q3SURFACEPARM_LAVA ) texture->supercontents |= SUPERCONTENTS_LAVA ;
2521 // if (shader->surfaceparms & Q3SURFACEPARM_LIGHTFILTER ) texture->supercontents |= SUPERCONTENTS_LIGHTFILTER ;
2522 // if (shader->surfaceparms & Q3SURFACEPARM_METALSTEPS ) texture->supercontents |= SUPERCONTENTS_METALSTEPS ;
2523 // if (shader->surfaceparms & Q3SURFACEPARM_NODAMAGE ) texture->supercontents |= SUPERCONTENTS_NODAMAGE ;
2524 // if (shader->surfaceparms & Q3SURFACEPARM_NODLIGHT ) texture->supercontents |= SUPERCONTENTS_NODLIGHT ;
2525 // if (shader->surfaceparms & Q3SURFACEPARM_NODRAW ) texture->supercontents |= SUPERCONTENTS_NODRAW ;
2526 if (shader->surfaceparms & Q3SURFACEPARM_NODROP ) texture->supercontents |= SUPERCONTENTS_NODROP ;
2527 // if (shader->surfaceparms & Q3SURFACEPARM_NOIMPACT ) texture->supercontents |= SUPERCONTENTS_NOIMPACT ;
2528 // if (shader->surfaceparms & Q3SURFACEPARM_NOLIGHTMAP ) texture->supercontents |= SUPERCONTENTS_NOLIGHTMAP ;
2529 // if (shader->surfaceparms & Q3SURFACEPARM_NOMARKS ) texture->supercontents |= SUPERCONTENTS_NOMARKS ;
2530 // if (shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS ) texture->supercontents |= SUPERCONTENTS_NOMIPMAPS ;
2531 if (shader->surfaceparms & Q3SURFACEPARM_NONSOLID ) texture->supercontents &=~SUPERCONTENTS_SOLID ;
2532 // if (shader->surfaceparms & Q3SURFACEPARM_ORIGIN ) texture->supercontents |= SUPERCONTENTS_ORIGIN ;
2533 if (shader->surfaceparms & Q3SURFACEPARM_PLAYERCLIP ) texture->supercontents |= SUPERCONTENTS_PLAYERCLIP ;
2534 if (shader->surfaceparms & Q3SURFACEPARM_SKY ) texture->supercontents |= SUPERCONTENTS_SKY ;
2535 // if (shader->surfaceparms & Q3SURFACEPARM_SLICK ) texture->supercontents |= SUPERCONTENTS_SLICK ;
2536 if (shader->surfaceparms & Q3SURFACEPARM_SLIME ) texture->supercontents |= SUPERCONTENTS_SLIME ;
2537 // if (shader->surfaceparms & Q3SURFACEPARM_STRUCTURAL ) texture->supercontents |= SUPERCONTENTS_STRUCTURAL ;
2538 // if (shader->surfaceparms & Q3SURFACEPARM_TRANS ) texture->supercontents |= SUPERCONTENTS_TRANS ;
2539 if (shader->surfaceparms & Q3SURFACEPARM_WATER ) texture->supercontents |= SUPERCONTENTS_WATER ;
2540 // if (shader->surfaceparms & Q3SURFACEPARM_POINTLIGHT ) texture->supercontents |= SUPERCONTENTS_POINTLIGHT ;
2541 // if (shader->surfaceparms & Q3SURFACEPARM_HINT ) texture->supercontents |= SUPERCONTENTS_HINT ;
2542 // if (shader->surfaceparms & Q3SURFACEPARM_DUST ) texture->supercontents |= SUPERCONTENTS_DUST ;
2544 // if (shader->surfaceparms & Q3SURFACEPARM_LIGHTGRID ) texture->supercontents |= SUPERCONTENTS_LIGHTGRID ;
2545 // if (shader->surfaceparms & Q3SURFACEPARM_ANTIPORTAL ) texture->supercontents |= SUPERCONTENTS_ANTIPORTAL ;
2546
2547 texture->surfaceflags = shader->surfaceflags;
2549 // if (shader->surfaceparms & Q3SURFACEPARM_AREAPORTAL ) texture->surfaceflags |= Q3SURFACEFLAG_AREAPORTAL ;
2550 // if (shader->surfaceparms & Q3SURFACEPARM_CLUSTERPORTAL) texture->surfaceflags |= Q3SURFACEFLAG_CLUSTERPORTAL;
2551 // if (shader->surfaceparms & Q3SURFACEPARM_DETAIL ) texture->surfaceflags |= Q3SURFACEFLAG_DETAIL ;
2552 // if (shader->surfaceparms & Q3SURFACEPARM_DONOTENTER ) texture->surfaceflags |= Q3SURFACEFLAG_DONOTENTER ;
2553 // if (shader->surfaceparms & Q3SURFACEPARM_FOG ) texture->surfaceflags |= Q3SURFACEFLAG_FOG ;
2554 // if (shader->surfaceparms & Q3SURFACEPARM_LAVA ) texture->surfaceflags |= Q3SURFACEFLAG_LAVA ;
2557 if (shader->surfaceparms & Q3SURFACEPARM_NODAMAGE ) texture->surfaceflags |= Q3SURFACEFLAG_NODAMAGE ;
2558 if (shader->surfaceparms & Q3SURFACEPARM_NODLIGHT ) texture->surfaceflags |= Q3SURFACEFLAG_NODLIGHT ;
2559 if (shader->surfaceparms & Q3SURFACEPARM_NODRAW ) texture->surfaceflags |= Q3SURFACEFLAG_NODRAW ;
2560 // if (shader->surfaceparms & Q3SURFACEPARM_NODROP ) texture->surfaceflags |= Q3SURFACEFLAG_NODROP ;
2561 if (shader->surfaceparms & Q3SURFACEPARM_NOIMPACT ) texture->surfaceflags |= Q3SURFACEFLAG_NOIMPACT ;
2563 if (shader->surfaceparms & Q3SURFACEPARM_NOMARKS ) texture->surfaceflags |= Q3SURFACEFLAG_NOMARKS ;
2564 // if (shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS ) texture->surfaceflags |= Q3SURFACEFLAG_NOMIPMAPS ;
2565 if (shader->surfaceparms & Q3SURFACEPARM_NONSOLID ) texture->surfaceflags |= Q3SURFACEFLAG_NONSOLID ;
2566 // if (shader->surfaceparms & Q3SURFACEPARM_ORIGIN ) texture->surfaceflags |= Q3SURFACEFLAG_ORIGIN ;
2567 // if (shader->surfaceparms & Q3SURFACEPARM_PLAYERCLIP ) texture->surfaceflags |= Q3SURFACEFLAG_PLAYERCLIP ;
2568 if (shader->surfaceparms & Q3SURFACEPARM_SKY ) texture->surfaceflags |= Q3SURFACEFLAG_SKY ;
2569 if (shader->surfaceparms & Q3SURFACEPARM_SLICK ) texture->surfaceflags |= Q3SURFACEFLAG_SLICK ;
2570 // if (shader->surfaceparms & Q3SURFACEPARM_SLIME ) texture->surfaceflags |= Q3SURFACEFLAG_SLIME ;
2571 // if (shader->surfaceparms & Q3SURFACEPARM_STRUCTURAL ) texture->surfaceflags |= Q3SURFACEFLAG_STRUCTURAL ;
2572 // if (shader->surfaceparms & Q3SURFACEPARM_TRANS ) texture->surfaceflags |= Q3SURFACEFLAG_TRANS ;
2573 // if (shader->surfaceparms & Q3SURFACEPARM_WATER ) texture->surfaceflags |= Q3SURFACEFLAG_WATER ;
2575 if (shader->surfaceparms & Q3SURFACEPARM_HINT ) texture->surfaceflags |= Q3SURFACEFLAG_HINT ;
2576 if (shader->surfaceparms & Q3SURFACEPARM_DUST ) texture->surfaceflags |= Q3SURFACEFLAG_DUST ;
2577 // if (shader->surfaceparms & Q3SURFACEPARM_BOTCLIP ) texture->surfaceflags |= Q3SURFACEFLAG_BOTCLIP ;
2578 // if (shader->surfaceparms & Q3SURFACEPARM_LIGHTGRID ) texture->surfaceflags |= Q3SURFACEFLAG_LIGHTGRID ;
2579 // if (shader->surfaceparms & Q3SURFACEPARM_ANTIPORTAL ) texture->surfaceflags |= Q3SURFACEFLAG_ANTIPORTAL ;
2580
2581 if (shader->dpmeshcollisions)
2582 texture->basematerialflags |= MATERIALFLAG_MESHCOLLISIONS;
2583 if (shader->dpshaderkill && developer_extra.integer)
2584 Con_DPrintf("^1%s:^7 killing shader ^3\"%s\" because of cvar\n", modelname, name);
2585 }
2586 else if (!strcmp(texture->name, "noshader") || !texture->name[0])
2587 {
2589 Con_DPrintf("^1%s:^7 using fallback noshader material for ^3\"%s\"\n", modelname, name);
2590 texture->basematerialflags = defaultmaterialflags;
2592 }
2593 else if (!strcmp(texture->name, "common/nodraw") || !strcmp(texture->name, "textures/common/nodraw"))
2594 {
2596 Con_DPrintf("^1%s:^7 using fallback nodraw material for ^3\"%s\"\n", modelname, name);
2597 texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
2598 texture->supercontents = SUPERCONTENTS_SOLID;
2599 }
2600 else
2601 {
2603 Con_DPrintf("^1%s:^7 No shader found for texture ^3\"%s\"\n", modelname, texture->name);
2604 if (texture->surfaceflags & Q3SURFACEFLAG_NODRAW)
2605 {
2606 texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
2607 texture->supercontents = SUPERCONTENTS_SOLID;
2608 }
2609 else if (texture->surfaceflags & Q3SURFACEFLAG_SKY)
2610 {
2611 texture->basematerialflags = MATERIALFLAG_SKY;
2612 texture->supercontents = SUPERCONTENTS_SKY;
2613 }
2614 else
2615 {
2616 texture->basematerialflags = defaultmaterialflags;
2618 }
2619 if(cls.state == ca_dedicated)
2620 {
2621 texture->materialshaderpass = NULL;
2622 success = false;
2623 }
2624 else
2625 {
2626 skinframe_t *skinframe = R_SkinFrame_LoadExternal(texture->name, defaulttexflags, false, fallback);
2627 if (skinframe)
2628 {
2629 texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(mempool, skinframe);
2630 if (texture->materialshaderpass->skinframes[0]->hasalpha)
2632 if (texture->q2contents)
2633 texture->supercontents = Mod_Q2BSP_SuperContentsFromNativeContents(texture->q2contents);
2634 }
2635 else
2636 success = false;
2637 if (!success && warnmissing)
2638 Con_Printf("^1%s:^7 could not load texture ^3\"%s\"\n", modelname, texture->name);
2639 }
2640 }
2641 // init the animation variables
2642 texture->currentframe = texture;
2643 texture->currentmaterialflags = texture->basematerialflags;
2644 if (!texture->materialshaderpass)
2645 texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(mempool, R_SkinFrame_LoadMissing());
2646 if (!texture->materialshaderpass->skinframes[0])
2647 texture->materialshaderpass->skinframes[0] = R_SkinFrame_LoadMissing();
2648 texture->currentskinframe = texture->materialshaderpass ? texture->materialshaderpass->skinframes[0] : NULL;
2649 texture->backgroundcurrentskinframe = texture->backgroundshaderpass ? texture->backgroundshaderpass->skinframes[0] : NULL;
2650 return success;
2651}
#define SUPERCONTENTS_SKY
Definition bspfile.h:200
#define SUPERCONTENTS_OPAQUE
Definition bspfile.h:208
#define SUPERCONTENTS_LAVA
Definition bspfile.h:199
#define SUPERCONTENTS_DONOTENTER
Definition bspfile.h:206
#define SUPERCONTENTS_MONSTERCLIP
Definition bspfile.h:205
#define SUPERCONTENTS_BOTCLIP
Definition bspfile.h:207
#define SUPERCONTENTS_SLIME
Definition bspfile.h:198
#define SUPERCONTENTS_PLAYERCLIP
Definition bspfile.h:204
#define SUPERCONTENTS_NODROP
Definition bspfile.h:203
#define SUPERCONTENTS_WATER
Definition bspfile.h:197
rtexture_t * R_GetCubemap(const char *basename)
Definition gl_rmain.c:2982
skinframe_t * R_SkinFrame_LoadMissing(void)
Definition gl_rmain.c:2804
#define Vector2Copy(in, out)
Definition mathlib.h:74
#define Vector4Copy(in, out)
Definition mathlib.h:84
int Mod_Q2BSP_SuperContentsFromNativeContents(int nativecontents)
cvar_t mod_q3shader_default_refractive_index
Definition model_brush.c:57
#define MATERIALFLAG_ADD
Definition model_brush.h:81
#define MATERIALFLAG_VERTEXCOLOR
#define MATERIALFLAG_FULLBRIGHT
Definition model_brush.h:87
#define MATERIALFLAG_ALPHA
Definition model_brush.h:79
#define MATERIALFLAG_REFRACTION
#define MATERIALFLAG_NODRAW
Definition model_brush.h:96
#define MATERIALFLAG_ALPHATEST
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_ALPHAGEN_VERTEX
#define MATERIALFLAG_WATERSHADER
#define MATERIALFLAG_CAMERA
#define MATERIALFLAG_MESHCOLLISIONS
Definition model_brush.h:77
#define MATERIALFLAG_REFLECTION
#define MATERIALFLAG_NOCULLFACE
#define MATERIALFLAG_CUSTOMBLEND
#define MATERIALFLAG_NORTLIGHT
#define Q3SURFACEFLAG_SKY
#define Q3SURFACEFLAG_NOMARKS
#define Q3SURFACEFLAG_SLICK
#define Q3SURFACEFLAG_METALSTEPS
#define Q3SURFACEFLAG_ALPHASHADOW
#define Q3SURFACEFLAG_NOIMPACT
#define Q3SURFACEFLAG_LIGHTFILTER
#define Q3SURFACEFLAG_NOLIGHTMAP
#define Q3SURFACEFLAG_HINT
#define Q3SURFACEFLAG_DUST
#define Q3SURFACEFLAG_NODRAW
#define Q3SURFACEFLAG_POINTLIGHT
#define Q3SURFACEFLAG_NONSOLID
#define Q3SURFACEFLAG_NODLIGHT
#define Q3SURFACEFLAG_NODAMAGE
shader_t * Mod_LookupQ3Shader(const char *name)
texture_shaderpass_t * Mod_CreateShaderPassFromQ3ShaderLayer(mempool_t *mempool, const char *modelname, q3shaderinfo_layer_t *layer, int layerindex, int texflags, const char *texturename)
#define TEXF_ISWORLD
Definition r_textures.h:33
#define TEXF_ISSPRITE
Definition r_textures.h:35
char skybox[MAX_QPATH]
q3shaderinfo_layer_alphagen_t alphagen
Definition r_qshader.h:168
q3shaderinfo_layer_rgbgen_t rgbgen
Definition r_qshader.h:167

References q3shaderinfo_layer_alphagen_t::alphagen, q3shaderinfo_layer_t::alphagen, q3shaderinfo_layer_t::alphatest, shader_t::biaspolygonfactor, shader_t::biaspolygonoffset, q3shaderinfo_layer_t::blendfunc, model_t::brush, ca_dedicated, cls, Con_DPrintf(), Con_Printf(), shader_t::deforms, developer_extra, developer_loading, dp_strlcpy, shader_t::dpmeshcollisions, shader_t::dpnortlight, shader_t::dpnoshadow, shader_t::dpreflectcube, shader_t::dpshaderkill, shader_t::dpshadow, dpsnprintf(), q3shaderinfo_layer_t::dptexflags, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ZERO, i, cvar_t::integer, shader_t::layers, shader_t::lighting, loadmodel, MATERIALFLAG_ADD, MATERIALFLAG_ALPHA, MATERIALFLAG_ALPHAGEN_VERTEX, MATERIALFLAG_ALPHATEST, MATERIALFLAG_BLENDED, MATERIALFLAG_CAMERA, MATERIALFLAG_CUSTOMBLEND, MATERIALFLAG_FULLBRIGHT, MATERIALFLAG_MESHCOLLISIONS, MATERIALFLAG_NOCULLFACE, MATERIALFLAG_NODRAW, MATERIALFLAG_NORTLIGHT, MATERIALFLAG_NOSHADOW, MATERIALFLAG_REFLECTION, MATERIALFLAG_REFRACTION, MATERIALFLAG_SKY, MATERIALFLAG_VERTEXCOLOR, MATERIALFLAG_WALL, MATERIALFLAG_WATERSHADER, Mod_CreateShaderPass(), Mod_CreateShaderPassFromQ3ShaderLayer(), Mod_LookupQ3Shader(), mod_noshader_default_offsetmapping, Mod_Q2BSP_SuperContentsFromNativeContents(), mod_q3shader_default_refractive_index, name, NULL, shader_t::numlayers, shader_t::offsetbias, shader_t::offsetmapping, OFFSETMAPPING_DEFAULT, OFFSETMAPPING_OFF, shader_t::offsetscale, Q3ALPHAGEN_LIGHTINGSPECULAR, Q3ALPHAGEN_VERTEX, Q3RGBGEN_LIGHTINGDIFFUSE, Q3RGBGEN_VERTEX, Q3SURFACEFLAG_ALPHASHADOW, Q3SURFACEFLAG_DUST, Q3SURFACEFLAG_HINT, Q3SURFACEFLAG_LIGHTFILTER, Q3SURFACEFLAG_METALSTEPS, Q3SURFACEFLAG_NODAMAGE, Q3SURFACEFLAG_NODLIGHT, Q3SURFACEFLAG_NODRAW, Q3SURFACEFLAG_NOIMPACT, Q3SURFACEFLAG_NOLIGHTMAP, Q3SURFACEFLAG_NOMARKS, Q3SURFACEFLAG_NONSOLID, Q3SURFACEFLAG_POINTLIGHT, Q3SURFACEFLAG_SKY, Q3SURFACEFLAG_SLICK, Q3SURFACEPARM_ALPHASHADOW, Q3SURFACEPARM_BOTCLIP, Q3SURFACEPARM_DONOTENTER, Q3SURFACEPARM_DUST, Q3SURFACEPARM_HINT, Q3SURFACEPARM_LAVA, Q3SURFACEPARM_LIGHTFILTER, Q3SURFACEPARM_METALSTEPS, Q3SURFACEPARM_NODAMAGE, Q3SURFACEPARM_NODLIGHT, Q3SURFACEPARM_NODRAW, Q3SURFACEPARM_NODROP, Q3SURFACEPARM_NOIMPACT, Q3SURFACEPARM_NOLIGHTMAP, Q3SURFACEPARM_NOMARKS, Q3SURFACEPARM_NONSOLID, Q3SURFACEPARM_PLAYERCLIP, Q3SURFACEPARM_POINTLIGHT, Q3SURFACEPARM_SKY, Q3SURFACEPARM_SLICK, Q3SURFACEPARM_SLIME, Q3SURFACEPARM_WATER, Q3TEXTUREFLAG_CAMERA, Q3TEXTUREFLAG_POLYGONOFFSET, Q3TEXTUREFLAG_REFLECTION, Q3TEXTUREFLAG_REFRACTION, Q3TEXTUREFLAG_TWOSIDED, Q3TEXTUREFLAG_WATERSHADER, R_GetCubemap(), R_SkinFrame_LoadExternal(), R_SkinFrame_LoadMissing(), shader_t::r_water_wateralpha, shader_t::r_water_waterscroll, shader_t::reflectcolor4f, shader_t::reflectfactor, shader_t::reflectmax, shader_t::reflectmin, shader_t::refractcolor4f, shader_t::refractfactor, q3shaderinfo_layer_rgbgen_t::rgbgen, q3shaderinfo_layer_t::rgbgen, shader_t::rtlightambient, model_brush_t::skybox, shader_t::skyboxname, shader_t::specularpowermod, shader_t::specularscalemod, client_static_t::state, SUPERCONTENTS_BOTCLIP, SUPERCONTENTS_DONOTENTER, SUPERCONTENTS_LAVA, SUPERCONTENTS_MONSTERCLIP, SUPERCONTENTS_NODROP, SUPERCONTENTS_OPAQUE, SUPERCONTENTS_PLAYERCLIP, SUPERCONTENTS_SKY, SUPERCONTENTS_SLIME, SUPERCONTENTS_SOLID, SUPERCONTENTS_WATER, shader_t::surfaceflags, shader_t::surfaceparms, TEXF_COMPRESS, TEXF_ISSPRITE, TEXF_ISWORLD, TEXF_PICMIP, texture, shader_t::textureflags, q3shaderinfo_layer_t::texturename, shader_t::transparentsort, TRANSPARENTSORT_DISTANCE, cvar_t::value, Vector2Copy, Vector4Copy, and shader_t::vertexalpha.

Referenced by CL_Beams_SetupExternalTexture(), Mod_BuildAliasSkinsFromSkinFiles(), Mod_IDP0_Load(), Mod_IDP2_Load(), Mod_Mesh_GetTexture(), Mod_Q1BSP_LoadTextures(), Mod_Q2BSP_LoadTexinfo(), and Mod_Q3BSP_LoadTextures().

◆ Mod_LookupQ3Shader()

shader_t * Mod_LookupQ3Shader ( const char * name)

Definition at line 2219 of file model_shared.c.

2220{
2221 unsigned short hash;
2222 q3shader_hash_entry_t* entry;
2223 if (!q3shaders_mem)
2225 hash = CRC_Block_CaseInsensitive ((const unsigned char *)name, strlen (name));
2226 entry = q3shader_data->hash + (hash % Q3SHADER_HASH_SIZE);
2227 while (entry != NULL)
2228 {
2229 if (strcasecmp (entry->shader.name, name) == 0)
2230 return &entry->shader;
2231 entry = entry->chain;
2232 }
2233 return NULL;
2234}
unsigned short CRC_Block_CaseInsensitive(const unsigned char *data, size_t size)
Definition com_crc16.c:83
#define Q3SHADER_HASH_SIZE
q3shader_hash_entry_t hash[Q3SHADER_HASH_SIZE]
struct q3shader_hash_entry_s * chain
shader_t shader

References q3shader_hash_entry_t::chain, CRC_Block_CaseInsensitive(), q3shader_data_t::hash, Mod_LoadQ3Shaders(), name, shader_t::name, NULL, q3shader_data, Q3SHADER_HASH_SIZE, q3shaders_mem, q3shader_hash_entry_t::shader, and strlen().

Referenced by Mod_LoadTextureFromQ3Shader().

◆ Mod_MakeSortedSurfaces()

void Mod_MakeSortedSurfaces ( model_t * mod)

Definition at line 2936 of file model_shared.c.

2937{
2938 // make an optimal set of texture-sorted batches to draw...
2939 int j, k;
2941
2942 if(cls.state == ca_dedicated)
2943 return;
2944
2945 info = (Mod_MakeSortedSurfaces_qsortsurface_t*)Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*info));
2946 if (!mod->modelsurfaces_sorted)
2947 mod->modelsurfaces_sorted = (int *) Mem_Alloc(loadmodel->mempool, mod->num_surfaces * sizeof(*mod->modelsurfaces_sorted));
2948 // the goal is to sort by submodel (can't change which submodel a surface belongs to), and then by effects and textures
2949 for (j = 0; j < mod->num_surfaces; j++)
2950 {
2951 info[j].surfaceindex = j;
2952 info[j].effect = mod->data_surfaces[j].effect;
2953 info[j].texture = mod->data_surfaces[j].texture;
2954 info[j].lightmaptexture = mod->data_surfaces[j].lightmaptexture;
2955 }
2956 for (k = 0; k < mod->brush.numsubmodels; k++)
2957 if (mod->brush.submodels[k]->submodelsurfaces_end > mod->brush.submodels[k]->submodelsurfaces_start + 1)
2958 qsort(info + mod->brush.submodels[k]->submodelsurfaces_start, (size_t)mod->brush.submodels[k]->submodelsurfaces_end - mod->brush.submodels[k]->submodelsurfaces_start, sizeof(*info), Mod_MakeSortedSurfaces_qsortfunc);
2959 for (j = 0; j < mod->num_surfaces; j++)
2960 mod->modelsurfaces_sorted[j] = info[j].surfaceindex;
2961 Mem_Free(info);
2962}
static int Mod_MakeSortedSurfaces_qsortfunc(const void *a, const void *b)

References ca_dedicated, cls, Mod_MakeSortedSurfaces_qsortsurface_t::effect, Mod_MakeSortedSurfaces_qsortsurface_t::lightmaptexture, loadmodel, Mem_Alloc, Mem_Free, model_t::mempool, mod(), Mod_MakeSortedSurfaces_qsortfunc(), client_static_t::state, Mod_MakeSortedSurfaces_qsortsurface_t::surfaceindex, and Mod_MakeSortedSurfaces_qsortsurface_t::texture.

Referenced by Mod_DARKPLACESMODEL_Load(), Mod_IDP3_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), Mod_Q1BSP_Load(), Mod_Q2BSP_Load(), Mod_Q3BSP_Load(), and Mod_ZYMOTICMODEL_Load().

◆ Mod_MakeSortedSurfaces_qsortfunc()

static int Mod_MakeSortedSurfaces_qsortfunc ( const void * a,
const void * b )
static

Definition at line 2913 of file model_shared.c.

2914{
2917 if (l->effect < r->effect)
2918 return -1;
2919 if (l->effect > r->effect)
2920 return 1;
2921 if (l->texture < r->texture)
2922 return -1;
2923 if (l->texture > r->texture)
2924 return 1;
2925 if (l->lightmaptexture < r->lightmaptexture)
2926 return -1;
2927 if (l->lightmaptexture > r->lightmaptexture)
2928 return 1;
2929 if (l->surfaceindex < r->surfaceindex)
2930 return -1;
2931 if (l->surfaceindex > r->surfaceindex)
2932 return 1;
2933 return 0;
2934}
dp_FragColor r

References a, b, Mod_MakeSortedSurfaces_qsortsurface_t::effect, Mod_MakeSortedSurfaces_qsortsurface_t::lightmaptexture, r, Mod_MakeSortedSurfaces_qsortsurface_t::surfaceindex, and Mod_MakeSortedSurfaces_qsortsurface_t::texture.

Referenced by Mod_MakeSortedSurfaces().

◆ Mod_Mesh_AddSurface()

msurface_t * Mod_Mesh_AddSurface ( model_t * mod,
texture_t * tex,
qbool batchwithprevioussurface )

Definition at line 4528 of file model_shared.c.

4529{
4530 msurface_t *surf;
4531 // batch if possible; primarily useful for UI rendering where bounding boxes don't matter
4532 if (batchwithprevioussurface && mod->num_surfaces > 0 && mod->data_surfaces[mod->num_surfaces - 1].texture == tex)
4533 return mod->data_surfaces + mod->num_surfaces - 1;
4534 // create new surface
4535 if (mod->max_surfaces == mod->num_surfaces)
4536 {
4537 mod->max_surfaces = 2 * max(mod->num_surfaces, 64);
4538 mod->data_surfaces = (msurface_t *)Mem_Realloc(mod->mempool, mod->data_surfaces, mod->max_surfaces * sizeof(*mod->data_surfaces));
4539 mod->modelsurfaces_sorted = (int *)Mem_Realloc(mod->mempool, mod->modelsurfaces_sorted, mod->max_surfaces * sizeof(*mod->modelsurfaces_sorted));
4540 }
4541 surf = mod->data_surfaces + mod->num_surfaces;
4542 mod->num_surfaces++;
4543 memset(surf, 0, sizeof(*surf));
4544 surf->texture = tex;
4545 surf->num_firsttriangle = mod->surfmesh.num_triangles;
4546 surf->num_firstvertex = mod->surfmesh.num_vertices;
4548 mod->DrawSky = R_Mod_DrawSky;
4550 mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
4551 return surf;
4552}
void R_Mod_DrawSky(entity_render_t *ent)
Definition gl_rsurf.c:596
void R_Mod_DrawAddWaterPlanes(entity_render_t *ent)
Definition gl_rsurf.c:603
#define Mem_Realloc(pool, data, size)
Definition zone.h:94

References texture_t::basematerialflags, MATERIALFLAG_CAMERA, MATERIALFLAG_REFLECTION, MATERIALFLAG_REFRACTION, MATERIALFLAG_SKY, MATERIALFLAG_WATERSHADER, max, Mem_Realloc, mod(), msurface_t::num_firsttriangle, msurface_t::num_firstvertex, R_Mod_DrawAddWaterPlanes(), R_Mod_DrawSky(), and msurface_t::texture.

Referenced by CL_Beam_AddPolygons(), DrawQ_Line(), DrawQ_Pic(), DrawQ_RotPic(), DrawQ_String_Scale(), DrawQ_SuperPic(), R_DebugLine(), and VM_CL_R_PolygonEnd().

◆ Mod_Mesh_AddTriangle()

void Mod_Mesh_AddTriangle ( model_t * mod,
msurface_t * surf,
int e0,
int e1,
int e2 )

Definition at line 4633 of file model_shared.c.

4634{
4635 surfmesh_t *mesh = &mod->surfmesh;
4636 if (mesh->max_triangles == mesh->num_triangles)
4637 {
4638 mesh->max_triangles = 2 * max(mesh->num_triangles, 128);
4639 mesh->data_element3s = (unsigned short *)Mem_Realloc(mod->mempool, mesh->data_element3s, mesh->max_triangles * sizeof(unsigned short[3]));
4640 mesh->data_element3i = (int *)Mem_Realloc(mod->mempool, mesh->data_element3i, mesh->max_triangles * sizeof(int[3]));
4641 }
4642 mesh->data_element3s[mesh->num_triangles * 3 + 0] = e0;
4643 mesh->data_element3s[mesh->num_triangles * 3 + 1] = e1;
4644 mesh->data_element3s[mesh->num_triangles * 3 + 2] = e2;
4645 mesh->data_element3i[mesh->num_triangles * 3 + 0] = e0;
4646 mesh->data_element3i[mesh->num_triangles * 3 + 1] = e1;
4647 mesh->data_element3i[mesh->num_triangles * 3 + 2] = e2;
4648 mesh->num_triangles++;
4649 surf->num_triangles++;
4650}

References surfmesh_t::data_element3i, surfmesh_t::data_element3s, max, surfmesh_t::max_triangles, Mem_Realloc, mod(), msurface_t::num_triangles, and surfmesh_t::num_triangles.

Referenced by CL_Beam_AddQuad(), DrawQ_Line(), DrawQ_Pic(), DrawQ_RotPic(), DrawQ_String_Scale(), DrawQ_SuperPic(), R_DebugLine(), and VM_CL_R_PolygonEnd().

◆ Mod_Mesh_ComputeBounds()

static void Mod_Mesh_ComputeBounds ( model_t * mod)
static

Definition at line 4680 of file model_shared.c.

4681{
4682 int i;
4683 vec_t x2a, x2b, y2a, y2b, z2a, z2b, x2, y2, z2, yawradius, rotatedradius;
4684
4685 if (mod->surfmesh.num_vertices > 0)
4686 {
4687 // calculate normalmins/normalmaxs
4688 VectorCopy(mod->surfmesh.data_vertex3f, mod->normalmins);
4689 VectorCopy(mod->surfmesh.data_vertex3f, mod->normalmaxs);
4690 for (i = 1; i < mod->surfmesh.num_vertices; i++)
4691 {
4692 float x = mod->surfmesh.data_vertex3f[i * 3 + 0];
4693 float y = mod->surfmesh.data_vertex3f[i * 3 + 1];
4694 float z = mod->surfmesh.data_vertex3f[i * 3 + 2];
4695 // expand bounds to include this vertex
4696 if (mod->normalmins[0] > x) mod->normalmins[0] = x;
4697 if (mod->normalmins[1] > y) mod->normalmins[1] = y;
4698 if (mod->normalmins[2] > z) mod->normalmins[2] = z;
4699 if (mod->normalmaxs[0] < x) mod->normalmaxs[0] = x;
4700 if (mod->normalmaxs[1] < y) mod->normalmaxs[1] = y;
4701 if (mod->normalmaxs[2] < z) mod->normalmaxs[2] = z;
4702 }
4703 // calculate yawmins/yawmaxs, rotatedmins/maxs from normalmins/maxs
4704 // (fast but less accurate than doing it per vertex)
4705 x2a = mod->normalmins[0] * mod->normalmins[0];
4706 x2b = mod->normalmaxs[0] * mod->normalmaxs[0];
4707 y2a = mod->normalmins[1] * mod->normalmins[1];
4708 y2b = mod->normalmaxs[1] * mod->normalmaxs[1];
4709 z2a = mod->normalmins[2] * mod->normalmins[2];
4710 z2b = mod->normalmaxs[2] * mod->normalmaxs[2];
4711 x2 = max(x2a, x2b);
4712 y2 = max(y2a, y2b);
4713 z2 = max(z2a, z2b);
4714 yawradius = sqrt(x2 + y2);
4715 rotatedradius = sqrt(x2 + y2 + z2);
4716 VectorSet(mod->yawmins, -yawradius, -yawradius, mod->normalmins[2]);
4717 VectorSet(mod->yawmaxs, yawradius, yawradius, mod->normalmaxs[2]);
4718 VectorSet(mod->rotatedmins, -rotatedradius, -rotatedradius, -rotatedradius);
4719 VectorSet(mod->rotatedmaxs, rotatedradius, rotatedradius, rotatedradius);
4720 mod->radius = rotatedradius;
4721 mod->radius2 = x2 + y2 + z2;
4722 }
4723 else
4724 {
4725 VectorClear(mod->normalmins);
4726 VectorClear(mod->normalmaxs);
4727 VectorClear(mod->yawmins);
4728 VectorClear(mod->yawmaxs);
4729 VectorClear(mod->rotatedmins);
4730 VectorClear(mod->rotatedmaxs);
4731 mod->radius = 0;
4732 mod->radius2 = 0;
4733 }
4734}
float vec_t
Definition qtypes.h:68
vec3 y2
vec3 x2

References i, max, mod(), sqrt(), VectorClear, VectorCopy, VectorSet, x, x2, y, y2, and z.

Referenced by Mod_Mesh_Finalize().

◆ Mod_Mesh_Create()

void Mod_Mesh_Create ( model_t * mod,
const char * name )

Definition at line 4443 of file model_shared.c.

4444{
4445 memset(mod, 0, sizeof(*mod));
4446 dp_strlcpy(mod->name, name, sizeof(mod->name));
4447 mod->mempool = Mem_AllocPool(name, 0, NULL);
4448 mod->texturepool = R_AllocTexturePool();
4449 mod->Draw = R_Mod_Draw;
4450 mod->DrawDepth = R_Mod_DrawDepth;
4451 mod->DrawDebug = R_Mod_DrawDebug;
4452 mod->DrawPrepass = R_Mod_DrawPrepass;
4453 mod->GetLightInfo = R_Mod_GetLightInfo;
4454 mod->DrawShadowMap = R_Mod_DrawShadowMap;
4455 mod->DrawLight = R_Mod_DrawLight;
4456}
void R_Mod_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes, qbool noocclusion)
Definition gl_rsurf.c:1202
void R_Mod_DrawDebug(entity_render_t *ent)
Definition gl_rsurf.c:660
void R_Mod_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist, const unsigned char *lighttrispvs)
Definition gl_rsurf.c:1399
void R_Mod_Draw(entity_render_t *ent)
Definition gl_rsurf.c:637
void R_Mod_DrawShadowMap(int side, entity_render_t *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs)
Definition gl_rsurf.c:1320
void R_Mod_DrawDepth(entity_render_t *ent)
Definition gl_rsurf.c:645
void R_Mod_DrawPrepass(entity_render_t *ent)
Definition gl_rsurf.c:667

References dp_strlcpy, Mem_AllocPool, mod(), name, NULL, R_AllocTexturePool(), R_Mod_Draw(), R_Mod_DrawDebug(), R_Mod_DrawDepth(), R_Mod_DrawLight(), R_Mod_DrawPrepass(), R_Mod_DrawShadowMap(), and R_Mod_GetLightInfo().

Referenced by CL_MeshEntities_Init(), CL_MeshEntities_Restart(), and CL_MeshEntities_Start().

◆ Mod_Mesh_Destroy()

void Mod_Mesh_Destroy ( model_t * mod)

Definition at line 4458 of file model_shared.c.

4459{
4461}

References mod(), and Mod_UnloadModel().

Referenced by CL_MeshEntities_Restart(), and CL_MeshEntities_Shutdown().

◆ Mod_Mesh_Finalize()

void Mod_Mesh_Finalize ( model_t * mod)

Definition at line 4775 of file model_shared.c.

4776{
4777 if (gl_paranoid.integer)
4782 Mod_BuildTextureVectorsFromNormals(0, mod->surfmesh.num_vertices, mod->surfmesh.num_triangles, mod->surfmesh.data_vertex3f, mod->surfmesh.data_texcoordtexture2f, mod->surfmesh.data_normal3f, mod->surfmesh.data_element3i, mod->surfmesh.data_svector3f, mod->surfmesh.data_tvector3f, true);
4784}
r_refdef_t r_refdef
Definition gl_rmain.c:57
static void Mod_Mesh_ComputeBounds(model_t *mod)
void Mod_Mesh_Validate(model_t *mod)
static void Mod_Mesh_UploadDynamicBuffers(model_t *mod)
void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qbool areaweighting)
static void Mod_Mesh_MakeSortedSurfaces(model_t *mod)
int draw2dstage
Definition render.h:452

References r_refdef_t::draw2dstage, gl_paranoid, cvar_t::integer, mod(), Mod_BuildTextureVectorsFromNormals(), Mod_Mesh_ComputeBounds(), Mod_Mesh_MakeSortedSurfaces(), Mod_Mesh_UploadDynamicBuffers(), Mod_Mesh_Validate(), and r_refdef.

Referenced by CL_MeshEntities_Scene_FinalizeRenderEntity(), and DrawQ_FlushUI().

◆ Mod_Mesh_GetTexture()

texture_t * Mod_Mesh_GetTexture ( model_t * mod,
const char * name,
int defaultdrawflags,
int defaulttexflags,
int defaultmaterialflags )

Definition at line 4476 of file model_shared.c.

4477{
4478 int i;
4479 texture_t *t;
4480 int drawflag = defaultdrawflags & DRAWFLAG_MASK;
4481 for (i = 0, t = mod->data_textures; i < mod->num_textures; i++, t++)
4482 if (!strcmp(t->name, name) && t->mesh_drawflag == drawflag && t->mesh_defaulttexflags == defaulttexflags && t->mesh_defaultmaterialflags == defaultmaterialflags)
4483 return t;
4484 if (mod->max_textures <= mod->num_textures)
4485 {
4486 texture_t *oldtextures = mod->data_textures;
4487 mod->max_textures = max(mod->max_textures * 2, 1024);
4488 mod->data_textures = (texture_t *)Mem_Realloc(mod->mempool, mod->data_textures, mod->max_textures * sizeof(*mod->data_textures));
4489 // update the pointers
4490 for (i = 0; i < mod->num_surfaces; i++)
4491 mod->data_surfaces[i].texture = mod->data_textures + (mod->data_surfaces[i].texture - oldtextures);
4492 }
4493 t = &mod->data_textures[mod->num_textures++];
4494 Mod_LoadTextureFromQ3Shader(mod->mempool, mod->name, t, name, true, true, defaulttexflags, defaultmaterialflags);
4495 t->mesh_drawflag = drawflag;
4496 t->mesh_defaulttexflags = defaulttexflags;
4497 t->mesh_defaultmaterialflags = defaultmaterialflags;
4498 switch (defaultdrawflags & DRAWFLAG_MASK)
4499 {
4500 case DRAWFLAG_ADDITIVE:
4503 break;
4504 case DRAWFLAG_MODULATE:
4508 t->customblendfunc[1] = GL_ZERO;
4509 break;
4515 break;
4516 case DRAWFLAG_SCREEN:
4520 t->customblendfunc[1] = GL_ONE;
4521 break;
4522 default:
4523 break;
4524 }
4525 return t;
4526}
const float DRAWFLAG_ADDITIVE
const float DRAWFLAG_2XMODULATE
const float DRAWFLAG_SCREEN
const float DRAWFLAG_MODULATE
@ DRAWFLAG_MASK
Definition draw.h:80
qbool Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qbool warnmissing, qbool fallback, int defaulttexflags, int defaultmaterialflags)
int currentmaterialflags
int mesh_drawflag
int mesh_defaulttexflags
int mesh_defaultmaterialflags
int customblendfunc[2]

References texture_t::basematerialflags, texture_t::currentmaterialflags, texture_t::customblendfunc, DRAWFLAG_2XMODULATE, DRAWFLAG_ADDITIVE, DRAWFLAG_MASK, DRAWFLAG_MODULATE, DRAWFLAG_SCREEN, GL_DST_COLOR, GL_ONE, GL_ONE_MINUS_DST_COLOR, GL_SRC_COLOR, GL_ZERO, i, MATERIALFLAG_ADD, MATERIALFLAG_BLENDED, MATERIALFLAG_CUSTOMBLEND, max, Mem_Realloc, texture_t::mesh_defaultmaterialflags, texture_t::mesh_defaulttexflags, texture_t::mesh_drawflag, mod(), Mod_LoadTextureFromQ3Shader(), name, and texture_t::name.

Referenced by DrawQ_Line(), DrawQ_Pic(), DrawQ_RotPic(), DrawQ_String_Scale(), DrawQ_SuperPic(), R_DebugLine(), and VM_CL_R_PolygonEnd().

◆ Mod_Mesh_IndexForVertex()

int Mod_Mesh_IndexForVertex ( model_t * mod,
msurface_t * surf,
float x,
float y,
float z,
float nx,
float ny,
float nz,
float s,
float t,
float u,
float v,
float r,
float g,
float b,
float a )

Definition at line 4554 of file model_shared.c.

4555{
4556 int hashindex, h, vnum, mask;
4557 surfmesh_t *mesh = &mod->surfmesh;
4558 if (mesh->max_vertices == mesh->num_vertices)
4559 {
4560 mesh->max_vertices = max(mesh->num_vertices * 2, 256);
4561 mesh->data_vertex3f = (float *)Mem_Realloc(mod->mempool, mesh->data_vertex3f, mesh->max_vertices * sizeof(float[3]));
4562 mesh->data_svector3f = (float *)Mem_Realloc(mod->mempool, mesh->data_svector3f, mesh->max_vertices * sizeof(float[3]));
4563 mesh->data_tvector3f = (float *)Mem_Realloc(mod->mempool, mesh->data_tvector3f, mesh->max_vertices * sizeof(float[3]));
4564 mesh->data_normal3f = (float *)Mem_Realloc(mod->mempool, mesh->data_normal3f, mesh->max_vertices * sizeof(float[3]));
4565 mesh->data_texcoordtexture2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordtexture2f, mesh->max_vertices * sizeof(float[2]));
4566 mesh->data_texcoordlightmap2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordlightmap2f, mesh->max_vertices * sizeof(float[2]));
4567 mesh->data_lightmapcolor4f = (float *)Mem_Realloc(mod->mempool, mesh->data_lightmapcolor4f, mesh->max_vertices * sizeof(float[4]));
4568 // rebuild the hash table
4569 mesh->num_vertexhashsize = 4 * mesh->max_vertices;
4570 mesh->num_vertexhashsize &= ~(mesh->num_vertexhashsize - 1); // round down to pow2
4571 mesh->data_vertexhash = (int *)Mem_Realloc(mod->mempool, mesh->data_vertexhash, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
4572 memset(mesh->data_vertexhash, -1, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
4573 mask = mod->surfmesh.num_vertexhashsize - 1;
4574 // no need to hash the vertices for the entire model, the latest surface will suffice.
4575 for (vnum = surf ? surf->num_firstvertex : 0; vnum < mesh->num_vertices; vnum++)
4576 {
4577 // this uses prime numbers intentionally for computing the hash
4578 hashindex = (unsigned int)(mesh->data_vertex3f[vnum * 3 + 0] * 2003 + mesh->data_vertex3f[vnum * 3 + 1] * 4001 + mesh->data_vertex3f[vnum * 3 + 2] * 7919 + mesh->data_normal3f[vnum * 3 + 0] * 4097 + mesh->data_normal3f[vnum * 3 + 1] * 257 + mesh->data_normal3f[vnum * 3 + 2] * 17) & mask;
4579 for (h = hashindex; mesh->data_vertexhash[h] >= 0; h = (h + 1) & mask)
4580 ; // just iterate until we find the terminator
4581 mesh->data_vertexhash[h] = vnum;
4582 }
4583 }
4584 mask = mod->surfmesh.num_vertexhashsize - 1;
4585 // this uses prime numbers intentionally for computing the hash
4586 hashindex = (unsigned int)(x * 2003 + y * 4001 + z * 7919 + nx * 4097 + ny * 257 + nz * 17) & mask;
4587 // when possible find an identical vertex within the same surface and return it
4588 for(h = hashindex;(vnum = mesh->data_vertexhash[h]) >= 0;h = (h + 1) & mask)
4589 {
4590 if (vnum >= surf->num_firstvertex
4591 && mesh->data_vertex3f[vnum * 3 + 0] == x && mesh->data_vertex3f[vnum * 3 + 1] == y && mesh->data_vertex3f[vnum * 3 + 2] == z
4592 && mesh->data_normal3f[vnum * 3 + 0] == nx && mesh->data_normal3f[vnum * 3 + 1] == ny && mesh->data_normal3f[vnum * 3 + 2] == nz
4593 && mesh->data_texcoordtexture2f[vnum * 2 + 0] == s && mesh->data_texcoordtexture2f[vnum * 2 + 1] == t
4594 && mesh->data_texcoordlightmap2f[vnum * 2 + 0] == u && mesh->data_texcoordlightmap2f[vnum * 2 + 1] == v
4595 && mesh->data_lightmapcolor4f[vnum * 4 + 0] == r && mesh->data_lightmapcolor4f[vnum * 4 + 1] == g && mesh->data_lightmapcolor4f[vnum * 4 + 2] == b && mesh->data_lightmapcolor4f[vnum * 4 + 3] == a)
4596 return vnum;
4597 }
4598 // add the new vertex
4599 vnum = mesh->num_vertices++;
4600 if (surf->num_vertices > 0)
4601 {
4602 if (surf->mins[0] > x) surf->mins[0] = x;
4603 if (surf->mins[1] > y) surf->mins[1] = y;
4604 if (surf->mins[2] > z) surf->mins[2] = z;
4605 if (surf->maxs[0] < x) surf->maxs[0] = x;
4606 if (surf->maxs[1] < y) surf->maxs[1] = y;
4607 if (surf->maxs[2] < z) surf->maxs[2] = z;
4608 }
4609 else
4610 {
4611 VectorSet(surf->mins, x, y, z);
4612 VectorSet(surf->maxs, x, y, z);
4613 }
4614 surf->num_vertices = mesh->num_vertices - surf->num_firstvertex;
4615 mesh->data_vertexhash[h] = vnum;
4616 mesh->data_vertex3f[vnum * 3 + 0] = x;
4617 mesh->data_vertex3f[vnum * 3 + 1] = y;
4618 mesh->data_vertex3f[vnum * 3 + 2] = z;
4619 mesh->data_normal3f[vnum * 3 + 0] = nx;
4620 mesh->data_normal3f[vnum * 3 + 1] = ny;
4621 mesh->data_normal3f[vnum * 3 + 2] = nz;
4622 mesh->data_texcoordtexture2f[vnum * 2 + 0] = s;
4623 mesh->data_texcoordtexture2f[vnum * 2 + 1] = t;
4624 mesh->data_texcoordlightmap2f[vnum * 2 + 0] = u;
4625 mesh->data_texcoordlightmap2f[vnum * 2 + 1] = v;
4626 mesh->data_lightmapcolor4f[vnum * 4 + 0] = r;
4627 mesh->data_lightmapcolor4f[vnum * 4 + 1] = g;
4628 mesh->data_lightmapcolor4f[vnum * 4 + 2] = b;
4629 mesh->data_lightmapcolor4f[vnum * 4 + 3] = a;
4630 return vnum;
4631}
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition glquake.h:609
dp_FragColor g
int * data_vertexhash
int num_vertexhashsize

References a, b, surfmesh_t::data_lightmapcolor4f, surfmesh_t::data_normal3f, surfmesh_t::data_svector3f, surfmesh_t::data_texcoordlightmap2f, surfmesh_t::data_texcoordtexture2f, surfmesh_t::data_tvector3f, surfmesh_t::data_vertex3f, surfmesh_t::data_vertexhash, g, int(), mask, max, surfmesh_t::max_vertices, msurface_t::maxs, Mem_Realloc, msurface_t::mins, mod(), msurface_t::num_firstvertex, surfmesh_t::num_vertexhashsize, msurface_t::num_vertices, surfmesh_t::num_vertices, r, v, VectorSet, x, y, and z.

Referenced by CL_Beam_AddQuad(), DrawQ_Line(), DrawQ_Pic(), DrawQ_RotPic(), DrawQ_String_Scale(), DrawQ_SuperPic(), R_DebugLine(), and VM_CL_R_PolygonEnd().

◆ Mod_Mesh_MakeSortedSurfaces()

static void Mod_Mesh_MakeSortedSurfaces ( model_t * mod)
static

Definition at line 4652 of file model_shared.c.

4653{
4654 int i, j;
4655 texture_t *tex;
4656
4657 // build the sorted surfaces list properly to reduce material setup
4658 // this is easy because we're just sorting on texture and don't care about the order of textures
4659 mod->submodelsurfaces_start = 0;
4660 mod->submodelsurfaces_end = 0;
4661 for (i = 0; i < mod->num_surfaces; i++)
4662 mod->data_surfaces[i].included = false;
4663 for (i = 0; i < mod->num_surfaces; i++)
4664 {
4665 if (mod->data_surfaces[i].included)
4666 continue;
4667 tex = mod->data_surfaces[i].texture;
4668 // j = i is intentional
4669 for (j = i; j < mod->num_surfaces; j++)
4670 {
4671 if (!mod->data_surfaces[j].included && mod->data_surfaces[j].texture == tex)
4672 {
4673 mod->data_surfaces[j].included = 1;
4674 mod->modelsurfaces_sorted[mod->submodelsurfaces_end++] = j;
4675 }
4676 }
4677 }
4678}

References i, and mod().

Referenced by Mod_Mesh_Finalize().

◆ Mod_Mesh_Reset()

void Mod_Mesh_Reset ( model_t * mod)

Definition at line 4465 of file model_shared.c.

4466{
4467 mod->num_surfaces = 0;
4468 mod->surfmesh.num_vertices = 0;
4469 mod->surfmesh.num_triangles = 0;
4470 if (mod->surfmesh.data_vertexhash) // UBSan: memset arg 1 isn't allowed to be null, but sometimes this is NULL.
4471 memset(mod->surfmesh.data_vertexhash, -1, mod->surfmesh.num_vertexhashsize * sizeof(*mod->surfmesh.data_vertexhash));
4472 mod->DrawSky = NULL; // will be set if a texture needs it
4473 mod->DrawAddWaterPlanes = NULL; // will be set if a texture needs it
4474}

References mod(), and NULL.

Referenced by CL_MeshEntities_Scene_Clear(), and DrawQ_FlushUI().

◆ Mod_Mesh_UploadDynamicBuffers()

static void Mod_Mesh_UploadDynamicBuffers ( model_t * mod)
static

Definition at line 4760 of file model_shared.c.

4761{
4762 mod->surfmesh.data_element3s_indexbuffer = mod->surfmesh.data_element3s ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(short[3]), mod->surfmesh.data_element3s, R_BUFFERDATA_INDEX16, &mod->surfmesh.data_element3s_bufferoffset) : NULL;
4763 mod->surfmesh.data_element3i_indexbuffer = mod->surfmesh.data_element3i ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(int[3]), mod->surfmesh.data_element3i, R_BUFFERDATA_INDEX32, &mod->surfmesh.data_element3i_bufferoffset) : NULL;
4764 mod->surfmesh.data_vertex3f_vertexbuffer = mod->surfmesh.data_vertex3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_vertex3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_vertex3f_bufferoffset) : NULL;
4765 mod->surfmesh.data_svector3f_vertexbuffer = mod->surfmesh.data_svector3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_svector3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_svector3f_bufferoffset) : NULL;
4766 mod->surfmesh.data_tvector3f_vertexbuffer = mod->surfmesh.data_tvector3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_tvector3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_tvector3f_bufferoffset) : NULL;
4767 mod->surfmesh.data_normal3f_vertexbuffer = mod->surfmesh.data_normal3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_normal3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_normal3f_bufferoffset) : NULL;
4768 mod->surfmesh.data_texcoordtexture2f_vertexbuffer = mod->surfmesh.data_texcoordtexture2f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[2]), mod->surfmesh.data_texcoordtexture2f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_texcoordtexture2f_bufferoffset) : NULL;
4769 mod->surfmesh.data_texcoordlightmap2f_vertexbuffer = mod->surfmesh.data_texcoordlightmap2f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[2]), mod->surfmesh.data_texcoordlightmap2f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_texcoordlightmap2f_bufferoffset) : NULL;
4770 mod->surfmesh.data_lightmapcolor4f_vertexbuffer = mod->surfmesh.data_lightmapcolor4f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[4]), mod->surfmesh.data_lightmapcolor4f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_lightmapcolor4f_bufferoffset) : NULL;
4771 mod->surfmesh.data_skeletalindex4ub_vertexbuffer = mod->surfmesh.data_skeletalindex4ub ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(unsigned char[4]), mod->surfmesh.data_skeletalindex4ub, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_skeletalindex4ub_bufferoffset) : NULL;
4772 mod->surfmesh.data_skeletalweight4ub_vertexbuffer = mod->surfmesh.data_skeletalweight4ub ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(unsigned char[4]), mod->surfmesh.data_skeletalweight4ub, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_skeletalweight4ub_bufferoffset) : NULL;
4773}
r_meshbuffer_t * R_BufferData_Store(size_t datasize, const void *data, r_bufferdata_type_t type, int *returnbufferoffset)
request space in a vertex/index/uniform buffer for the chosen data, returns the buffer pointer and of...
Definition gl_rmain.c:3707
@ R_BUFFERDATA_VERTEX
Definition render.h:525
@ R_BUFFERDATA_INDEX32
index buffer - 16bit (because D3D cares)
Definition render.h:527
@ R_BUFFERDATA_INDEX16
vertex buffer
Definition render.h:526

References mod(), NULL, R_BUFFERDATA_INDEX16, R_BUFFERDATA_INDEX32, R_BufferData_Store(), and R_BUFFERDATA_VERTEX.

Referenced by Mod_Mesh_Finalize().

◆ Mod_Mesh_Validate()

void Mod_Mesh_Validate ( model_t * mod)

Definition at line 4736 of file model_shared.c.

4737{
4738 int i;
4739 qbool warned = false;
4740 for (i = 0; i < mod->num_surfaces; i++)
4741 {
4742 msurface_t *surf = mod->data_surfaces + i;
4743 int *e = mod->surfmesh.data_element3i + surf->num_firsttriangle * 3;
4744 int first = surf->num_firstvertex;
4745 int end = surf->num_firstvertex + surf->num_vertices;
4746 int j;
4747 for (j = 0;j < surf->num_triangles * 3;j++)
4748 {
4749 if (e[j] < first || e[j] >= end)
4750 {
4751 if (!warned)
4752 Con_DPrintf(CON_WARN "Mod_Mesh_Validate: detected corrupt surface - debug me!\n");
4753 warned = true;
4754 e[j] = first;
4755 }
4756 }
4757 }
4758}

References Con_DPrintf(), CON_WARN, first, i, mod(), msurface_t::num_firsttriangle, msurface_t::num_firstvertex, msurface_t::num_triangles, and msurface_t::num_vertices.

Referenced by Mod_Mesh_Finalize().

◆ mod_newmap()

static void mod_newmap ( void )
static

Definition at line 122 of file model_shared.c.

123{
124 msurface_t *surface;
125 int i, j, k, l, surfacenum, ssize, tsize;
126 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
127 model_t *mod;
128
129 for (i = 0;i < nummodels;i++)
130 {
131 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool)
132 {
133 for (j = 0;j < mod->num_textures && mod->data_textures;j++)
134 {
135 // note that materialshaderpass and backgroundshaderpass point to shaderpasses[] and so do the pre/post shader ranges, so this catches all of them...
136 for (l = 0; l < Q3SHADER_MAXLAYERS; l++)
137 if (mod->data_textures[j].shaderpasses[l])
138 for (k = 0; k < mod->data_textures[j].shaderpasses[l]->numframes; k++)
139 R_SkinFrame_MarkUsed(mod->data_textures[j].shaderpasses[l]->skinframes[k]);
140 }
141 if (mod->brush.solidskyskinframe)
142 R_SkinFrame_MarkUsed(mod->brush.solidskyskinframe);
143 if (mod->brush.alphaskyskinframe)
144 R_SkinFrame_MarkUsed(mod->brush.alphaskyskinframe);
145 }
146 }
147
149 return;
150
151 for (i = 0;i < nummodels;i++)
152 {
153 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->mempool && mod->data_surfaces)
154 {
155 for (surfacenum = 0, surface = mod->data_surfaces;surfacenum < mod->num_surfaces;surfacenum++, surface++)
156 {
157 if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
158 {
159 ssize = (surface->lightmapinfo->extents[0] >> 4) + 1;
160 tsize = (surface->lightmapinfo->extents[1] >> 4) + 1;
161 memset(surface->lightmapinfo->stainsamples, 255, ssize * tsize * 3);
162 mod->brushq1.lightmapupdateflags[surfacenum] = true;
163 }
164 }
165 }
166 }
167}
cvar_t cl_stainmaps_clearonload
Definition cl_main.c:76
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
Definition gl_rmain.c:2176
unsigned char * stainsamples

References cl_stainmaps_clearonload, msurface_lightmapinfo_t::extents, i, int(), cvar_t::integer, msurface_t::lightmapinfo, Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), models, Q3SHADER_MAXLAYERS, R_SkinFrame_MarkUsed(), and msurface_lightmapinfo_t::stainsamples.

Referenced by Mod_RenderInit().

◆ Mod_Precache_f()

static void Mod_Precache_f ( cmd_state_t * cmd)
static

Definition at line 716 of file model_shared.c.

717{
718 if (Cmd_Argc(cmd) == 2)
719 Mod_ForName(Cmd_Argv(cmd, 1), false, true, Cmd_Argv(cmd, 1)[0] == '*' ? cl.model_name[1] : NULL);
720 else
721 Con_Print("usage: modelprecache <filename>\n");
722}

References cl, cmd(), Cmd_Argc(), Cmd_Argv(), Con_Print(), Mod_ForName(), client_state_t::model_name, and NULL.

Referenced by Mod_Init().

◆ Mod_Print_f()

static void Mod_Print_f ( cmd_state_t * cmd)
static

Definition at line 692 of file model_shared.c.

693{
694 int i;
695 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
696 model_t *mod;
697
698 Con_Print("Loaded models:\n");
699 for (i = 0;i < nummodels;i++)
700 {
701 if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
702 {
703 if (mod->brush.numsubmodels)
704 Con_Printf("%4iK %s (%i submodels)\n", mod->mempool ? (int)((mod->mempool->totalsize + 1023) / 1024) : 0, mod->name, mod->brush.numsubmodels);
705 else
706 Con_Printf("%4iK %s\n", mod->mempool ? (int)((mod->mempool->totalsize + 1023) / 1024) : 0, mod->name);
707 }
708 }
709}

References Con_Print(), Con_Printf(), i, int(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), and models.

Referenced by Mod_Init().

◆ Mod_PurgeUnused()

void Mod_PurgeUnused ( void )

Definition at line 574 of file model_shared.c.

575{
576 int i;
577 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
578 model_t *mod;
579 for (i = 0;i < nummodels;i++)
580 {
581 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && !mod->used)
582 {
585 }
586 }
587}
void Mem_ExpandableArray_FreeRecord(memexpandablearray_t *l, void *record)
Definition zone.c:743

References i, int(), Mem_ExpandableArray_FreeRecord(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), Mod_UnloadModel(), and models.

Referenced by CL_SignonReply(), and SV_SpawnServer().

◆ Mod_Reload()

void Mod_Reload ( void )

Definition at line 661 of file model_shared.c.

662{
663 int i, count;
664 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
665 model_t *mod;
666
667 SCR_PushLoadingScreen("Reloading models", 1.0);
668 count = 0;
669 for (i = 0;i < nummodels;i++)
670 if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
671 ++count;
672 for (i = 0;i < nummodels;i++)
673 if ((mod = (model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used)
674 {
675 SCR_PushLoadingScreen(mod->name, 1.0 / count);
676 Mod_LoadModel(mod, true, true);
678 }
680}

References count, i, int(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), Mod_LoadModel(), models, SCR_PopLoadingScreen(), and SCR_PushLoadingScreen().

◆ Mod_RemoveDegenerateTriangles()

int Mod_RemoveDegenerateTriangles ( int numtriangles,
const int * inelement3i,
int * outelement3i,
const float * vertex3f )

Definition at line 2841 of file model_shared.c.

2842{
2843 int i, outtriangles;
2844 float edgedir1[3], edgedir2[3], temp[3];
2845 // a degenerate triangle is one with no width (thickness, surface area)
2846 // these are characterized by having all 3 points colinear (along a line)
2847 // or having two points identical
2848 // the simplest check is to calculate the triangle's area
2849 for (i = 0, outtriangles = 0;i < numtriangles;i++, inelement3i += 3)
2850 {
2851 // calculate first edge
2852 VectorSubtract(vertex3f + inelement3i[1] * 3, vertex3f + inelement3i[0] * 3, edgedir1);
2853 VectorSubtract(vertex3f + inelement3i[2] * 3, vertex3f + inelement3i[0] * 3, edgedir2);
2854 CrossProduct(edgedir1, edgedir2, temp);
2855 if (VectorLength2(temp) < 0.001f)
2856 continue; // degenerate triangle (no area)
2857 // valid triangle (has area)
2858 VectorCopy(inelement3i, outelement3i);
2859 outelement3i += 3;
2860 outtriangles++;
2861 }
2862 return outtriangles;
2863}

References CrossProduct, i, VectorCopy, VectorLength2, and VectorSubtract.

Referenced by Mod_Q3BSP_LoadFaces().

◆ Mod_RenderInit()

void Mod_RenderInit ( void )

Definition at line 206 of file model_shared.c.

207{
209}
static void mod_newmap(void)
static void mod_start(void)
static void mod_shutdown(void)
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
Definition r_modules.c:25

References mod_newmap(), mod_shutdown(), mod_start(), NULL, and R_RegisterModule().

Referenced by Render_Init().

◆ Mod_SetDrawSkyAndWater()

void Mod_SetDrawSkyAndWater ( model_t * mod)

Sets the mod->DrawSky and mod->DrawAddWaterPlanes pointers conditionally based on whether surfaces in this submodel use these features called specifically by brush model loaders when generating submodels automatically called after model loader returns.

Definition at line 2887 of file model_shared.c.

2888{
2889 int j;
2890 uint64_t basematerialflags = 0;
2891 // by default assume there is no sky or water used in this model
2892 mod->DrawSky = NULL;
2893 mod->DrawAddWaterPlanes = NULL;
2894 // combine all basematerialflags observed in the submodelsurfaces range, then check for special flags
2895 for (j = mod->submodelsurfaces_start; j < mod->submodelsurfaces_end; j++)
2896 if (mod->data_surfaces[j].texture)
2897 basematerialflags |= mod->data_surfaces[j].texture->basematerialflags;
2898 if (basematerialflags & MATERIALFLAG_SKY)
2899 mod->DrawSky = R_Mod_DrawSky;
2901 mod->DrawAddWaterPlanes = R_Mod_DrawAddWaterPlanes;
2902}

References MATERIALFLAG_CAMERA, MATERIALFLAG_REFLECTION, MATERIALFLAG_REFRACTION, MATERIALFLAG_SKY, MATERIALFLAG_WATERSHADER, mod(), NULL, R_Mod_DrawAddWaterPlanes(), and R_Mod_DrawSky().

Referenced by Mod_LoadModel(), Mod_OBJ_Load(), Mod_Q1BSP_Load(), Mod_Q2BSP_Load(), and Mod_Q3BSP_Load().

◆ Mod_ShadowMesh_AddMesh()

void Mod_ShadowMesh_AddMesh ( shadowmesh_t * mesh,
const float * vertex3f,
int numtris,
const int * element3i )

Definition at line 1041 of file model_shared.c.

1042{
1043 int i;
1044
1045 for (i = 0;i < numtris;i++)
1046 {
1047 if ((mesh->numtriangles * 3 + 2) * sizeof(int) + 1 >= Mem_Size(mesh->element3i))
1048 {
1049 // FIXME: we didn't allocate enough space for all the tris, see R_Mod_CompileShadowMap
1050 Con_Print(CON_WARN "Mod_ShadowMesh_AddMesh: insufficient memory allocated!\n");
1051 return;
1052 }
1053 mesh->element3i[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 0]);
1054 mesh->element3i[mesh->numtriangles * 3 + 1] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 1]);
1055 mesh->element3i[mesh->numtriangles * 3 + 2] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 2]);
1056 mesh->numtriangles++;
1057 }
1058
1059 // the triangle calculation can take a while, so let's do a keepalive here
1060 CL_KeepaliveMessage(false);
1061}
void CL_KeepaliveMessage(qbool readmessages)
Definition cl_parse.c:314
int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, const float *vertex3f)
static size_t Mem_Size(void *data)
Returns the current size of an allocation.
Definition zone.h:122

References CL_KeepaliveMessage(), Con_Print(), CON_WARN, shadowmesh_t::element3i, i, Mem_Size(), Mod_ShadowMesh_AddVertex(), and shadowmesh_t::numtriangles.

Referenced by Mod_CreateCollisionMesh(), and R_Shadow_ShadowMapFromList().

◆ Mod_ShadowMesh_AddVertex()

int Mod_ShadowMesh_AddVertex ( shadowmesh_t * mesh,
const float * vertex3f )

Definition at line 1019 of file model_shared.c.

1020{
1021 int hashindex, vnum;
1023 // this uses prime numbers intentionally
1024 hashindex = (unsigned int) (vertex3f[0] * 2003 + vertex3f[1] * 4001 + vertex3f[2] * 7919) % SHADOWMESHVERTEXHASH;
1025 for (hash = mesh->vertexhashtable[hashindex];hash;hash = hash->next)
1026 {
1027 vnum = (hash - mesh->vertexhashentries);
1028 if (mesh->vertex3f[vnum * 3 + 0] == vertex3f[0] && mesh->vertex3f[vnum * 3 + 1] == vertex3f[1] && mesh->vertex3f[vnum * 3 + 2] == vertex3f[2])
1029 return hash - mesh->vertexhashentries;
1030 }
1031 vnum = mesh->numverts++;
1032 hash = mesh->vertexhashentries + vnum;
1033 hash->next = mesh->vertexhashtable[hashindex];
1034 mesh->vertexhashtable[hashindex] = hash;
1035 mesh->vertex3f[vnum * 3 + 0] = vertex3f[0];
1036 mesh->vertex3f[vnum * 3 + 1] = vertex3f[1];
1037 mesh->vertex3f[vnum * 3 + 2] = vertex3f[2];
1038 return vnum;
1039}
#define SHADOWMESHVERTEXHASH
shadowmeshvertexhash_t ** vertexhashtable
float * vertex3f
shadowmeshvertexhash_t * vertexhashentries
struct shadowmeshvertexhash_s * next

References int(), shadowmeshvertexhash_t::next, shadowmesh_t::numverts, SHADOWMESHVERTEXHASH, shadowmesh_t::vertex3f, shadowmesh_t::vertexhashentries, and shadowmesh_t::vertexhashtable.

Referenced by Mod_ShadowMesh_AddMesh().

◆ Mod_ShadowMesh_Alloc()

shadowmesh_t * Mod_ShadowMesh_Alloc ( mempool_t * mempool,
int maxverts,
int maxtriangles )

Definition at line 1000 of file model_shared.c.

1001{
1002 shadowmesh_t *newmesh;
1003 newmesh = (shadowmesh_t *)Mem_Alloc(mempool, sizeof(shadowmesh_t));
1004 newmesh->mempool = mempool;
1005 newmesh->maxverts = maxverts;
1006 newmesh->maxtriangles = maxtriangles;
1007 newmesh->numverts = 0;
1008 newmesh->numtriangles = 0;
1009 memset(newmesh->sideoffsets, 0, sizeof(newmesh->sideoffsets));
1010 memset(newmesh->sidetotals, 0, sizeof(newmesh->sidetotals));
1011
1012 newmesh->vertex3f = (float *)Mem_Alloc(mempool, maxverts * sizeof(float[3]));
1013 newmesh->element3i = (int *)Mem_Alloc(mempool, maxtriangles * sizeof(int[3]));
1015 newmesh->vertexhashentries = (shadowmeshvertexhash_t *)Mem_Alloc(mempool, maxverts * sizeof(shadowmeshvertexhash_t));
1016 return newmesh;
1017}
int sidetotals[6]
struct mempool_s * mempool
int sideoffsets[6]

References shadowmesh_t::element3i, shadowmesh_t::maxtriangles, shadowmesh_t::maxverts, Mem_Alloc, shadowmesh_t::mempool, shadowmesh_t::numtriangles, shadowmesh_t::numverts, SHADOWMESHVERTEXHASH, shadowmesh_t::sideoffsets, shadowmesh_t::sidetotals, shadowmesh_t::vertex3f, shadowmesh_t::vertexhashentries, and shadowmesh_t::vertexhashtable.

Referenced by Mod_ShadowMesh_Begin().

◆ Mod_ShadowMesh_Begin()

shadowmesh_t * Mod_ShadowMesh_Begin ( mempool_t * mempool,
int maxverts,
int maxtriangles )

Definition at line 1063 of file model_shared.c.

1064{
1065 // the preparation before shadow mesh initialization can take a while, so let's do a keepalive here
1066 CL_KeepaliveMessage(false);
1067
1068 return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles);
1069}
shadowmesh_t * Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles)

References CL_KeepaliveMessage(), and Mod_ShadowMesh_Alloc().

Referenced by Mod_CreateCollisionMesh(), and R_Mod_CompileShadowMap().

◆ Mod_ShadowMesh_CalcBBox()

void Mod_ShadowMesh_CalcBBox ( shadowmesh_t * mesh,
vec3_t mins,
vec3_t maxs,
vec3_t center,
float * radius )

Definition at line 1136 of file model_shared.c.

1137{
1138 int i;
1139 vec3_t nmins, nmaxs, ncenter, temp;
1140 float nradius2, dist2, *v;
1141 VectorClear(nmins);
1142 VectorClear(nmaxs);
1143 // calculate bbox
1144 VectorCopy(mesh->vertex3f, nmins);
1145 VectorCopy(mesh->vertex3f, nmaxs);
1146 for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
1147 {
1148 if (nmins[0] > v[0]) { nmins[0] = v[0]; } if (nmaxs[0] < v[0]) { nmaxs[0] = v[0]; }
1149 if (nmins[1] > v[1]) { nmins[1] = v[1]; } if (nmaxs[1] < v[1]) { nmaxs[1] = v[1]; }
1150 if (nmins[2] > v[2]) { nmins[2] = v[2]; } if (nmaxs[2] < v[2]) { nmaxs[2] = v[2]; }
1151 }
1152 // calculate center and radius
1153 ncenter[0] = (nmins[0] + nmaxs[0]) * 0.5f;
1154 ncenter[1] = (nmins[1] + nmaxs[1]) * 0.5f;
1155 ncenter[2] = (nmins[2] + nmaxs[2]) * 0.5f;
1156 nradius2 = 0;
1157 for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
1158 {
1159 VectorSubtract(v, ncenter, temp);
1160 dist2 = DotProduct(temp, temp);
1161 if (nradius2 < dist2)
1162 nradius2 = dist2;
1163 }
1164 // return data
1165 if (mins)
1166 VectorCopy(nmins, mins);
1167 if (maxs)
1168 VectorCopy(nmaxs, maxs);
1169 if (center)
1170 VectorCopy(ncenter, center);
1171 if (radius)
1172 *radius = sqrt(nradius2);
1173}
vec_t vec3_t[3]
Definition qtypes.h:71

References DotProduct, i, maxs, mins, sqrt(), v, VectorClear, VectorCopy, VectorSubtract, and shadowmesh_t::vertex3f.

◆ Mod_ShadowMesh_CreateVBOs()

static void Mod_ShadowMesh_CreateVBOs ( shadowmesh_t * mesh)
static

Definition at line 1071 of file model_shared.c.

1072{
1073 if (!mesh->numverts)
1074 return;
1075
1076 // make sure we don't crash inside the driver if something went wrong, as it's annoying to debug
1077 Mod_ValidateElements(mesh->element3i, mesh->element3s, mesh->numtriangles, 0, mesh->numverts, __FILE__, __LINE__);
1078
1079 // upload short indices as a buffer
1080 if (mesh->element3s && !mesh->element3s_indexbuffer)
1081 mesh->element3s_indexbuffer = R_Mesh_CreateMeshBuffer(mesh->element3s, mesh->numtriangles * sizeof(short[3]), "shadowmesh", true, false, false, true);
1082
1083 // upload int indices as a buffer
1084 if (mesh->element3i && !mesh->element3i_indexbuffer && !mesh->element3s)
1085 mesh->element3i_indexbuffer = R_Mesh_CreateMeshBuffer(mesh->element3i, mesh->numtriangles * sizeof(int[3]), "shadowmesh", true, false, false, false);
1086
1087 // vertex buffer is several arrays and we put them in the same buffer
1088 //
1089 // is this wise? the texcoordtexture2f array is used with dynamic
1090 // vertex/svector/tvector/normal when rendering animated models, on the
1091 // other hand animated models don't use a lot of vertices anyway...
1092 if (!mesh->vbo_vertexbuffer)
1093 {
1094 mesh->vbooffset_vertex3f = 0;
1095 mesh->vbo_vertexbuffer = R_Mesh_CreateMeshBuffer(mesh->vertex3f, mesh->numverts * sizeof(float[3]), "shadowmesh", false, false, false, false);
1096 }
1097}
qbool Mod_ValidateElements(int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline)
r_meshbuffer_t * element3s_indexbuffer
r_meshbuffer_t * vbo_vertexbuffer
r_meshbuffer_t * element3i_indexbuffer
unsigned short * element3s

References shadowmesh_t::element3i, shadowmesh_t::element3i_indexbuffer, shadowmesh_t::element3s, shadowmesh_t::element3s_indexbuffer, Mod_ValidateElements(), shadowmesh_t::numtriangles, shadowmesh_t::numverts, R_Mesh_CreateMeshBuffer(), shadowmesh_t::vbo_vertexbuffer, shadowmesh_t::vbooffset_vertex3f, and shadowmesh_t::vertex3f.

Referenced by Mod_ShadowMesh_Finish().

◆ Mod_ShadowMesh_Finish()

shadowmesh_t * Mod_ShadowMesh_Finish ( shadowmesh_t * mesh,
qbool createvbo )

Definition at line 1099 of file model_shared.c.

1100{
1101 if (mesh->numverts >= 3 && mesh->numtriangles >= 1)
1102 {
1103 if (mesh->vertexhashentries)
1105 mesh->vertexhashentries = NULL;
1106 if (mesh->vertexhashtable)
1108 mesh->vertexhashtable = NULL;
1109 if (mesh->maxverts > mesh->numverts)
1110 {
1111 mesh->vertex3f = (float *)Mem_Realloc(mesh->mempool, mesh->vertex3f, mesh->numverts * sizeof(float[3]));
1112 mesh->maxverts = mesh->numverts;
1113 }
1114 if (mesh->maxtriangles > mesh->numtriangles)
1115 {
1116 mesh->element3i = (int *)Mem_Realloc(mesh->mempool, mesh->element3i, mesh->numtriangles * sizeof(int[3]));
1117 mesh->maxtriangles = mesh->numtriangles;
1118 }
1119 if (mesh->numverts <= 65536)
1120 {
1121 int i;
1122 mesh->element3s = (unsigned short *)Mem_Alloc(mesh->mempool, mesh->numtriangles * sizeof(unsigned short[3]));
1123 for (i = 0;i < mesh->numtriangles*3;i++)
1124 mesh->element3s[i] = mesh->element3i[i];
1125 }
1126 if (createvbo)
1128 }
1129
1130 // this can take a while, so let's do a keepalive here
1131 CL_KeepaliveMessage(false);
1132
1133 return mesh;
1134}
static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh)

References CL_KeepaliveMessage(), shadowmesh_t::element3i, shadowmesh_t::element3s, i, shadowmesh_t::maxtriangles, shadowmesh_t::maxverts, Mem_Alloc, Mem_Free, Mem_Realloc, shadowmesh_t::mempool, Mod_ShadowMesh_CreateVBOs(), NULL, shadowmesh_t::numtriangles, shadowmesh_t::numverts, shadowmesh_t::vertex3f, shadowmesh_t::vertexhashentries, and shadowmesh_t::vertexhashtable.

Referenced by Mod_CreateCollisionMesh(), and R_Mod_CompileShadowMap().

◆ Mod_ShadowMesh_Free()

◆ mod_shutdown()

static void mod_shutdown ( void )
static

Definition at line 108 of file model_shared.c.

109{
110 int i;
111 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
112 model_t *mod;
113
114 for (i = 0;i < nummodels;i++)
115 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && (mod->loaded || mod->mempool))
117
120}
void Mod_Skeletal_FreeBuffers(void)
Definition model_alias.c:46

References i, int(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), Mod_FreeQ3Shaders(), Mod_Skeletal_FreeBuffers(), Mod_UnloadModel(), and models.

Referenced by Mod_RenderInit().

◆ Mod_SnapVertices()

void Mod_SnapVertices ( int numcomponents,
int numvertices,
float * vertices,
float snap )

Definition at line 2833 of file model_shared.c.

2834{
2835 int i;
2836 double isnap = 1.0 / snap;
2837 for (i = 0;i < numvertices*numcomponents;i++)
2838 vertices[i] = floor(vertices[i]*isnap)*snap;
2839}

References floor(), and i.

Referenced by Mod_Q3BSP_LoadFaces().

◆ mod_start()

static void mod_start ( void )
static

Definition at line 85 of file model_shared.c.

86{
87 int i, count;
88 int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
89 model_t *mod;
90
91 SCR_PushLoadingScreen("Loading models", 1.0);
92 count = 0;
93 for (i = 0;i < nummodels;i++)
94 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
95 if (mod->used)
96 ++count;
97 for (i = 0;i < nummodels;i++)
98 if ((mod = (model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*')
99 if (mod->used)
100 {
101 SCR_PushLoadingScreen(mod->name, 1.0 / count);
102 Mod_LoadModel(mod, true, false);
104 }
106}

References count, i, int(), Mem_ExpandableArray_IndexRange(), Mem_ExpandableArray_RecordAtIndex(), mod(), Mod_LoadModel(), models, SCR_PopLoadingScreen(), and SCR_PushLoadingScreen().

Referenced by Mod_RenderInit().

◆ Mod_UnloadCustomMaterial()

void Mod_UnloadCustomMaterial ( texture_t * texture,
qbool purgeskins )

Removes all shaderpasses from material, and optionally deletes the textures in the skinframes.

Definition at line 2685 of file model_shared.c.

2686{
2687 long unsigned int i, j;
2688 for (i = 0; i < sizeof(texture->shaderpasses) / sizeof(texture->shaderpasses[0]); i++)
2689 {
2690 if (texture->shaderpasses[i])
2691 {
2692 if (purgeskins)
2693 for (j = 0; j < sizeof(texture->shaderpasses[i]->skinframes) / sizeof(skinframe_t *);j++)
2694 if (texture->shaderpasses[i]->skinframes[j] && texture->shaderpasses[i]->skinframes[j]->base)
2695 R_SkinFrame_PurgeSkinFrame(texture->shaderpasses[i]->skinframes[j]);
2696 Mem_Free(texture->shaderpasses[i]);
2697 texture->shaderpasses[i] = NULL;
2698 }
2699 }
2700 texture->materialshaderpass = NULL;
2701 texture->currentskinframe = NULL;
2702 texture->backgroundcurrentskinframe = NULL;
2703}
void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
Definition gl_rmain.c:2184

References i, Mem_Free, NULL, R_SkinFrame_PurgeSkinFrame(), and texture.

◆ Mod_UnloadModel()

void Mod_UnloadModel ( model_t * mod)

Definition at line 211 of file model_shared.c.

212{
213 char name[MAX_QPATH];
214 qbool used;
215 model_t *parentmodel;
216
218 Con_Printf("unloading model %s\n", mod->name);
219
220 dp_strlcpy(name, mod->name, sizeof(name));
221 parentmodel = mod->brush.parentmodel;
222 used = mod->used;
223 if (mod->mempool)
224 {
225 if (mod->surfmesh.data_element3i_indexbuffer && !mod->surfmesh.data_element3i_indexbuffer->isdynamic)
226 R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_element3i_indexbuffer);
227 mod->surfmesh.data_element3i_indexbuffer = NULL;
228 if (mod->surfmesh.data_element3s_indexbuffer && !mod->surfmesh.data_element3s_indexbuffer->isdynamic)
229 R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_element3s_indexbuffer);
230 mod->surfmesh.data_element3s_indexbuffer = NULL;
231 if (mod->surfmesh.data_vertex3f_vertexbuffer && !mod->surfmesh.data_vertex3f_vertexbuffer->isdynamic)
232 R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_vertex3f_vertexbuffer);
233 mod->surfmesh.data_vertex3f_vertexbuffer = NULL;
234 mod->surfmesh.data_svector3f_vertexbuffer = NULL;
235 mod->surfmesh.data_tvector3f_vertexbuffer = NULL;
236 mod->surfmesh.data_normal3f_vertexbuffer = NULL;
237 mod->surfmesh.data_texcoordtexture2f_vertexbuffer = NULL;
238 mod->surfmesh.data_texcoordlightmap2f_vertexbuffer = NULL;
239 mod->surfmesh.data_lightmapcolor4f_vertexbuffer = NULL;
240 mod->surfmesh.data_skeletalindex4ub_vertexbuffer = NULL;
241 mod->surfmesh.data_skeletalweight4ub_vertexbuffer = NULL;
242 }
243 // free textures/memory attached to the model
244 R_FreeTexturePool(&mod->texturepool);
245 Mem_FreePool(&mod->mempool);
246 // clear the struct to make it available
247 memset(mod, 0, sizeof(model_t));
248 // restore the fields we want to preserve
249 dp_strlcpy(mod->name, name, sizeof(mod->name));
250 mod->brush.parentmodel = parentmodel;
251 mod->used = used;
252 mod->loaded = false;
253}
void R_FreeTexturePool(rtexturepool_t **rtexturepool)

References Con_Printf(), developer_loading, dp_strlcpy, cvar_t::integer, MAX_QPATH, Mem_FreePool, mod(), name, NULL, R_FreeTexturePool(), and R_Mesh_DestroyMeshBuffer().

Referenced by Mod_LoadModel(), Mod_Mesh_Destroy(), Mod_PurgeUnused(), and mod_shutdown().

◆ Mod_ValidateElements()

qbool Mod_ValidateElements ( int * element3i,
unsigned short * element3s,
int numtriangles,
int firstvertex,
int numvertices,
const char * filename,
int fileline )

Definition at line 738 of file model_shared.c.

739{
740 int first = firstvertex, last = first + numvertices - 1, numelements = numtriangles * 3;
741 int i;
742 int invalidintcount = 0, invalidintexample = 0;
743 int invalidshortcount = 0, invalidshortexample = 0;
744 int invalidmismatchcount = 0, invalidmismatchexample = 0;
745 if (element3i)
746 {
747 for (i = 0; i < numelements; i++)
748 {
749 if (element3i[i] < first || element3i[i] > last)
750 {
751 invalidintcount++;
752 invalidintexample = i;
753 }
754 }
755 }
756 if (element3s)
757 {
758 for (i = 0; i < numelements; i++)
759 {
760 if (element3s[i] < first || element3s[i] > last)
761 {
762 invalidintcount++;
763 invalidintexample = i;
764 }
765 }
766 }
767 if (element3i && element3s)
768 {
769 for (i = 0; i < numelements; i++)
770 {
771 if (element3s[i] != element3i[i])
772 {
773 invalidmismatchcount++;
774 invalidmismatchexample = i;
775 }
776 }
777 }
778 if (invalidintcount || invalidshortcount || invalidmismatchcount)
779 {
780 Con_Printf("Mod_ValidateElements(%i, %i, %i, %p, %p) called at %s:%d", numelements, first, last, (void *)element3i, (void *)element3s, filename, fileline);
781 Con_Printf(", %i elements are invalid in element3i (example: element3i[%i] == %i)", invalidintcount, invalidintexample, element3i ? element3i[invalidintexample] : 0);
782 Con_Printf(", %i elements are invalid in element3s (example: element3s[%i] == %i)", invalidshortcount, invalidshortexample, element3s ? element3s[invalidshortexample] : 0);
783 Con_Printf(", %i elements mismatch between element3i and element3s (example: element3s[%i] is %i and element3i[%i] is %i)", invalidmismatchcount, invalidmismatchexample, element3s ? element3s[invalidmismatchexample] : 0, invalidmismatchexample, element3i ? element3i[invalidmismatchexample] : 0);
784 Con_Print(". Please debug the engine code - these elements have been modified to not crash, but nothing more.\n");
785
786 // edit the elements to make them safer, as the driver will crash otherwise
787 if (element3i)
788 for (i = 0; i < numelements; i++)
789 if (element3i[i] < first || element3i[i] > last)
790 element3i[i] = first;
791 if (element3s)
792 for (i = 0; i < numelements; i++)
793 if (element3s[i] < first || element3s[i] > last)
794 element3s[i] = first;
795 if (element3i && element3s)
796 for (i = 0; i < numelements; i++)
797 if (element3s[i] != element3i[i])
798 element3s[i] = element3i[i];
799
800 return false;
801 }
802 return true;
803}

References Con_Print(), Con_Printf(), first, and i.

Referenced by Mod_DARKPLACESMODEL_Load(), Mod_IDP0_Load(), Mod_IDP3_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), Mod_ShadowMesh_CreateVBOs(), and Mod_ZYMOTICMODEL_Load().

◆ Mod_VertexRangeFromElements()

void Mod_VertexRangeFromElements ( int numelements,
const int * elements,
int * firstvertexpointer,
int * lastvertexpointer )

Definition at line 2865 of file model_shared.c.

2866{
2867 int i, e;
2868 int firstvertex, lastvertex;
2869 if (numelements > 0 && elements)
2870 {
2871 firstvertex = lastvertex = elements[0];
2872 for (i = 1;i < numelements;i++)
2873 {
2874 e = elements[i];
2875 firstvertex = min(firstvertex, e);
2876 lastvertex = max(lastvertex, e);
2877 }
2878 }
2879 else
2880 firstvertex = lastvertex = 0;
2881 if (firstvertexpointer)
2882 *firstvertexpointer = firstvertex;
2883 if (lastvertexpointer)
2884 *lastvertexpointer = lastvertex;
2885}

References i, max, and min.

◆ Q3Shader_AddToHash()

static void Q3Shader_AddToHash ( shader_t * shader)
static

Definition at line 1408 of file model_shared.c.

1409{
1410 unsigned short hash = CRC_Block_CaseInsensitive ((const unsigned char *)shader->name, strlen (shader->name));
1412 q3shader_hash_entry_t* lastEntry = NULL;
1413 do
1414 {
1415 if (strcasecmp (entry->shader.name, shader->name) == 0)
1416 {
1417 // redeclaration
1418 if(shader->dpshaderkill)
1419 {
1420 // killed shader is a redeclarion? we can safely ignore it
1421 return;
1422 }
1423 else if(entry->shader.dpshaderkill)
1424 {
1425 // replace the old shader!
1426 // this will skip the entry allocating part
1427 // below and just replace the shader
1428 break;
1429 }
1430 else
1431 {
1432 unsigned char *start, *end, *start2;
1433 start = (unsigned char *) (&shader->Q3SHADERINFO_COMPARE_START);
1434 end = ((unsigned char *) (&shader->Q3SHADERINFO_COMPARE_END)) + sizeof(shader->Q3SHADERINFO_COMPARE_END);
1435 start2 = (unsigned char *) (&entry->shader.Q3SHADERINFO_COMPARE_START);
1436 if(memcmp(start, start2, end - start))
1437 Con_DPrintf("Shader '%s' already defined, ignoring mismatching redeclaration\n", shader->name);
1438 else
1439 Con_DPrintf("Shader '%s' already defined\n", shader->name);
1440 return;
1441 }
1442 }
1443 lastEntry = entry;
1444 entry = entry->chain;
1445 }
1446 while (entry != NULL);
1447 if (entry == NULL)
1448 {
1449 if (lastEntry->shader.name[0] != 0)
1450 {
1451 /* Add to chain */
1454
1455 while (lastEntry->chain != NULL) lastEntry = lastEntry->chain;
1456 lastEntry->chain = newEntry;
1457 newEntry->chain = NULL;
1458 lastEntry = newEntry;
1459 }
1460 /* else: head of chain, in hash entry array */
1461 entry = lastEntry;
1462 }
1463 memcpy (&entry->shader, shader, sizeof (shader_t));
1464}

References q3shader_hash_entry_t::chain, Con_DPrintf(), CRC_Block_CaseInsensitive(), shader_t::dpshaderkill, q3shader_data_t::hash, q3shader_data_t::hash_entries, Mem_ExpandableArray_AllocRecord(), shader_t::name, NULL, q3shader_data, Q3SHADER_HASH_SIZE, q3shader_hash_entry_t::shader, and strlen().

Referenced by Mod_LoadQ3Shaders().

◆ R_Model_Null_Draw()

static void R_Model_Null_Draw ( entity_render_t * ent)
static

Definition at line 255 of file model_shared.c.

256{
257 return;
258}

Referenced by Mod_LoadModel().

Variable Documentation

◆ lmaxis

float lmaxis[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}

Definition at line 4121 of file model_shared.c.

4121{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};

Referenced by Mod_GenerateLightmaps_CreateLightmaps().

◆ loader

modloader_t loader[]
static
Initial value:
=
{
{"obj", NULL, 0, Mod_OBJ_Load},
{NULL, "IDPO", 4, Mod_IDP0_Load},
{NULL, "IDP2", 4, Mod_IDP2_Load},
{NULL, "IDP3", 4, Mod_IDP3_Load},
{NULL, "IDSP", 4, Mod_IDSP_Load},
{NULL, "IDS2", 4, Mod_IDS2_Load},
{NULL, "\035", 1, Mod_Q1BSP_Load},
{NULL, "\036", 1, Mod_HLBSP_Load},
{NULL, "BSP2", 4, Mod_BSP2_Load},
{NULL, "2PSB", 4, Mod_2PSB_Load},
{NULL, "IBSP", 4, Mod_IBSP_Load},
{NULL, "VBSP", 4, Mod_VBSP_Load},
{NULL, "ZYMOTICMODEL", 13, Mod_ZYMOTICMODEL_Load},
{NULL, "DARKPLACESMODEL", 16, Mod_DARKPLACESMODEL_Load},
{NULL, "PSKMODEL", 9, Mod_PSKMODEL_Load},
{NULL, "INTERQUAKEMODEL", 16, Mod_INTERQUAKEMODEL_Load},
{"map", NULL, 0, Mod_MAP_Load},
{NULL, NULL, 0, NULL}
}
void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_INTERQUAKEMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_OBJ_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_HLBSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IBSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_2PSB_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_VBSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_BSP2_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend)
void Mod_IDS2_Load(model_t *mod, void *buffer, void *bufferend)

Definition at line 45 of file model_shared.c.

46{
47 {"obj", NULL, 0, Mod_OBJ_Load},
48 {NULL, "IDPO", 4, Mod_IDP0_Load},
49 {NULL, "IDP2", 4, Mod_IDP2_Load},
50 {NULL, "IDP3", 4, Mod_IDP3_Load},
51 {NULL, "IDSP", 4, Mod_IDSP_Load},
52 {NULL, "IDS2", 4, Mod_IDS2_Load},
53 {NULL, "\035", 1, Mod_Q1BSP_Load},
54 {NULL, "\036", 1, Mod_HLBSP_Load},
55 {NULL, "BSP2", 4, Mod_BSP2_Load},
56 {NULL, "2PSB", 4, Mod_2PSB_Load},
57 {NULL, "IBSP", 4, Mod_IBSP_Load},
58 {NULL, "VBSP", 4, Mod_VBSP_Load},
59 {NULL, "ZYMOTICMODEL", 13, Mod_ZYMOTICMODEL_Load},
60 {NULL, "DARKPLACESMODEL", 16, Mod_DARKPLACESMODEL_Load},
61 {NULL, "PSKMODEL", 9, Mod_PSKMODEL_Load},
62 {NULL, "INTERQUAKEMODEL", 16, Mod_INTERQUAKEMODEL_Load},
63 {"map", NULL, 0, Mod_MAP_Load},
64 {NULL, NULL, 0, NULL}
65};

Referenced by Mod_LoadModel().

◆ loadmodel

model_t * loadmodel

Definition at line 42 of file model_shared.c.

Referenced by Mod_Alias_CalculateBoundingBox(), Mod_Alias_MorphMesh_CompileFrames(), Mod_AllocSurfMesh(), Mod_BSP_DecompressVis(), Mod_BSP_FinalizePortals(), Mod_BSP_LoadNodes_RecursiveSetParent(), Mod_BSP_LoadSubmodels(), Mod_BSP_MakePortals(), Mod_BSP_RecursiveNodePortals(), Mod_BuildAliasSkinsFromSkinFiles(), Mod_BuildBaseBonePoses(), Mod_BuildVBOs(), Mod_DARKPLACESMODEL_Load(), Mod_GenerateLightmaps(), Mod_GenerateLightmaps_CreateLightmaps(), Mod_IDP0_Load(), Mod_IDP2_Load(), Mod_IDP3_Load(), Mod_IDS2_Load(), Mod_IDSP_Load(), Mod_INTERQUAKEMODEL_Load(), Mod_LoadModel(), Mod_LoadSkinFiles(), Mod_LoadTextureFromQ3Shader(), Mod_MakeCollisionBIH(), Mod_MakeSortedSurfaces(), Mod_MDL_LoadFrames(), Mod_OBJ_Load(), Mod_PSKMODEL_Load(), Mod_Q1BSP_CheckWaterAlphaSupport(), Mod_Q1BSP_Load(), Mod_Q1BSP_LoadClipnodes(), Mod_Q1BSP_LoadEdges(), Mod_Q1BSP_LoadEntities(), Mod_Q1BSP_LoadFaces(), Mod_Q1BSP_LoadLeaffaces(), Mod_Q1BSP_LoadLeafs(), Mod_Q1BSP_LoadLighting(), Mod_Q1BSP_LoadMapBrushes(), Mod_Q1BSP_LoadNodes(), Mod_Q1BSP_LoadPlanes(), Mod_Q1BSP_LoadSplitSky(), Mod_Q1BSP_LoadSurfedges(), Mod_Q1BSP_LoadTexinfo(), Mod_Q1BSP_LoadTextures(), Mod_Q1BSP_LoadVertexes(), Mod_Q1BSP_LoadVisibility(), Mod_Q1BSP_MakeHull0(), Mod_Q1BSP_ParseWadsFromEntityLump(), Mod_Q2BSP_Load(), Mod_Q2BSP_LoadBrushes(), Mod_Q2BSP_LoadBrushSides(), Mod_Q2BSP_LoadLeafBrushes(), Mod_Q2BSP_LoadLeafs(), Mod_Q2BSP_LoadLighting(), Mod_Q2BSP_LoadNodes(), Mod_Q2BSP_LoadTexinfo(), Mod_Q2BSP_LoadVisibility(), Mod_Q3BSP_Load(), Mod_Q3BSP_LoadBrushes(), Mod_Q3BSP_LoadBrushSides(), Mod_Q3BSP_LoadBrushSides_IG(), Mod_Q3BSP_LoadEffects(), Mod_Q3BSP_LoadEntities(), Mod_Q3BSP_LoadFaces(), Mod_Q3BSP_LoadLeafBrushes(), Mod_Q3BSP_LoadLeafFaces(), Mod_Q3BSP_LoadLeafs(), Mod_Q3BSP_LoadLightGrid(), Mod_Q3BSP_LoadLightmaps(), Mod_Q3BSP_LoadModels(), Mod_Q3BSP_LoadNodes(), Mod_Q3BSP_LoadPlanes(), Mod_Q3BSP_LoadPVS(), Mod_Q3BSP_LoadTextures(), Mod_Q3BSP_LoadTriangles(), Mod_Q3BSP_LoadVertices(), Mod_Q3BSP_RecursiveFindNumLeafs(), Mod_Sprite_SharedSetup(), Mod_SpriteSetupTexture(), Mod_VBSP_LoadEdges(), Mod_VBSP_LoadEntities(), Mod_VBSP_LoadFaces(), Mod_VBSP_LoadPlanes(), Mod_VBSP_LoadSurfedges(), Mod_VBSP_LoadTexinfo(), Mod_VBSP_LoadVertexes(), and Mod_ZYMOTICMODEL_Load().

◆ mod_base

◆ mod_generatelightmaps_borderpixels

cvar_t mod_generatelightmaps_borderpixels = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_borderpixels", "2", "extra space around polygons to prevent sampling artifacts"}

Definition at line 33 of file model_shared.c.

33{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_borderpixels", "2", "extra space around polygons to prevent sampling artifacts"};
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), and Mod_Init().

◆ mod_generatelightmaps_gridradius

cvar_t mod_generatelightmaps_gridradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"}

Definition at line 40 of file model_shared.c.

40{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_generatelightmaps_gridsamples

cvar_t mod_generatelightmaps_gridsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridsamples", "64", "number of shadow tests done per lightgrid cell"}

Definition at line 37 of file model_shared.c.

37{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_gridsamples", "64", "number of shadow tests done per lightgrid cell"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_generatelightmaps_lightinfo

lightmaplight_t* mod_generatelightmaps_lightinfo
static

◆ mod_generatelightmaps_lightmapradius

cvar_t mod_generatelightmaps_lightmapradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapradius", "16", "sampling area around each lightmap pixel"}

Definition at line 38 of file model_shared.c.

38{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapradius", "16", "sampling area around each lightmap pixel"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_generatelightmaps_lightmapsamples

cvar_t mod_generatelightmaps_lightmapsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapsamples", "16", "number of shadow tests done per lightmap pixel"}

Definition at line 35 of file model_shared.c.

35{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_lightmapsamples", "16", "number of shadow tests done per lightmap pixel"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_generatelightmaps_lightmaptriangles

◆ mod_generatelightmaps_numlights

int mod_generatelightmaps_numlights
static

◆ mod_generatelightmaps_numoffsets

◆ mod_generatelightmaps_offsets

◆ mod_generatelightmaps_texturesize

cvar_t mod_generatelightmaps_texturesize = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_texturesize", "1024", "size of lightmap textures"}

Definition at line 34 of file model_shared.c.

34{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_texturesize", "1024", "size of lightmap textures"};

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), and Mod_Init().

◆ mod_generatelightmaps_unitspersample

cvar_t mod_generatelightmaps_unitspersample = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"}

Definition at line 32 of file model_shared.c.

32{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"};

Referenced by Mod_GenerateLightmaps_CreateLightmaps(), and Mod_Init().

◆ mod_generatelightmaps_vertexradius

cvar_t mod_generatelightmaps_vertexradius = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"}

Definition at line 39 of file model_shared.c.

39{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_generatelightmaps_vertexsamples

cvar_t mod_generatelightmaps_vertexsamples = {CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexsamples", "16", "number of shadow tests done per vertex"}

Definition at line 36 of file model_shared.c.

36{CF_CLIENT | CF_ARCHIVE, "mod_generatelightmaps_vertexsamples", "16", "number of shadow tests done per vertex"};

Referenced by Mod_GenerateLightmaps_InitSampleOffsets(), and Mod_Init().

◆ mod_mempool

mempool_t* mod_mempool
static

Definition at line 67 of file model_shared.c.

Referenced by Mod_Init().

◆ mod_obj_orientation

cvar_t mod_obj_orientation
extern

Definition at line 70 of file model_brush.c.

70{CF_CLIENT | CF_SERVER, "mod_obj_orientation", "1", "fix orientation of OBJ models to the usual conventions (if zero, use coordinates as is)"};
#define CF_SERVER
cvar/command that only the server can change/execute
Definition cmd.h:49

Referenced by Mod_BrushInit(), Mod_Decompile_OBJ(), and Mod_OBJ_Load().

◆ mod_q3bsp_nolightmaps

cvar_t mod_q3bsp_nolightmaps
extern

Definition at line 45 of file model_brush.c.

45{CF_CLIENT | CF_ARCHIVE, "mod_q3bsp_nolightmaps", "0", "do not load lightmaps in Q3BSP maps (to save video RAM, but be warned: it looks ugly)"};

Referenced by Mod_BrushInit(), Mod_GenerateLightmaps(), and Mod_Q3BSP_LoadLightmaps().

◆ models

◆ q3shader_data

q3shader_data_t* q3shader_data
static

Definition at line 83 of file model_shared.c.

Referenced by Mod_LoadQ3Shaders(), Mod_LookupQ3Shader(), and Q3Shader_AddToHash().

◆ q3shaders_mem

mempool_t* q3shaders_mem
static

◆ r_mipnormalmaps

cvar_t r_mipnormalmaps = {CF_CLIENT | CF_ARCHIVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"}

Definition at line 31 of file model_shared.c.

31{CF_CLIENT | CF_ARCHIVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"};

Referenced by Mod_Init(), R_SkinFrame_GenerateTexturesFromQPixels(), R_SkinFrame_LoadExternal_SkinFrame(), and R_SkinFrame_LoadInternalBGRA().

◆ r_mipskins

cvar_t r_mipskins = {CF_CLIENT | CF_ARCHIVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"}

Definition at line 30 of file model_shared.c.

30{CF_CLIENT | CF_ARCHIVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"};

Referenced by Mod_BuildAliasSkinsFromSkinFiles(), Mod_IDP0_Load(), Mod_IDP2_Load(), Mod_Init(), and R_LoadQWSkin().

◆ r_shadow_lightattenuationdividebias

cvar_t r_shadow_lightattenuationdividebias
extern

Definition at line 153 of file r_shadow.c.

153{CF_CLIENT, "r_shadow_lightattenuationdividebias", "1", "changes attenuation texture generation"};

Referenced by Mod_GenerateLightmaps_LightPoint(), Mod_GenerateLightmaps_SamplePoint(), R_CompleteLightPoint(), R_Shadow_Init(), R_Shadow_MakeTextures(), R_Shadow_MakeTextures_SamplePoint(), and R_Shadow_RenderMode_Begin().

◆ r_shadow_lightattenuationlinearscale

cvar_t r_shadow_lightattenuationlinearscale
extern

Definition at line 154 of file r_shadow.c.

154{CF_CLIENT, "r_shadow_lightattenuationlinearscale", "2", "changes attenuation texture generation"};

Referenced by Mod_GenerateLightmaps_LightPoint(), Mod_GenerateLightmaps_SamplePoint(), R_CompleteLightPoint(), R_Shadow_Init(), R_Shadow_MakeTextures(), R_Shadow_MakeTextures_SamplePoint(), and R_Shadow_RenderMode_Begin().

◆ vid_opened

qbool vid_opened
extern

Definition at line 2785 of file cl_main.c.

Referenced by Mod_ForName().