Mod_UnloadModel(mod);
Mod_FreeQ3Shaders();
+ Mod_Skeletal_FreeBuffers();
}
static void mod_newmap(void)
static void Mod_Print(void);
static void Mod_Precache (void);
static void Mod_Decompile_f(void);
-static void Mod_BuildVBOs(void);
static void Mod_GenerateLightmaps_f(void);
void Mod_Init (void)
{
Mod_FrameGroupify_ParseGroups(buf, Mod_FrameGroupify_ParseGroups_Store, mod);
}
+void Mod_FindPotentialDeforms(dp_model_t *mod)
+{
+ int i, j;
+ texture_t *texture;
+ mod->wantnormals = false;
+ mod->wanttangents = false;
+ for (i = 0;i < mod->num_textures;i++)
+ {
+ texture = mod->data_textures + i;
+ if (texture->tcgen.tcgen == Q3TCGEN_ENVIRONMENT)
+ mod->wantnormals = true;
+ for (j = 0;j < Q3MAXDEFORMS;j++)
+ {
+ if (texture->deforms[j].deform == Q3DEFORM_AUTOSPRITE)
+ {
+ mod->wanttangents = true;
+ mod->wantnormals = true;
+ break;
+ }
+ if (texture->deforms[j].deform != Q3DEFORM_NONE)
+ mod->wantnormals = true;
+ }
+ }
+}
+
/*
==================
Mod_LoadModel
else Con_Printf("Mod_LoadModel: model \"%s\" is of unknown/unsupported type\n", mod->name);
Mem_Free(buf);
+ Mod_FindPotentialDeforms(mod);
+
buf = FS_LoadFile (va("%s.framegroups", mod->name), tempmempool, false, &filesize);
if(buf)
{
{
if (!vid.support.arb_vertex_buffer_object)
return;
+ if (mesh->vbo)
+ return;
// element buffer is easy because it's just one array
if (mesh->numtriangles)
}
extern cvar_t r_picmipworld;
+extern cvar_t mod_q3shader_default_offsetmapping;
void Mod_LoadQ3Shaders(void)
{
int j;
shader.reflectfactor = 1;
Vector4Set(shader.reflectcolor4f, 1, 1, 1, 1);
shader.r_water_wateralpha = 1;
+ shader.offsetmapping = (mod_q3shader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
+ shader.offsetscale = 1;
shader.specularscalemod = 1;
shader.specularpowermod = 1;
{
if (j < TEXTURE_MAXFRAMES + 4)
{
- strlcpy(parameter[j], com_token, sizeof(parameter[j]));
+ // remap dp_water to dpwater, dp_reflect to dpreflect, etc.
+ if(j == 0 && !strncasecmp(com_token, "dp_", 3))
+ dpsnprintf(parameter[j], sizeof(parameter[j]), "dp%s", &com_token[3]);
+ else
+ strlcpy(parameter[j], com_token, sizeof(parameter[j]));
numparameters = j + 1;
}
if (!COM_ParseToken_QuakeC(&text, true))
{
if (j < TEXTURE_MAXFRAMES + 4)
{
- strlcpy(parameter[j], com_token, sizeof(parameter[j]));
+ // remap dp_water to dpwater, dp_reflect to dpreflect, etc.
+ if(j == 0 && !strncasecmp(com_token, "dp_", 3))
+ dpsnprintf(parameter[j], sizeof(parameter[j]), "dp%s", &com_token[3]);
+ else
+ strlcpy(parameter[j], com_token, sizeof(parameter[j]));
numparameters = j + 1;
}
if (!COM_ParseToken_QuakeC(&text, true))
shader.dpshadow = true;
else if (!strcasecmp(parameter[0], "dpnoshadow"))
shader.dpnoshadow = true;
+ else if (!strcasecmp(parameter[0], "dpreflectcube"))
+ strlcpy(shader.dpreflectcube, parameter[1], sizeof(shader.dpreflectcube));
+ else if (!strcasecmp(parameter[0], "dpmeshcollisions"))
+ shader.dpmeshcollisions = true;
else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
{
// some q3 skies don't have the sky parm set
shader.textureflags |= Q3TEXTUREFLAG_NOPICMIP;
else if (!strcasecmp(parameter[0], "polygonoffset"))
shader.textureflags |= Q3TEXTUREFLAG_POLYGONOFFSET;
- else if (!strcasecmp(parameter[0], "dp_refract") && numparameters >= 5)
+ else if (!strcasecmp(parameter[0], "dprefract") && numparameters >= 5)
{
shader.textureflags |= Q3TEXTUREFLAG_REFRACTION;
shader.refractfactor = atof(parameter[1]);
Vector4Set(shader.refractcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), 1);
}
- else if (!strcasecmp(parameter[0], "dp_reflect") && numparameters >= 6)
+ else if (!strcasecmp(parameter[0], "dpreflect") && numparameters >= 6)
{
shader.textureflags |= Q3TEXTUREFLAG_REFLECTION;
shader.reflectfactor = atof(parameter[1]);
Vector4Set(shader.reflectcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), atof(parameter[5]));
}
- else if (!strcasecmp(parameter[0], "dp_water") && numparameters >= 12)
+ else if (!strcasecmp(parameter[0], "dpwater") && numparameters >= 12)
{
shader.textureflags |= Q3TEXTUREFLAG_WATERSHADER;
shader.reflectmin = atof(parameter[1]);
Vector4Set(shader.reflectcolor4f, atof(parameter[8]), atof(parameter[9]), atof(parameter[10]), 1);
shader.r_water_wateralpha = atof(parameter[11]);
}
- else if (!strcasecmp(parameter[0], "dp_glossintensitymod") && numparameters >= 2)
+ else if (!strcasecmp(parameter[0], "dpglossintensitymod") && numparameters >= 2)
{
shader.specularscalemod = atof(parameter[1]);
}
- else if (!strcasecmp(parameter[0], "dp_glossexponentmod") && numparameters >= 2)
+ else if (!strcasecmp(parameter[0], "dpglossexponentmod") && numparameters >= 2)
{
shader.specularpowermod = atof(parameter[1]);
}
+ else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 3)
+ {
+ if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "off"))
+ shader.offsetmapping = OFFSETMAPPING_OFF;
+ else if (!strcasecmp(parameter[1], "default"))
+ shader.offsetmapping = OFFSETMAPPING_DEFAULT;
+ else if (!strcasecmp(parameter[1], "linear"))
+ shader.offsetmapping = OFFSETMAPPING_LINEAR;
+ else if (!strcasecmp(parameter[1], "relief"))
+ shader.offsetmapping = OFFSETMAPPING_RELIEF;
+ shader.offsetscale = atof(parameter[2]);
+ }
else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
{
int i, deformindex;
texflagsmask &= ~TEXF_PICMIP;
if(!(defaulttexflags & TEXF_COMPRESS))
texflagsmask &= ~TEXF_COMPRESS;
- texture->specularscalemod = 1; // unless later loaded from the shader
- texture->specularpowermod = 1; // unless later loaded from the shader
+ // unless later loaded from the shader
+ texture->offsetmapping = (mod_q3shader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
+ texture->offsetscale = 1;
+ texture->specularscalemod = 1;
+ texture->specularpowermod = 1;
// WHEN ADDING DEFAULTS HERE, REMEMBER TO SYNC TO SHADER LOADING ABOVE
// HERE, AND Q1BSP LOADING
// JUST GREP FOR "specularscalemod = 1".
texture->reflectfactor = shader->reflectfactor;
Vector4Copy(shader->reflectcolor4f, texture->reflectcolor4f);
texture->r_water_wateralpha = shader->r_water_wateralpha;
+ texture->offsetmapping = shader->offsetmapping;
+ texture->offsetscale = shader->offsetscale;
texture->specularscalemod = shader->specularscalemod;
texture->specularpowermod = shader->specularpowermod;
+ if (shader->dpreflectcube[0])
+ texture->reflectcubetexture = R_GetCubemap(shader->dpreflectcube);
+
+ // set up default supercontents (on q3bsp this is overridden by the q3bsp loader)
+ texture->supercontents = SUPERCONTENTS_SOLID | SUPERCONTENTS_OPAQUE;
+ if (shader->surfaceparms & Q3SURFACEPARM_LAVA ) texture->supercontents = SUPERCONTENTS_LAVA ;
+ if (shader->surfaceparms & Q3SURFACEPARM_SLIME ) texture->supercontents = SUPERCONTENTS_SLIME ;
+ if (shader->surfaceparms & Q3SURFACEPARM_WATER ) texture->supercontents = SUPERCONTENTS_WATER ;
+ if (shader->surfaceparms & Q3SURFACEPARM_NONSOLID ) texture->supercontents = 0 ;
+ if (shader->surfaceparms & Q3SURFACEPARM_PLAYERCLIP ) texture->supercontents = SUPERCONTENTS_PLAYERCLIP ;
+ if (shader->surfaceparms & Q3SURFACEPARM_BOTCLIP ) texture->supercontents = SUPERCONTENTS_MONSTERCLIP ;
+ if (shader->surfaceparms & Q3SURFACEPARM_SKY ) texture->supercontents = SUPERCONTENTS_SKY ;
+
+ // if (shader->surfaceparms & Q3SURFACEPARM_ALPHASHADOW ) texture->supercontents |= SUPERCONTENTS_ALPHASHADOW ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_AREAPORTAL ) texture->supercontents |= SUPERCONTENTS_AREAPORTAL ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_CLUSTERPORTAL) texture->supercontents |= SUPERCONTENTS_CLUSTERPORTAL;
+ // if (shader->surfaceparms & Q3SURFACEPARM_DETAIL ) texture->supercontents |= SUPERCONTENTS_DETAIL ;
+ if (shader->surfaceparms & Q3SURFACEPARM_DONOTENTER ) texture->supercontents |= SUPERCONTENTS_DONOTENTER ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_FOG ) texture->supercontents |= SUPERCONTENTS_FOG ;
+ if (shader->surfaceparms & Q3SURFACEPARM_LAVA ) texture->supercontents |= SUPERCONTENTS_LAVA ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_LIGHTFILTER ) texture->supercontents |= SUPERCONTENTS_LIGHTFILTER ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_METALSTEPS ) texture->supercontents |= SUPERCONTENTS_METALSTEPS ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NODAMAGE ) texture->supercontents |= SUPERCONTENTS_NODAMAGE ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NODLIGHT ) texture->supercontents |= SUPERCONTENTS_NODLIGHT ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NODRAW ) texture->supercontents |= SUPERCONTENTS_NODRAW ;
+ if (shader->surfaceparms & Q3SURFACEPARM_NODROP ) texture->supercontents |= SUPERCONTENTS_NODROP ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NOIMPACT ) texture->supercontents |= SUPERCONTENTS_NOIMPACT ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NOLIGHTMAP ) texture->supercontents |= SUPERCONTENTS_NOLIGHTMAP ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NOMARKS ) texture->supercontents |= SUPERCONTENTS_NOMARKS ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS ) texture->supercontents |= SUPERCONTENTS_NOMIPMAPS ;
+ if (shader->surfaceparms & Q3SURFACEPARM_NONSOLID ) texture->supercontents &=~SUPERCONTENTS_SOLID ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_ORIGIN ) texture->supercontents |= SUPERCONTENTS_ORIGIN ;
+ if (shader->surfaceparms & Q3SURFACEPARM_PLAYERCLIP ) texture->supercontents |= SUPERCONTENTS_PLAYERCLIP ;
+ if (shader->surfaceparms & Q3SURFACEPARM_SKY ) texture->supercontents |= SUPERCONTENTS_SKY ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_SLICK ) texture->supercontents |= SUPERCONTENTS_SLICK ;
+ if (shader->surfaceparms & Q3SURFACEPARM_SLIME ) texture->supercontents |= SUPERCONTENTS_SLIME ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_STRUCTURAL ) texture->supercontents |= SUPERCONTENTS_STRUCTURAL ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_TRANS ) texture->supercontents |= SUPERCONTENTS_TRANS ;
+ if (shader->surfaceparms & Q3SURFACEPARM_WATER ) texture->supercontents |= SUPERCONTENTS_WATER ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_POINTLIGHT ) texture->supercontents |= SUPERCONTENTS_POINTLIGHT ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_HINT ) texture->supercontents |= SUPERCONTENTS_HINT ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_DUST ) texture->supercontents |= SUPERCONTENTS_DUST ;
+ if (shader->surfaceparms & Q3SURFACEPARM_BOTCLIP ) texture->supercontents |= SUPERCONTENTS_BOTCLIP | SUPERCONTENTS_MONSTERCLIP;
+ // if (shader->surfaceparms & Q3SURFACEPARM_LIGHTGRID ) texture->supercontents |= SUPERCONTENTS_LIGHTGRID ;
+ // if (shader->surfaceparms & Q3SURFACEPARM_ANTIPORTAL ) texture->supercontents |= SUPERCONTENTS_ANTIPORTAL ;
+
+ if (shader->dpmeshcollisions)
+ texture->basematerialflags |= MATERIALFLAG_MESHCOLLISIONS;
}
else if (!strcmp(texture->name, "noshader") || !texture->name[0])
{
if (developer_extra.integer)
Con_DPrintf("^1%s:^7 using fallback noshader material for ^3\"%s\"\n", loadmodel->name, name);
texture->surfaceparms = 0;
+ texture->supercontents = SUPERCONTENTS_SOLID | SUPERCONTENTS_OPAQUE;
}
else if (!strcmp(texture->name, "common/nodraw") || !strcmp(texture->name, "textures/common/nodraw"))
{
Con_DPrintf("^1%s:^7 using fallback nodraw material for ^3\"%s\"\n", loadmodel->name, name);
texture->surfaceparms = 0;
texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
+ texture->supercontents = SUPERCONTENTS_SOLID;
}
else
{
Con_DPrintf("^1%s:^7 No shader found for texture ^3\"%s\"\n", loadmodel->name, texture->name);
texture->surfaceparms = 0;
if (texture->surfaceflags & Q3SURFACEFLAG_NODRAW)
+ {
texture->basematerialflags |= MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
+ texture->supercontents = SUPERCONTENTS_SOLID;
+ }
else if (texture->surfaceflags & Q3SURFACEFLAG_SKY)
+ {
texture->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW;
+ texture->supercontents = SUPERCONTENTS_SKY;
+ }
else
+ {
texture->basematerialflags |= MATERIALFLAG_WALL;
+ texture->supercontents = SUPERCONTENTS_SOLID | SUPERCONTENTS_OPAQUE;
+ }
texture->numskinframes = 1;
if(cls.state == ca_dedicated)
{
Mem_Free(numsurfacesfortexture);
}
-static void Mod_BuildVBOs(void)
+void Mod_BuildVBOs(void)
{
if (gl_paranoid.integer && loadmodel->surfmesh.data_element3s && loadmodel->surfmesh.data_element3i)
{
if (!vid.support.arb_vertex_buffer_object)
return;
+ // only build a vbo if one has not already been created (this is important for brush models which load specially)
+ if (loadmodel->surfmesh.vbo)
+ return;
// element buffer is easy because it's just one array
if (loadmodel->surfmesh.num_triangles)
int poseindex;
int cornerindex;
const int *e;
-#if 0
- const float *pose;
-#endif
size_t l;
size_t outbufferpos = 0;
size_t outbuffermax = 0x100000;
l = dpsnprintf(outbuffer + outbufferpos, outbuffermax - outbufferpos, "time %i\n", poseindex);
if (l > 0)
outbufferpos += l;
- for (transformindex = 0;transformindex < model->num_bones;transformindex++ /*, pose += 12 */)
+ for (transformindex = 0;transformindex < model->num_bones;transformindex++)
{
- float a, b, c;
float angles[3];
float mtest[4][3];
matrix4x4_t posematrix;
if (angles[1] >= 180) angles[1] -= 360;
if (angles[2] >= 180) angles[2] -= 360;
- a = DEG2RAD(angles[ROLL]);
- b = DEG2RAD(angles[PITCH]);
- c = DEG2RAD(angles[YAW]);
-
#if 0
{
+ float a = DEG2RAD(angles[ROLL]);
+ float b = DEG2RAD(angles[PITCH]);
+ float c = DEG2RAD(angles[YAW]);
float cy, sy, cp, sp, cr, sr;
float test[4][3];
// smd matrix construction, for comparing
const float *v = model->surfmesh.data_vertex3f + index * 3;
const float *vn = model->surfmesh.data_normal3f + index * 3;
const float *vt = model->surfmesh.data_texcoordtexture2f + index * 2;
- const int *wi = model->surfmesh.data_vertexweightindex4i + index * 4;
- const float *wf = model->surfmesh.data_vertexweightinfluence4f + index * 4;
- 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], wi[1], wf[1], wi[2], wf[2], wi[3], wf[3]);
- 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], wi[1], wf[1], wi[2], wf[2]);
- 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], wi[1], wf[1]);
- 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]);
+ const int b = model->surfmesh.blends[index];
+ if (b < model->num_bones)
+ 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]);
+ else
+ {
+ const blendweights_t *w = model->surfmesh.data_blendweights + b - model->num_bones;
+ const unsigned char *wi = w->index;
+ const unsigned char *wf = w->influence;
+ 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);
+ 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);
+ 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);
+ 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]);
+ }
if (l > 0)
outbufferpos += l;
}
static int mod_generatelightmaps_numlights;
static lightmaplight_t *mod_generatelightmaps_lightinfo;
+extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
+extern cvar_t r_shadow_lightattenuationdividebias;
+extern cvar_t r_shadow_lightattenuationlinearscale;
+
+static void Mod_GenerateLightmaps_LightPoint(dp_model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
+{
+ int i;
+ int index;
+ int result;
+ float relativepoint[3];
+ float color[3];
+ float dir[3];
+ float dist;
+ float dist2;
+ float intensity;
+ float sample[5*3];
+ float lightorigin[3];
+ float lightradius;
+ float lightradius2;
+ float lightiradius;
+ float lightcolor[3];
+ trace_t trace;
+ for (i = 0;i < 5*3;i++)
+ sample[i] = 0.0f;
+ for (index = 0;;index++)
+ {
+ result = R_Shadow_GetRTLightInfo(index, lightorigin, &lightradius, lightcolor);
+ if (result < 0)
+ break;
+ if (result == 0)
+ continue;
+ lightradius2 = lightradius * lightradius;
+ VectorSubtract(lightorigin, pos, relativepoint);
+ dist2 = VectorLength2(relativepoint);
+ if (dist2 >= lightradius2)
+ continue;
+ lightiradius = 1.0f / lightradius;
+ dist = sqrt(dist2) * lightiradius;
+ intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
+ if (intensity <= 0)
+ continue;
+ if (model && model->TraceLine)
+ {
+ model->TraceLine(model, NULL, NULL, &trace, pos, lightorigin, SUPERCONTENTS_VISBLOCKERMASK);
+ if (trace.fraction < 1)
+ continue;
+ }
+ // scale down intensity to add to both ambient and diffuse
+ //intensity *= 0.5f;
+ VectorNormalize(relativepoint);
+ VectorScale(lightcolor, intensity, color);
+ VectorMA(sample , 0.5f , color, sample );
+ VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+ VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+ VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+ // calculate a weighted average light direction as well
+ intensity *= VectorLength(color);
+ VectorMA(sample + 12, intensity, relativepoint, sample + 12);
+ }
+ // calculate the direction we'll use to reduce the sample to a directional light source
+ VectorCopy(sample + 12, dir);
+ //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
+ VectorNormalize(dir);
+ // extract the diffuse color along the chosen direction and scale it
+ diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]);
+ diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]);
+ diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]);
+ // subtract some of diffuse from ambient
+ VectorMA(sample, -0.333f, diffuse, ambient);
+ // store the normalized lightdir
+ VectorCopy(dir, lightdir);
+}
+
static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const dp_model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
{
int surfaceindex;
{
if (!BoxesOverlap(surface->mins, surface->maxs, mins, maxs))
continue;
- if (R_GetCurrentTexture(surface->texture)->currentmaterialflags & MATERIALFLAG_NOSHADOW)
+ if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW)
continue;
for (triangleindex = 0, e = element3i + 3*surface->num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
{
Mem_Free(nodes);
}
-extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
static void Mod_GenerateLightmaps_CreateLights(dp_model_t *model)
{
int index;
return num == -1; // true if empty, false if solid (shadowed)
}
-extern cvar_t r_shadow_lightattenuationdividebias;
-extern cvar_t r_shadow_lightattenuationlinearscale;
static void Mod_GenerateLightmaps_SamplePoint(const float *pos, const float *normal, float *sample, int numoffsets, const float *offsets)
{
int i;
if (model->brushq3.data_lightmaps)
{
for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
- R_FreeTexture(model->brushq3.data_lightmaps[i]);
+ if (model->brushq3.data_lightmaps[i])
+ R_FreeTexture(model->brushq3.data_lightmaps[i]);
Mem_Free(model->brushq3.data_lightmaps);
model->brushq3.data_lightmaps = NULL;
}
if (model->brushq3.data_deluxemaps)
{
for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
- R_FreeTexture(model->brushq3.data_deluxemaps[i]);
+ if (model->brushq3.data_deluxemaps[i])
+ R_FreeTexture(model->brushq3.data_deluxemaps[i]);
Mem_Free(model->brushq3.data_deluxemaps);
model->brushq3.data_deluxemaps = NULL;
}
model->surfmesh.data_tvector3f[outvertexindex*3+2] = oldsurfmesh.data_tvector3f[vertexindex*3+2];
model->surfmesh.data_texcoordtexture2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+0];
model->surfmesh.data_texcoordtexture2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+1];
- model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+0];
- model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+1];
- model->surfmesh.data_lightmapcolor4f[outvertexindex*4+0] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+0];
- model->surfmesh.data_lightmapcolor4f[outvertexindex*4+1] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+1];
- model->surfmesh.data_lightmapcolor4f[outvertexindex*4+2] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+2];
- model->surfmesh.data_lightmapcolor4f[outvertexindex*4+3] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+3];
+ if (oldsurfmesh.data_texcoordlightmap2f)
+ {
+ model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+0];
+ model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+1];
+ }
+ if (oldsurfmesh.data_lightmapcolor4f)
+ {
+ model->surfmesh.data_lightmapcolor4f[outvertexindex*4+0] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+0];
+ model->surfmesh.data_lightmapcolor4f[outvertexindex*4+1] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+1];
+ model->surfmesh.data_lightmapcolor4f[outvertexindex*4+2] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+2];
+ model->surfmesh.data_lightmapcolor4f[outvertexindex*4+3] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+3];
+ }
+ else
+ Vector4Set(model->surfmesh.data_lightmapcolor4f + 4*outvertexindex, 1, 1, 1, 1);
model->surfmesh.data_element3i[surface->num_firsttriangle*3+i] = outvertexindex;
outvertexindex++;
}
float lm_basescalepixels;
int lm_borderpixels;
int lm_texturesize;
- int lm_maxpixels;
+ //int lm_maxpixels;
const int *e;
lightmaptriangle_t *triangle;
unsigned char *lightmappixels;
lm_basescalepixels = 1.0f / max(0.0001f, mod_generatelightmaps_unitspersample.value);
lm_borderpixels = mod_generatelightmaps_borderpixels.integer;
lm_texturesize = bound(lm_borderpixels*2+1, 64, (int)vid.maxtexturesize_2d);
- lm_maxpixels = lm_texturesize-(lm_borderpixels*2+1);
+ //lm_maxpixels = lm_texturesize-(lm_borderpixels*2+1);
Mod_AllocLightmap_Init(&lmstate, lm_texturesize, lm_texturesize);
lightmapnumber = 0;
for (surfaceindex = 0;surfaceindex < model->num_surfaces;surfaceindex++)
lightmapnumber++;
Mod_AllocLightmap_Free(&lmstate);
- // now together lightmap textures
+ // now put triangles together into lightmap textures, and do not allow
+ // triangles of a surface to go into different textures (as that would
+ // require rewriting the surface list)
model->brushq3.deluxemapping_modelspace = true;
model->brushq3.deluxemapping = true;
model->brushq3.num_mergedlightmaps = lightmapnumber;
lightmapindex = mod_generatelightmaps_lightmaptriangles[surface->num_firsttriangle].lightmapindex;
surface->lightmaptexture = model->brushq3.data_lightmaps[lightmapindex];
surface->deluxemaptexture = model->brushq3.data_deluxemaps[lightmapindex];
+ surface->lightmapinfo = NULL;
+ }
+
+ model->brush.LightPoint = Mod_GenerateLightmaps_LightPoint;
+ model->brushq1.lightdata = NULL;
+ model->brushq1.lightmapupdateflags = NULL;
+ model->brushq1.firstrender = false;
+ model->brushq1.num_lightstyles = 0;
+ model->brushq1.data_lightstyleinfo = NULL;
+ for (i = 0;i < model->brush.numsubmodels;i++)
+ {
+ model->brush.submodels[i]->brushq1.lightmapupdateflags = NULL;
+ model->brush.submodels[i]->brushq1.firstrender = false;
+ model->brush.submodels[i]->brushq1.num_lightstyles = 0;
+ model->brush.submodels[i]->brushq1.data_lightstyleinfo = NULL;
}
}