2023-05-08 14:33:37 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
// tr_staticmodels.cpp -- static model rendering
|
|
|
|
|
|
|
|
#include "tr_local.h"
|
|
|
|
#include "tiki.h"
|
|
|
|
|
|
|
|
#define MAX_STATIC_MODELS_SURFS 8192
|
|
|
|
|
|
|
|
int g_nStaticSurfaces;
|
2023-05-09 21:17:01 +02:00
|
|
|
staticSurface_t g_staticSurfaces[MAX_STATIC_MODELS_SURFS];
|
2023-05-08 14:33:37 +02:00
|
|
|
qboolean g_bInfostaticmodels;
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
R_InitStaticModels
|
|
|
|
==============
|
|
|
|
*/
|
2023-05-09 21:17:01 +02:00
|
|
|
void R_InitStaticModels(void) {
|
|
|
|
cStaticModelUnpacked_t* pSM;
|
|
|
|
char szTemp[1024];
|
|
|
|
bool exists;
|
|
|
|
skelBoneCache_t bones[128];
|
|
|
|
float radius;
|
|
|
|
int i, j, k, l;
|
|
|
|
|
|
|
|
g_bInfostaticmodels = qfalse;
|
|
|
|
|
|
|
|
if (tr.overbrightShift)
|
|
|
|
{
|
|
|
|
for (i = 0; i < tr.world->numStaticModelData; i++)
|
|
|
|
{
|
|
|
|
int r, g, b;
|
|
|
|
|
|
|
|
r = (int)((float)tr.world->staticModelData[i * 4] * tr.overbrightMult);
|
|
|
|
g = (int)((float)tr.world->staticModelData[i * 4 + 1] * tr.overbrightMult);
|
|
|
|
b = (int)((float)tr.world->staticModelData[i * 4 + 2] * tr.overbrightMult);
|
|
|
|
|
|
|
|
if ((r | g | b) & 0xFFFFFF00)
|
|
|
|
{
|
|
|
|
float t;
|
|
|
|
unsigned long long rgb;
|
|
|
|
|
|
|
|
rgb = (g + (~((unsigned long long)(r - g) >> 32) & (r - g)) - b);
|
|
|
|
|
|
|
|
t = 255.0 / (float)(b + (~(rgb & 0x00000000FFFFFFFF) & rgb));
|
|
|
|
|
|
|
|
r = (int)((float)r * t);
|
|
|
|
g = (int)((float)g * t);
|
|
|
|
b = (int)((float)b * t);
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.world->staticModelData[i * 4] = r;
|
|
|
|
tr.world->staticModelData[i * 4 + 1] = g;
|
|
|
|
tr.world->staticModelData[i * 4 + 2] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < tr.world->numStaticModels; i++)
|
|
|
|
{
|
|
|
|
vec3_t mins, maxs;
|
|
|
|
|
|
|
|
pSM = &tr.world->staticModels[i];
|
|
|
|
|
|
|
|
pSM->bRendered = qfalse;
|
|
|
|
AngleVectorsLeft(pSM->angles, pSM->axis[0], pSM->axis[1], pSM->axis[2]);
|
|
|
|
|
|
|
|
if (!strnicmp(pSM->model, "models", 6)) {
|
|
|
|
strcpy(szTemp, pSM->model);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(szTemp, "models/%s", pSM->model);
|
|
|
|
}
|
|
|
|
|
|
|
|
FS_CanonicalFilename(szTemp);
|
|
|
|
exists = TIKI_FindTiki(szTemp) != NULL;
|
|
|
|
pSM->tiki = TIKI_RegisterTiki(szTemp);
|
|
|
|
|
|
|
|
if (!pSM->tiki) {
|
|
|
|
ri.Printf(PRINT_WARNING, "^~^~^: Warning: Cannot Load Static Model %s\n", szTemp);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pSM->radius = TIKI_GlobalRadius(pSM->tiki);
|
|
|
|
|
|
|
|
//
|
|
|
|
// register shaders
|
|
|
|
//
|
|
|
|
for (j = 0; j < pSM->tiki->num_surfaces; j++)
|
|
|
|
{
|
|
|
|
dtikisurface_t* surf = &pSM->tiki->surfaces[j];
|
|
|
|
|
|
|
|
for (k = 0; k < surf->numskins; k++)
|
|
|
|
{
|
|
|
|
if (surf->shader[k][0]) {
|
|
|
|
shader_t* sh = R_FindShader(surf->shader[k], -1, !(surf->flags & TIKI_SURF_NOMIPMAPS), !(surf->flags & TIKI_SURF_NOPICMIP), qtrue, qtrue);
|
|
|
|
surf->hShader[k] = sh->index;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
surf->hShader[k] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// prepare the skeleton frame for the static model
|
|
|
|
TIKI_GetSkelAnimFrame(pSM->tiki, bones, &radius, &mins, &maxs);
|
|
|
|
pSM->cull_radius = radius * pSM->tiki->load_scale * pSM->scale;
|
|
|
|
|
|
|
|
// Suggestion:
|
|
|
|
// It would be cool to have animated static model in the future
|
|
|
|
|
|
|
|
if (!exists)
|
|
|
|
{
|
|
|
|
for (j = 0; j < pSM->tiki->numMeshes; j++)
|
|
|
|
{
|
|
|
|
skelHeaderGame_t* skelmodel = TIKI_GetSkel(pSM->tiki->mesh[j]);
|
|
|
|
skelSurfaceGame_t* surf;
|
|
|
|
|
|
|
|
if (!skelmodel) {
|
|
|
|
ri.Printf(PRINT_WARNING, "^~^~^: Warning: Missing mesh in Static Model %s\n", skelmodel->name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
surf = skelmodel->pSurfaces;
|
|
|
|
|
|
|
|
for (k = 0; k < skelmodel->numSurfaces; k++, surf = surf->pNext)
|
|
|
|
{
|
|
|
|
byte* buf;
|
|
|
|
byte* p;
|
|
|
|
skelWeight_t* weight;
|
|
|
|
skeletorVertex_t* vert;
|
|
|
|
|
|
|
|
if (surf->pStaticXyz) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// allocate static vectors
|
|
|
|
p = buf = (byte*)ri.TIKI_Alloc((sizeof(vec4_t) + sizeof(vec4_t) + sizeof(vec2_t) * 2) * surf->numVerts);
|
|
|
|
surf->pStaticXyz = (vec4_t*)p;
|
|
|
|
p += sizeof(vec4_t) * surf->numVerts;
|
|
|
|
surf->pStaticNormal = (vec4_t*)p;
|
|
|
|
p += sizeof(vec4_t) * surf->numVerts;
|
|
|
|
surf->pStaticTexCoords = (vec2_t(*)[2])p;
|
|
|
|
|
|
|
|
vert = surf->pVerts;
|
|
|
|
|
|
|
|
for (l = 0; l < surf->numVerts; l++)
|
|
|
|
{
|
|
|
|
int channel;
|
|
|
|
skelBoneCache_t* bone;
|
|
|
|
|
2023-05-10 20:39:59 +02:00
|
|
|
weight = (skelWeight_t*)((byte*)vert + sizeof(skeletorVertex_t) + vert->numMorphs * sizeof(skeletorMorph_t));
|
2023-05-09 21:17:01 +02:00
|
|
|
|
|
|
|
if (j > 0) {
|
|
|
|
channel = pSM->tiki->m_boneList.GetLocalFromGlobal(skelmodel->pBones[weight->boneIndex].channel);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
channel = weight->boneIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
bone = &bones[channel];
|
|
|
|
|
|
|
|
surf->pStaticXyz[l][0] = ((weight->offset[0] * bone->matrix[0][0]
|
|
|
|
+ weight->offset[1] * bone->matrix[1][0]
|
|
|
|
+ weight->offset[2] * bone->matrix[2][0])
|
|
|
|
+ bone->offset[0]) * weight->boneWeight;
|
|
|
|
surf->pStaticXyz[l][1] = ((weight->offset[0] * bone->matrix[0][1]
|
|
|
|
+ weight->offset[1] * bone->matrix[1][1]
|
|
|
|
+ weight->offset[2] * bone->matrix[2][1])
|
|
|
|
+ bone->offset[1]) * weight->boneWeight;
|
|
|
|
surf->pStaticXyz[l][2] = ((weight->offset[0] * bone->matrix[0][2]
|
|
|
|
+ weight->offset[1] * bone->matrix[1][2]
|
|
|
|
+ weight->offset[2] * bone->matrix[2][2])
|
|
|
|
+ bone->offset[2]) * weight->boneWeight;
|
|
|
|
|
|
|
|
surf->pStaticNormal[l][0] = vert->normal[0] * bone->matrix[0][0]
|
|
|
|
+ vert->normal[1] * bone->matrix[1][0]
|
|
|
|
+ vert->normal[2] * bone->matrix[2][0];
|
|
|
|
surf->pStaticNormal[l][1] = vert->normal[0] * bone->matrix[0][1]
|
|
|
|
+ vert->normal[1] * bone->matrix[1][1]
|
|
|
|
+ vert->normal[2] * bone->matrix[2][1];
|
|
|
|
surf->pStaticNormal[l][2] = vert->normal[0] * bone->matrix[0][2]
|
|
|
|
+ vert->normal[1] * bone->matrix[1][2]
|
|
|
|
+ vert->normal[2] * bone->matrix[2][2];
|
|
|
|
|
|
|
|
surf->pStaticTexCoords[l][0][0] = vert->texCoords[0];
|
|
|
|
surf->pStaticTexCoords[l][0][1] = vert->texCoords[1];
|
|
|
|
surf->pStaticTexCoords[l][1][0] = vert->texCoords[0];
|
|
|
|
surf->pStaticTexCoords[l][1][1] = vert->texCoords[1];
|
|
|
|
|
|
|
|
vert = (skeletorVertex_t*)((byte*)vert + sizeof(skeletorVertex_t) + sizeof(skeletorMorph_t) * vert->numMorphs + sizeof(skelWeight_t) * vert->numWeights);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.refdef.numStaticModels = tr.world->numStaticModels;
|
|
|
|
tr.refdef.staticModels = tr.world->staticModels;
|
|
|
|
tr.refdef.numStaticModelData = tr.world->numStaticModelData;
|
|
|
|
tr.refdef.staticModelData = tr.world->staticModelData;
|
2023-05-08 14:33:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
R_CullStaticModel
|
|
|
|
==============
|
|
|
|
*/
|
2023-05-09 21:17:01 +02:00
|
|
|
static int R_CullStaticModel(dtiki_t* tiki, float fScale, const vec3_t vLocalOrg) {
|
|
|
|
vec3_t bounds[2];
|
|
|
|
int i;
|
|
|
|
int cull;
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
bounds[0][i] = vLocalOrg[i] + tiki->a->mins[i] * fScale;
|
|
|
|
bounds[1][i] = vLocalOrg[i] + tiki->a->maxs[i] * fScale;
|
|
|
|
}
|
|
|
|
|
|
|
|
cull = R_CullLocalBox(bounds);
|
|
|
|
|
|
|
|
// FIXME: r_showcull
|
|
|
|
|
|
|
|
switch (cull)
|
|
|
|
{
|
|
|
|
case CULL_CLIP:
|
|
|
|
tr.pc.c_box_cull_md3_clip++;
|
|
|
|
break;
|
|
|
|
case CULL_IN:
|
|
|
|
tr.pc.c_box_cull_md3_in++;
|
|
|
|
break;
|
|
|
|
case CULL_OUT:
|
|
|
|
tr.pc.c_box_cull_md3_out++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cull;
|
2023-05-08 14:33:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
R_AddStaticModelSurfaces
|
|
|
|
==============
|
|
|
|
*/
|
2023-05-09 21:17:01 +02:00
|
|
|
void R_AddStaticModelSurfaces(void) {
|
|
|
|
cStaticModelUnpacked_t* SM;
|
|
|
|
int i, j;
|
|
|
|
int ofsStaticData;
|
|
|
|
int iRadiusCull;
|
|
|
|
dtiki_t* tiki;
|
|
|
|
float tiki_scale;
|
|
|
|
vec3_t tiki_localorigin;
|
|
|
|
vec3_t tiki_worldorigin;
|
|
|
|
|
|
|
|
if (!tr.world->numStaticModels) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.shiftedIsStatic = 1;
|
|
|
|
|
|
|
|
for (i = 0; i < tr.world->numStaticModels; i++)
|
|
|
|
{
|
|
|
|
SM = &tr.world->staticModels[i];
|
|
|
|
|
|
|
|
//if( SM->visCount != tr.visCounts[ tr.visIndex ] ) {
|
|
|
|
// continue;
|
|
|
|
//}
|
|
|
|
|
|
|
|
tiki = SM->tiki;
|
|
|
|
|
|
|
|
if (!tiki) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.currentEntityNum = i;
|
|
|
|
tr.shiftedEntityNum = i << QSORT_REFENTITYNUM_SHIFT;
|
|
|
|
|
2023-05-11 22:48:13 +02:00
|
|
|
R_RotateForStaticModel(SM, &tr.viewParms, &tr.ori );
|
2023-05-09 21:17:01 +02:00
|
|
|
|
|
|
|
ofsStaticData = 0;
|
|
|
|
|
|
|
|
// get the world position
|
|
|
|
tiki_scale = tiki->load_scale * SM->scale;
|
|
|
|
VectorScale(tiki->load_origin, tiki_scale, tiki_localorigin);
|
|
|
|
R_LocalPointToWorld(tiki_localorigin, tiki_worldorigin);
|
|
|
|
|
|
|
|
iRadiusCull = R_CullPointAndRadius(tiki_worldorigin, SM->cull_radius);
|
|
|
|
|
|
|
|
// FIXME: r_showcull
|
|
|
|
|
|
|
|
if (iRadiusCull != 2 && (iRadiusCull != 1 || R_CullStaticModel(SM->tiki, tiki_scale, tiki_localorigin)))
|
|
|
|
{
|
|
|
|
dtikisurface_t* dsurf;
|
|
|
|
|
|
|
|
// FIXME: Calc LOD
|
|
|
|
if (tr.viewParms.isPortal)
|
|
|
|
{
|
|
|
|
//R_CalcLod( tiki_worldorigin, SM->cull_radius / SM->scale );
|
|
|
|
SM->lodpercentage[1] = SM->cull_radius / SM->scale;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//R_CalcLod( tiki_worldorigin, SM->cull_radius / SM->scale );
|
|
|
|
SM->lodpercentage[0] = SM->cull_radius / SM->scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// draw all meshes
|
|
|
|
//
|
|
|
|
dsurf = tiki->surfaces;
|
|
|
|
for (int mesh = 0; mesh < tiki->numMeshes; mesh++)
|
|
|
|
{
|
|
|
|
skelHeaderGame_t* skelmodel = TIKI_GetSkel(tiki->mesh[mesh]);
|
|
|
|
skelSurfaceGame_t* surface;
|
|
|
|
shader_t* shader;
|
|
|
|
|
|
|
|
if (!skelmodel) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// draw all surfaces
|
|
|
|
//
|
|
|
|
surface = skelmodel->pSurfaces;
|
|
|
|
for (j = 0; j < skelmodel->numSurfaces; j++, surface = surface->pNext, dsurf++)
|
|
|
|
{
|
|
|
|
if (g_nStaticSurfaces >= MAX_STATIC_MODELS_SURFS)
|
|
|
|
{
|
|
|
|
ri.Printf(PRINT_DEVELOPER, "^~^~^ ERROR: MAX_STATIC_MODELS_SURFS exceeded - surface of '%s' skipped\n", tiki->a->name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_staticSurfaces[g_nStaticSurfaces].ident = SF_TIKI_STATIC;
|
|
|
|
g_staticSurfaces[g_nStaticSurfaces].ofsStaticData = ofsStaticData;
|
|
|
|
g_staticSurfaces[g_nStaticSurfaces].surface = surface;
|
|
|
|
g_staticSurfaces[g_nStaticSurfaces].meshNum = mesh;
|
|
|
|
|
|
|
|
shader = tr.shaders[dsurf->hShader[0]];
|
|
|
|
|
|
|
|
SM->bRendered = qtrue;
|
|
|
|
R_AddDrawSurf((surfaceType_t*)&g_staticSurfaces[g_nStaticSurfaces], shader, 0, 0);
|
|
|
|
|
|
|
|
g_nStaticSurfaces++;
|
|
|
|
ofsStaticData += surface->numVerts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.shiftedIsStatic = 0;
|
2023-05-08 14:33:37 +02:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
RB_StaticMesh
|
|
|
|
=============
|
|
|
|
*/
|
2023-05-09 21:17:01 +02:00
|
|
|
void RB_StaticMesh(staticSurface_t* staticSurf) {
|
|
|
|
int i, j;
|
|
|
|
dtiki_t* tiki;
|
|
|
|
skelSurfaceGame_t* surf;
|
|
|
|
int meshNum;
|
|
|
|
skelHeaderGame_t* skelmodel;
|
|
|
|
int render_count;
|
|
|
|
skelIndex_t* collapse_map;
|
|
|
|
skelIndex_t* triangles;
|
|
|
|
int indexes;
|
|
|
|
int baseIndex, baseVertex;
|
|
|
|
short collapse[1000];
|
2023-05-08 14:33:37 +02:00
|
|
|
|
|
|
|
tiki = backEnd.currentStaticModel->tiki;
|
|
|
|
surf = staticSurf->surface;
|
|
|
|
|
|
|
|
assert(surf->pStaticXyz);
|
|
|
|
|
|
|
|
meshNum = staticSurf->meshNum;
|
|
|
|
skelmodel = TIKI_GetSkel(tiki->mesh[meshNum]);
|
|
|
|
|
|
|
|
// FIXME: LOD
|
|
|
|
render_count = surf->numVerts;
|
|
|
|
|
|
|
|
if (tess.numVertexes + render_count >= TIKI_MAX_VERTEXES ||
|
|
|
|
tess.numIndexes + surf->numTriangles >= TIKI_MAX_TRIANGLES * 3) {
|
|
|
|
RB_CHECKOVERFLOW(render_count, surf->numTriangles);
|
|
|
|
}
|
|
|
|
|
|
|
|
collapse_map = surf->pCollapse;
|
|
|
|
triangles = surf->pTriangles;
|
|
|
|
indexes = surf->numTriangles * 3;
|
|
|
|
baseIndex = tess.numIndexes;
|
|
|
|
baseVertex = tess.numVertexes;
|
|
|
|
tess.numVertexes += render_count;
|
|
|
|
|
|
|
|
if (render_count == surf->numVerts)
|
|
|
|
{
|
|
|
|
for (j = 0; j < indexes; j++) {
|
|
|
|
tess.indexes[baseIndex + j] = baseVertex + triangles[j];
|
|
|
|
}
|
|
|
|
tess.numIndexes += indexes;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < render_count; i++) {
|
|
|
|
collapse[i] = i;
|
|
|
|
}
|
|
|
|
for (i = 0; i < surf->numVerts; i++) {
|
|
|
|
collapse[i] = collapse[collapse_map[i]];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < indexes; j += 3)
|
|
|
|
{
|
|
|
|
if (collapse[triangles[j]] == collapse[triangles[j + 1]] ||
|
|
|
|
collapse[triangles[j + 1]] == collapse[triangles[j + 2]] ||
|
|
|
|
collapse[triangles[j + 2]] == collapse[triangles[j]])
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
tess.indexes[baseIndex + j] = baseVertex + collapse[triangles[j]];
|
|
|
|
tess.indexes[baseIndex + j + 1] = baseVertex + collapse[triangles[j + 1]];
|
|
|
|
tess.indexes[baseIndex + j + 2] = baseVertex + collapse[triangles[j + 2]];
|
|
|
|
}
|
|
|
|
tess.numIndexes += j;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < render_count; j++) {
|
|
|
|
Vector4Copy(surf->pStaticXyz[j], tess.xyz[baseVertex + j]);
|
|
|
|
Vector4Copy(surf->pStaticNormal[j], tess.normal[baseVertex + j]);
|
|
|
|
tess.texCoords[baseVertex + j][0][0] = surf->pStaticTexCoords[j][0][0];
|
|
|
|
tess.texCoords[baseVertex + j][0][1] = surf->pStaticTexCoords[j][0][1];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (backEndData[0]->staticModels) {
|
|
|
|
color4ub_t* in = (color4ub_t*)&backEndData[0]->staticModelData[backEnd.currentStaticModel->firstVertexData + staticSurf->ofsStaticData];
|
2023-05-09 21:17:01 +02:00
|
|
|
color4ub_t* out = &tess.vertexColors[baseVertex];
|
2023-05-08 14:33:37 +02:00
|
|
|
|
|
|
|
for (i = 0; i < render_count; i++, in++, out++)
|
|
|
|
{
|
|
|
|
(*out)[0] = (*in)[0];
|
|
|
|
(*out)[1] = (*in)[1];
|
|
|
|
(*out)[2] = (*in)[2];
|
|
|
|
(*out)[3] = 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (i = 0; i < render_count; i++) {
|
|
|
|
tess.vertexColors[baseVertex + i][0] = 1.0;
|
|
|
|
tess.vertexColors[baseVertex + i][1] = 1.0;
|
|
|
|
tess.vertexColors[baseVertex + i][2] = 1.0;
|
|
|
|
tess.vertexColors[baseVertex + i][3] = 1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tess.vertexColorValid = qtrue;
|
|
|
|
}
|