Beispiel #1
0
/**
 * @brief Puts the map data into buffers
 * @sa R_ModAddMapTile
 * @note Shift the verts after the texcoords for diffuse and lightmap are loaded
 * @sa R_ModShiftTile
 * @todo Don't use the buffers from r_state here - they might overflow
 * @todo Decrease MAX_GL_ARRAY_LENGTH to 32768 again when this is fixed
 */
static void R_LoadBspVertexArrays (model_t *mod)
{
	int i, j;
	int vertind, coordind, tangind;
	float *vecShifted;
	float soff, toff, s, t;
	float *point, *sdir, *tdir;
	vec4_t tangent;
	vec3_t binormal;
	mBspSurface_t *surf;
	mBspVertex_t *vert;
	int vertexcount;

	vertind = coordind = tangind = vertexcount = 0;

	for (i = 0, surf = mod->bsp.surfaces; i < mod->bsp.numsurfaces; i++, surf++)
		for (j = 0; j < surf->numedges; j++)
			vertexcount++;

	surf = mod->bsp.surfaces;

	/* allocate the vertex arrays */
	mod->bsp.texcoords = (GLfloat *)Mem_PoolAlloc(vertexcount * 2 * sizeof(GLfloat), vid_modelPool, 0);
	mod->bsp.lmtexcoords = (GLfloat *)Mem_PoolAlloc(vertexcount * 2 * sizeof(GLfloat), vid_modelPool, 0);
	mod->bsp.verts = (GLfloat *)Mem_PoolAlloc(vertexcount * 3 * sizeof(GLfloat), vid_modelPool, 0);
	mod->bsp.normals = (GLfloat *)Mem_PoolAlloc(vertexcount * 3 * sizeof(GLfloat), vid_modelPool, 0);
	mod->bsp.tangents = (GLfloat *)Mem_PoolAlloc(vertexcount * 4 * sizeof(GLfloat), vid_modelPool, 0);

	for (i = 0; i < mod->bsp.numsurfaces; i++, surf++) {
		surf->index = vertind / 3;

		for (j = 0; j < surf->numedges; j++) {
			const float *normal;
			const int index = mod->bsp.surfedges[surf->firstedge + j];

			if (vertind >= MAX_GL_ARRAY_LENGTH * 3)
				Com_Error(ERR_DROP, "R_LoadBspVertexArrays: Exceeded MAX_GL_ARRAY_LENGTH %i", vertind);

			/* vertex */
			if (index > 0) {  /* negative indices to differentiate which end of the edge */
				const mBspEdge_t *edge = &mod->bsp.edges[index];
				vert = &mod->bsp.vertexes[edge->v[0]];
			} else {
				const mBspEdge_t *edge = &mod->bsp.edges[-index];
				vert = &mod->bsp.vertexes[edge->v[1]];
			}

			point = vert->position;

			/* shift it for assembled maps */
			vecShifted = &mod->bsp.verts[vertind];
			/* origin (func_door, func_rotating) bmodels must not have shifted vertices,
			 * they are translated by their entity origin value */
			if (surf->isOriginBrushModel)
				VectorCopy(point, vecShifted);
			else
				VectorAdd(point, shift, vecShifted);

			/* texture directional vectors and offsets */
			sdir = surf->texinfo->uv;
			soff = surf->texinfo->u_offset;

			tdir = surf->texinfo->vv;
			toff = surf->texinfo->v_offset;

			/* texture coordinates */
			s = DotProduct(point, sdir) + soff;
			s /= surf->texinfo->image->width;

			t = DotProduct(point, tdir) + toff;
			t /= surf->texinfo->image->height;

			mod->bsp.texcoords[coordind + 0] = s;
			mod->bsp.texcoords[coordind + 1] = t;

			if (surf->flags & MSURF_LIGHTMAP) {  /* lightmap coordinates */
				s = DotProduct(point, sdir) + soff;
				s -= surf->stmins[0];
				s += surf->light_s * surf->lightmap_scale;
				s += surf->lightmap_scale / 2.0;
				s /= r_lightmaps.size * surf->lightmap_scale;

				t = DotProduct(point, tdir) + toff;
				t -= surf->stmins[1];
				t += surf->light_t * surf->lightmap_scale;
				t += surf->lightmap_scale / 2.0;
				t /= r_lightmaps.size * surf->lightmap_scale;
			}

			mod->bsp.lmtexcoords[coordind + 0] = s;
			mod->bsp.lmtexcoords[coordind + 1] = t;

			/* normal vectors */
			if (surf->texinfo->flags & SURF_PHONG && VectorNotEmpty(vert->normal))
				normal = vert->normal; /* phong shaded */
			else
				normal = surf->normal; /* per plane */

			memcpy(&mod->bsp.normals[vertind], normal, sizeof(vec3_t));

			/* tangent vector */
			TangentVectors(normal, sdir, tdir, tangent, binormal);
			memcpy(&mod->bsp.tangents[tangind], tangent, sizeof(vec4_t));

			vertind += 3;
			coordind += 2;
			tangind += 4;
		}
	}

	if (qglBindBuffer) {
		/* and also the vertex buffer objects */
		qglGenBuffers(1, &mod->bsp.vertex_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.vertex_buffer);
		qglBufferData(GL_ARRAY_BUFFER, vertind * sizeof(GLfloat), mod->bsp.verts, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.texcoord_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.texcoord_buffer);
		qglBufferData(GL_ARRAY_BUFFER, coordind * sizeof(GLfloat), mod->bsp.texcoords, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.lmtexcoord_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.lmtexcoord_buffer);
		qglBufferData(GL_ARRAY_BUFFER, coordind * sizeof(GLfloat), mod->bsp.lmtexcoords, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.normal_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.normal_buffer);
		qglBufferData(GL_ARRAY_BUFFER, vertind * sizeof(GLfloat), mod->bsp.normals, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.tangent_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.tangent_buffer);
		qglBufferData(GL_ARRAY_BUFFER, tangind * sizeof(GLfloat), mod->bsp.tangents, GL_STATIC_DRAW);

		qglBindBuffer(GL_ARRAY_BUFFER, 0);
	}
}
Beispiel #2
0
/*
 * R_LoadBspVertexArrays
 */
static void R_LoadBspVertexArrays(void) {
	int i, j;
	int vert_index, texcoord_index, tangent_index, color_index;
	float soff, toff, s, t;
	float *point, *normal, *sdir, *tdir;
	vec4_t tangent;
	vec3_t bitangent;
	r_bsp_surface_t *surf;
	r_bsp_edge_t *edge;
	r_bsp_vertex_t *vert;

	R_AllocVertexArrays(r_load_model); // allocate the arrays

	vert_index = texcoord_index = tangent_index = 0;
	surf = r_load_model->surfaces;

	for (i = 0; i < r_load_model->num_surfaces; i++, surf++) {

		surf->index = vert_index / 3;

		for (j = 0; j < surf->num_edges; j++) {
			const int index = r_load_model->surface_edges[surf->first_edge + j];

			// vertex
			if (index > 0) { // negative indices to differentiate which end of the edge
				edge = &r_load_model->edges[index];
				vert = &r_load_model->vertexes[edge->v[0]];
			} else {
				edge = &r_load_model->edges[-index];
				vert = &r_load_model->vertexes[edge->v[1]];
			}

			point = vert->position;
			memcpy(&r_load_model->verts[vert_index], point, sizeof(vec3_t));

			// texture directional vectors and offsets
			sdir = surf->texinfo->vecs[0];
			soff = surf->texinfo->vecs[0][3];

			tdir = surf->texinfo->vecs[1];
			toff = surf->texinfo->vecs[1][3];

			// texture coordinates
			s = DotProduct(point, sdir) + soff;
			s /= surf->texinfo->image->width;

			t = DotProduct(point, tdir) + toff;
			t /= surf->texinfo->image->height;

			r_load_model->texcoords[texcoord_index + 0] = s;
			r_load_model->texcoords[texcoord_index + 1] = t;

			if (surf->flags & R_SURF_LIGHTMAP) { // lightmap coordinates
				s = DotProduct(point, sdir) + soff;
				s -= surf->st_mins[0];
				s += surf->light_s * r_load_model->lightmap_scale;
				s += r_load_model->lightmap_scale / 2.0;
				s /= r_lightmaps.size * r_load_model->lightmap_scale;

				t = DotProduct(point, tdir) + toff;
				t -= surf->st_mins[1];
				t += surf->light_t * r_load_model->lightmap_scale;
				t += r_load_model->lightmap_scale / 2.0;
				t /= r_lightmaps.size * r_load_model->lightmap_scale;
			}

			r_load_model->lmtexcoords[texcoord_index + 0] = s;
			r_load_model->lmtexcoords[texcoord_index + 1] = t;

			// normal vector
			if ((surf->texinfo->flags & SURF_PHONG) && !VectorCompare(
					vert->normal, vec3_origin)) // phong shaded
				normal = vert->normal;
			else
				// per-plane
				normal = surf->normal;

			memcpy(&r_load_model->normals[vert_index], normal, sizeof(vec3_t));

			// tangent vector
			TangentVectors(normal, sdir, tdir, tangent, bitangent);
			memcpy(&r_load_model->tangents[tangent_index], tangent, sizeof(vec4_t));

			// accumulate colors
			R_AddBspVertexColor(vert, surf);

			vert_index += 3;
			texcoord_index += 2;
			tangent_index += 4;
		}
	}

	color_index = 0;
	surf = r_load_model->surfaces;

	// now iterate over the verts again, assembling the accumulated colors
	for (i = 0; i < r_load_model->num_surfaces; i++, surf++) {

		for (j = 0; j < surf->num_edges; j++) {
			const int index = r_load_model->surface_edges[surf->first_edge + j];

			// vertex
			if (index > 0) { // negative indices to differentiate which end of the edge
				edge = &r_load_model->edges[index];
				vert = &r_load_model->vertexes[edge->v[0]];
			} else {
				edge = &r_load_model->edges[-index];
				vert = &r_load_model->vertexes[edge->v[1]];
			}

			memcpy(&r_load_model->colors[color_index], vert->color, sizeof(vec4_t));
			color_index += 4;
		}
	}
}
void PolygonGroup::BuildTangentsBinormals(uint32 flagsToAdd)
{
    if (!(vertexFormat & EVF_TANGENT))
    {
        // Dirty hack. Copy pointers of this polygon group 
        //        PolygonGroup * oldGroup = this;
        //        AllocateData(oldGroup->GetVertexFormat() | flagsToAdd, oldGroup->GetVertexCount(), oldGroup->GetIndexCount());
        //        CopyFrom(oldGroup);
        //        SafeRelease(oldGroup);
    }
    
    for (int v = 0; v < vertexCount; ++v)
    {
        //Vector3 * tan0 = (Vector3 *)((uint8 *)normalArray + v * vertexStride);  
        Vector3 * tan1 = (Vector3 *)((uint8 *)tangentArray + v * vertexStride);  
        Vector3 * tan2 = (Vector3 *)((uint8 *)binormalArray + v * vertexStride);  
        //*tan0 = Vector3(0.0f, 0.0f, 0.0f);
        tan1->x = 0;
        tan1->y = 0;
        tan1->z = 0;
        
        tan2->x = 0;
        tan2->y = 0;
        tan2->z = 0;
    }
    
    for (int t = 0; t < triangleCount; ++t)	
    {
        int32 i1 = indexArray[t * 3];
        int32 i2 = indexArray[t * 3 + 1];
        int32 i3 = indexArray[t * 3 + 2];
        
        Vector3 v1 = *(Vector3 *)((uint8 *)vertexArray + i1 * vertexStride);  
        Vector3 v2 = *(Vector3 *)((uint8 *)vertexArray + i2 * vertexStride);  
        Vector3 v3 = *(Vector3 *)((uint8 *)vertexArray + i3 * vertexStride);  
        
        
        // use first texture coordinate
        Vector2 w1 = *(Vector2 *)((uint8 *)textureCoordArray[0] + i1 * vertexStride);  
        Vector2 w2 = *(Vector2 *)((uint8 *)textureCoordArray[0] + i2 * vertexStride);  
        Vector2 w3 = *(Vector2 *)((uint8 *)textureCoordArray[0] + i3 * vertexStride);  
        
        //float32 x1 = v2.x - v1.x;
        //float32 x2 = v3.x - v1.x;
        //float32 y1 = v2.y - v1.y;
        //float32 y2 = v3.y - v1.y;
        //float32 z1 = v2.z - v1.z;
        //float32 z2 = v3.z - v1.z;
        
        //float32 s1 = w2.x - w1.x;
        //float32 s2 = w3.x - w1.x;
        //float32 t1 = w2.y - w1.y;
        //float32 t2 = w3.y - w1.y;
        
        //float r = 1.0F / (s1 * t2 - s2 * t1);
        //Vector3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
        //	(t2 * z1 - t1 * z2) * r);
        //Vector3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
        //	(s1 * z2 - s2 * z1) * r);
        
        
        Vector3 sdir, tdir, norm;
        
        TangentVectors(v1, v2, v3, w1, w2, w3, sdir, tdir, norm);
        
        //Vector3 * nor1 = (Vector3 *)((uint8 *)normalArray + i1 * vertexStride);  
        //Vector3 * nor2 = (Vector3 *)((uint8 *)normalArray + i2 * vertexStride);  
        //Vector3 * nor3 = (Vector3 *)((uint8 *)normalArray + i3 * vertexStride);  
        
        Vector3 * tan1 = (Vector3 *)((uint8 *)tangentArray + i1 * vertexStride);  
        Vector3 * tan2 = (Vector3 *)((uint8 *)tangentArray + i2 * vertexStride);  
        Vector3 * tan3 = (Vector3 *)((uint8 *)tangentArray + i3 * vertexStride);  
        
        Vector3 * tan21 = (Vector3 *)((uint8 *)binormalArray + i1 * vertexStride);  
        Vector3 * tan22 = (Vector3 *)((uint8 *)binormalArray + i2 * vertexStride);  
        Vector3 * tan23 = (Vector3 *)((uint8 *)binormalArray + i3 * vertexStride);  
        
        
        //*nor1 += norm;
        //*nor2 += norm;
        //*nor3 += norm;
        
        *tan1 += sdir;
        *tan2 += sdir;
        *tan3 += sdir;
        
        *tan21 += tdir;
        *tan22 += tdir;
        *tan23 += tdir;
    }
    
    for (int v = 0; v < vertexCount; ++v)
    {
        Vector3 * nres = (Vector3 *)((uint8 *)normalArray + v * vertexStride);  
        Vector3 * tres = (Vector3 *)((uint8 *)tangentArray + v * vertexStride);  
        Vector3 * bres = (Vector3 *)((uint8 *)binormalArray + v * vertexStride);  
        
        *bres = -*bres;
        nres->Normalize();
        tres->Normalize();
        bres->Normalize();
        
        //Vector3 n = *nres;
        //Vector3 t = *tres;
        //Vector3 t2 = *bres;
        
        //*tres = (t - DotProduct(n, t) * n);
        //
        ////tres->x = -tres->x;
        ////tres->y = -tres->y;
        ////tres->z = -tres->z;
        ////nres->x = -nres->x;
        ////nres->y = -nres->y;
        ////nres->z = -nres->z;
        
        
        //tres->Normalize();
        //
        //float32 handedness = (DotProduct(CrossProduct(n, t), t2) < 0.0f) ? (-1.0f) : (1.0f);
        
        //if (vertexFormat & EVF_BINORMAL)
        //{
        //	*bres = CrossProduct(*tres, *nres);
        //	bres->Normalize();
        //}
        ////*bres = -*bres;
        //*tres = -*tres;
        
        /*
         BORODA: Removed unused variable
         Vector3 nrecomp = CrossProduct(*tres, *bres);
        */
        
        // int xt = 0;
        // use this method (get from .. http://www.c4engine.com/code/tangent.html);
        //const Vector3D& n = normal[a];
        //const Vector3D& t = tan1[a];
        //// Gram-Schmidt orthogonalize
        // tangent[a] = (t - n * Dot(n, t)).Normalize();
        //
        // // Calculate handedness
        // tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
    }
}
/**
 * @brief Puts the map data into buffers
 * @sa R_ModAddMapTile
 * @note Shift the verts after the texcoords for diffuse and lightmap are loaded
 * @sa R_ModShiftTile
 * @todo Don't use the buffers from r_state here - they might overflow
 * @todo Decrease MAX_GL_ARRAY_LENGTH to 32768 again when this is fixed
 */
static void R_LoadBspVertexArrays (model_t *mod)
{
	int i, j;
	int vertOfs, texCoordOfs, tangOfs;
	float *vecShifted;
	float soff, toff, s, t;
	float *point, *sdir, *tdir;
	vec4_t tangent;
	vec3_t binormal;
	mBspSurface_t *surf;
	mBspVertex_t *vert;
	int vertexCount, indexCount;

	vertOfs = texCoordOfs = tangOfs = 0;
	vertexCount = indexCount = 0;

	for (i = 0, surf = mod->bsp.surfaces; i < mod->bsp.numsurfaces; i++, surf++) {
		const int numedges = surf->numedges;
		vertexCount += numedges;
		if (numedges > 2) /* no triangles for degenerate polys */
			indexCount += (numedges - 2) * 3;
	}

	surf = mod->bsp.surfaces;

	/* allocate the vertex arrays */
	mod->bsp.texcoords   = Mem_PoolAllocTypeN(GLfloat, vertexCount * 2, vid_modelPool);
	mod->bsp.lmtexcoords = Mem_PoolAllocTypeN(GLfloat, vertexCount * 2, vid_modelPool);
	mod->bsp.verts       = Mem_PoolAllocTypeN(GLfloat, vertexCount * 3, vid_modelPool);
	mod->bsp.normals     = Mem_PoolAllocTypeN(GLfloat, vertexCount * 3, vid_modelPool);
	mod->bsp.tangents    = Mem_PoolAllocTypeN(GLfloat, vertexCount * 4, vid_modelPool);
	mod->bsp.indexes    = Mem_PoolAllocTypeN(GLint, indexCount, vid_modelPool); /* Will be filled at the end of map loading, after building surface lists */

	for (i = 0; i < mod->bsp.numsurfaces; i++, surf++) {
		surf->index = vertOfs / 3;
		surf->firstTriangle = -1; /* Mark as "no triangles generated yet" */

		for (j = 0; j < surf->numedges; j++) {
			const float *normal;
			const int index = mod->bsp.surfedges[surf->firstedge + j];

			/* vertex */
			if (index > 0) {  /* negative indices to differentiate which end of the edge */
				const mBspEdge_t *edge = &mod->bsp.edges[index];
				vert = &mod->bsp.vertexes[edge->v[0]];
			} else {
				const mBspEdge_t *edge = &mod->bsp.edges[-index];
				vert = &mod->bsp.vertexes[edge->v[1]];
			}

			point = vert->position;

			/* shift it for assembled maps */
			vecShifted = &mod->bsp.verts[vertOfs];
			/* origin (func_door, func_rotating) bmodels must not have shifted vertices,
			 * they are translated by their entity origin value */
			if (surf->isOriginBrushModel)
				VectorCopy(point, vecShifted);
			else
				VectorAdd(point, shift, vecShifted);

			/* texture directional vectors and offsets */
			sdir = surf->texinfo->uv;
			soff = surf->texinfo->u_offset;

			tdir = surf->texinfo->vv;
			toff = surf->texinfo->v_offset;

			/* texture coordinates */
			s = DotProduct(point, sdir) + soff;
			s /= surf->texinfo->image->width;

			t = DotProduct(point, tdir) + toff;
			t /= surf->texinfo->image->height;

			mod->bsp.texcoords[texCoordOfs + 0] = s;
			mod->bsp.texcoords[texCoordOfs + 1] = t;

			if (surf->flags & MSURF_LIGHTMAP) {  /* lightmap coordinates */
				s = DotProduct(point, sdir) + soff;
				s -= surf->stmins[0];
				s += surf->light_s * surf->lightmap_scale;
				s += surf->lightmap_scale / 2.0;
				s /= r_lightmaps.size * surf->lightmap_scale;

				t = DotProduct(point, tdir) + toff;
				t -= surf->stmins[1];
				t += surf->light_t * surf->lightmap_scale;
				t += surf->lightmap_scale / 2.0;
				t /= r_lightmaps.size * surf->lightmap_scale;
			}

			mod->bsp.lmtexcoords[texCoordOfs + 0] = s;
			mod->bsp.lmtexcoords[texCoordOfs + 1] = t;

			/* normal vectors */
			if ((surf->texinfo->flags & SURF_PHONG) && VectorNotEmpty(vert->normal))
				normal = vert->normal; /* phong shaded */
			else
				normal = surf->normal; /* per plane */

			memcpy(&mod->bsp.normals[vertOfs], normal, sizeof(vec3_t));

			/* tangent vector */
			TangentVectors(normal, sdir, tdir, tangent, binormal);
			memcpy(&mod->bsp.tangents[tangOfs], tangent, sizeof(vec4_t));

			vertOfs += 3;
			texCoordOfs += 2;
			tangOfs += 4;
		}
	}

	R_ReallocateStateArrays(vertOfs / 3);

	if (qglBindBuffer) {
		/* and also the vertex buffer objects */
		qglGenBuffers(1, &mod->bsp.vertex_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.vertex_buffer);
		qglBufferData(GL_ARRAY_BUFFER, vertOfs * sizeof(GLfloat), mod->bsp.verts, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.texcoord_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.texcoord_buffer);
		qglBufferData(GL_ARRAY_BUFFER, texCoordOfs * sizeof(GLfloat), mod->bsp.texcoords, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.lmtexcoord_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.lmtexcoord_buffer);
		qglBufferData(GL_ARRAY_BUFFER, texCoordOfs * sizeof(GLfloat), mod->bsp.lmtexcoords, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.normal_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.normal_buffer);
		qglBufferData(GL_ARRAY_BUFFER, vertOfs * sizeof(GLfloat), mod->bsp.normals, GL_STATIC_DRAW);

		qglGenBuffers(1, &mod->bsp.tangent_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.tangent_buffer);
		qglBufferData(GL_ARRAY_BUFFER, tangOfs * sizeof(GLfloat), mod->bsp.tangents, GL_STATIC_DRAW);

		qglBindBuffer(GL_ARRAY_BUFFER, 0);
	}
}
Beispiel #5
0
/**
 * @brief
 * @sa FinalLightFace
 */
void BuildFacelights (unsigned int facenum)
{
	dBspSurface_t* face;
	dBspPlane_t* plane;
	dBspTexinfo_t* tex;
	float* center;
	float* sdir, *tdir;
	vec3_t normal, binormal;
	vec4_t tangent;
	lightinfo_t li;
	float scale;
	int i, j, numsamples;
	facelight_t* fl;
	int* headhints;
	const int grid_type = config.soft ? 1 : 0;

	if (facenum >= MAX_MAP_FACES) {
		Com_Printf("MAX_MAP_FACES hit\n");
		return;
	}

	face = &curTile->faces[facenum];
	plane = &curTile->planes[face->planenum];
	tex = &curTile->texinfo[face->texinfo];

	if (tex->surfaceFlags & SURF_WARP)
		return;		/* non-lit texture */

	sdir = tex->vecs[0];
	tdir = tex->vecs[1];

	/* lighting -extra antialiasing */
	if (config.extrasamples)
		numsamples = config.soft ? SOFT_SAMPLES : MAX_SAMPLES;
	else
		numsamples = 1;

	OBJZERO(li);

	scale = 1.0 / numsamples; /* each sample contributes this much */

	li.face = face;
	li.facedist = plane->dist;
	VectorCopy(plane->normal, li.facenormal);
	/* negate the normal and dist */
	if (face->side) {
		VectorNegate(li.facenormal, li.facenormal);
		li.facedist = -li.facedist;
	}

	/* get the origin offset for rotating bmodels */
	VectorCopy(face_offset[facenum], li.modelorg);

	/* calculate lightmap texture mins and maxs */
	CalcLightinfoExtents(&li);

	/* and the lightmap texture vectors */
	CalcLightinfoVectors(&li);

	/* now generate all of the sample points */
	CalcPoints(&li, 0, 0);

	fl = &facelight[config.compile_for_day][facenum];
	fl->numsamples = li.numsurfpt;
	fl->samples    = Mem_AllocTypeN(vec3_t, fl->numsamples);
	fl->directions = Mem_AllocTypeN(vec3_t, fl->numsamples);

	center = face_extents[facenum].center;  /* center of the face */

	/* Also setup the hints.  Each hint is specific to each light source, including sunlight. */
	headhints = Mem_AllocTypeN(int, (numlights[config.compile_for_day] + 1));

	/* calculate light for each sample */
	for (i = 0; i < fl->numsamples; i++) {
		float* const sample    = fl->samples[i];    /* accumulate lighting here */
		float* const direction = fl->directions[i]; /* accumulate direction here */

		if (tex->surfaceFlags & SURF_PHONG)
			/* interpolated normal */
			SampleNormal(&li, li.surfpt[i], normal);
		else
			/* or just plane normal */
			VectorCopy(li.facenormal, normal);

		for (j = 0; j < numsamples; j++) {  /* with antialiasing */
			vec3_t pos;

			/* add offset for supersampling */
			VectorMA(li.surfpt[i], sampleofs[grid_type][j][0] * li.step, li.textoworld[0], pos);
			VectorMA(pos, sampleofs[grid_type][j][1] * li.step, li.textoworld[1], pos);

			NudgeSamplePosition(pos, normal, center, pos);

			GatherSampleLight(pos, normal, sample, direction, scale, headhints);
		}
		if (VectorNotEmpty(direction)) {
			vec3_t dir;

			/* normalize it */
			VectorNormalize(direction);

			/* finalize the lighting direction for the sample */
			TangentVectors(normal, sdir, tdir, tangent, binormal);

			dir[0] = DotProduct(direction, tangent);
			dir[1] = DotProduct(direction, binormal);
			dir[2] = DotProduct(direction, normal);

			VectorCopy(dir, direction);
		}
	}

	/* Free the hints. */
	Mem_Free(headhints);

	for (i = 0; i < fl->numsamples; i++) {  /* pad them */
		float* const direction = fl->directions[i];
		if (VectorEmpty(direction))
			VectorSet(direction, 0.0, 0.0, 1.0);
	}

	/* free the sample positions for the face */
	Mem_Free(li.surfpt);
}
Beispiel #6
0
/*
 * @brief Writes vertex data for the given surface to the load model's arrays.
 *
 * @param count The current vertex count for the load model.
 */
static void R_LoadBspVertexArrays_Surface(r_model_t *mod, r_bsp_surface_t *surf, GLuint *count) {
	uint16_t i;

	surf->index = *count;
	for (i = 0; i < surf->num_edges; i++) {

		const int32_t index = mod->bsp->surface_edges[surf->first_edge + i];

		const r_bsp_edge_t *edge;
		r_bsp_vertex_t *vert;

		// vertex
		if (index > 0) { // negative indices to differentiate which end of the edge
			edge = &mod->bsp->edges[index];
			vert = &mod->bsp->vertexes[edge->v[0]];
		} else {
			edge = &mod->bsp->edges[-index];
			vert = &mod->bsp->vertexes[edge->v[1]];
		}

		memcpy(&mod->verts[(*count) * 3], vert->position, sizeof(vec3_t));

		// texture directional vectors and offsets
		const vec_t *sdir = surf->texinfo->vecs[0];
		const vec_t soff = surf->texinfo->vecs[0][3];

		const vec_t *tdir = surf->texinfo->vecs[1];
		const vec_t toff = surf->texinfo->vecs[1][3];

		// texture coordinates
		vec_t s = DotProduct(vert->position, sdir) + soff;
		s /= surf->texinfo->material->diffuse->width;

		vec_t t = DotProduct(vert->position, tdir) + toff;
		t /= surf->texinfo->material->diffuse->height;

		mod->texcoords[(*count) * 2 + 0] = s;
		mod->texcoords[(*count) * 2 + 1] = t;

		// lightmap texture coordinates
		if (surf->flags & R_SURF_LIGHTMAP) {
			s = DotProduct(vert->position, sdir) + soff;
			s -= surf->st_mins[0];
			s += surf->light_s * mod->bsp->lightmaps->scale;
			s += mod->bsp->lightmaps->scale / 2.0;
			s /= surf->lightmap->width * mod->bsp->lightmaps->scale;

			t = DotProduct(vert->position, tdir) + toff;
			t -= surf->st_mins[1];
			t += surf->light_t * mod->bsp->lightmaps->scale;
			t += mod->bsp->lightmaps->scale / 2.0;
			t /= surf->lightmap->height * mod->bsp->lightmaps->scale;
		}

		mod->lightmap_texcoords[(*count) * 2 + 0] = s;
		mod->lightmap_texcoords[(*count) * 2 + 1] = t;

		// normal vector, which is per-vertex for SURF_PHONG

		const vec_t *normal;
		if ((surf->texinfo->flags & SURF_PHONG) && !VectorCompare(vert->normal, vec3_origin))
			normal = vert->normal;
		else
			normal = surf->normal;

		memcpy(&mod->normals[(*count) * 3], normal, sizeof(vec3_t));

		// tangent vectors
		vec4_t tangent;
		vec3_t bitangent;

		TangentVectors(normal, sdir, tdir, tangent, bitangent);
		memcpy(&mod->tangents[(*count) * 4], tangent, sizeof(vec4_t));

		(*count)++;
	}
}