Example #1
0
/* Clip a triangle against the viewport and user clip planes.
 */
static void TAG(clip_draw_triangle)( GLcontext *ctx,
				     TNL_VERTEX *v0,
				     TNL_VERTEX *v1,
				     TNL_VERTEX *v2,
				     GLuint mask )
{
   LOCAL_VARS;
   GET_INTERP_FUNC;
   TNL_VERTEX tmp[MAX_CLIPPED_VERTICES];
   TNL_VERTEX *verts = tmp;
   TNL_VERTEX *(inlist[2][MAX_CLIPPED_VERTICES]);
   TNL_VERTEX **out;
   GLuint in = 0;
   GLuint n = 3;
   GLuint i;

   ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */

   POLY_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
   POLY_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
   POLY_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
   POLY_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
   POLY_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
   POLY_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );

   if ((ctx->_TriangleCaps & DD_FLATSHADE) && v2 != inlist[0]) 
      COPY_PV( ctx, inlist[0], v2 );

   out = inlist[in];
   DRAW_POLYGON( out, n );
}
Example #2
0
	static void ClipTriangle(int *indices, int* numIndices)
	{
		int mask = 0;

		mask |= CalcClipMask(Vertices[0]);
		mask |= CalcClipMask(Vertices[1]);
		mask |= CalcClipMask(Vertices[2]);

		if (mask != 0)
		{
			for (int i = 0; i < 3; i += 3)
			{
				int vlist[2][2*6+1];
				int *inlist = vlist[0], *outlist = vlist[1];
				int n = 3;
				int numVertices = 3;

				inlist[0] = 0;
				inlist[1] = 1;
				inlist[2] = 2;

				// mark this triangle as unused in case it should be completely
				// clipped
				indices[0] = SKIP_FLAG;
				indices[1] = SKIP_FLAG;
				indices[2] = SKIP_FLAG;

				POLY_CLIP(CLIP_POS_X_BIT, -1,  0,  0, 1);
				POLY_CLIP(CLIP_NEG_X_BIT,  1,  0,  0, 1);
				POLY_CLIP(CLIP_POS_Y_BIT,  0, -1,  0, 1);
				POLY_CLIP(CLIP_NEG_Y_BIT,  0,  1,  0, 1);
				POLY_CLIP(CLIP_POS_Z_BIT,  0,  0,  0, 1);
				POLY_CLIP(CLIP_NEG_Z_BIT,  0,  0,  1, 1);

				INCSTAT(stats.thisFrame.numTrianglesClipped);

				// transform the poly in inlist into triangles
				indices[0] = inlist[0];
				indices[1] = inlist[1];
				indices[2] = inlist[2];
				for (int j = 3; j < n; ++j)
				{
					indices[(*numIndices)++] = inlist[0];
					indices[(*numIndices)++] = inlist[j - 1];
					indices[(*numIndices)++] = inlist[j];
				}
			}
		}
	}
Example #3
0
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking) {
	if (gstate.isModeThrough()) {
		// In case of cull reordering, make sure the right color is on the final vertex.
		if (gstate.getShadeMode() == GE_SHADE_FLAT) {
			VertexData corrected2 = v2;
			corrected2.color0 = provoking.color0;
			corrected2.color1 = provoking.color1;
			Rasterizer::DrawTriangle(v0, v1, corrected2);
		} else {
			Rasterizer::DrawTriangle(v0, v1, v2);
		}
		return;
	}

	enum { NUM_CLIPPED_VERTICES = 33, NUM_INDICES = NUM_CLIPPED_VERTICES + 3 };

	VertexData* Vertices[NUM_INDICES];
	VertexData ClippedVertices[NUM_CLIPPED_VERTICES];
	for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i)
		Vertices[i+3] = &ClippedVertices[i];

	// TODO: Change logic when it's a backface (why? In what way?)
	Vertices[0] = &v0;
	Vertices[1] = &v1;
	Vertices[2] = &v2;

	int indices[NUM_INDICES] = { 0, 1, 2, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG,
									SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG,
									SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG };
	int numIndices = 3;

	int mask = 0;
	mask |= CalcClipMask(v0.clippos);
	mask |= CalcClipMask(v1.clippos);
	mask |= CalcClipMask(v2.clippos);

	if (mask) {
		for (int i = 0; i < 3; i += 3) {
			int vlist[2][2*6+1];
			int *inlist = vlist[0], *outlist = vlist[1];
			int n = 3;
			int numVertices = 3;

			inlist[0] = 0;
			inlist[1] = 1;
			inlist[2] = 2;

			// mark this triangle as unused in case it should be completely clipped
			indices[0] = SKIP_FLAG;
			indices[1] = SKIP_FLAG;
			indices[2] = SKIP_FLAG;

			POLY_CLIP(CLIP_POS_X_BIT, -1,  0,  0, 1);
			POLY_CLIP(CLIP_NEG_X_BIT,  1,  0,  0, 1);
			POLY_CLIP(CLIP_POS_Y_BIT,  0, -1,  0, 1);
			POLY_CLIP(CLIP_NEG_Y_BIT,  0,  1,  0, 1);
			POLY_CLIP(CLIP_POS_Z_BIT,  0,  0,  0, 1);
			POLY_CLIP(CLIP_NEG_Z_BIT,  0,  0,  1, 1);

			// transform the poly in inlist into triangles
			indices[0] = inlist[0];
			indices[1] = inlist[1];
			indices[2] = inlist[2];
			for (int j = 3; j < n; ++j) {
				indices[numIndices++] = inlist[0];
				indices[numIndices++] = inlist[j - 1];
				indices[numIndices++] = inlist[j];
			}
		}
	} else if (CalcClipMask(v0.clippos) & CalcClipMask(v1.clippos) & CalcClipMask(v2.clippos))  {
		// If clipping is disabled, only discard the current primitive
		// if all three vertices lie outside one of the clipping planes
		return;
	}

	for (int i = 0; i + 3 <= numIndices; i += 3) {
		if (indices[i] != SKIP_FLAG) {
			VertexData data[3] = { *Vertices[indices[i]], *Vertices[indices[i+1]], *Vertices[indices[i+2]] };
			data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos);
			data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos);
			data[2].screenpos = TransformUnit::ClipToScreen(data[2].clippos);

			if (gstate.getShadeMode() == GE_SHADE_FLAT) {
				// So that the order of clipping doesn't matter...
				data[2].color0 = provoking.color0;
				data[2].color1 = provoking.color1;
			}

			Rasterizer::DrawTriangle(data[0], data[1], data[2]);
		}
	}
}
Example #4
0
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2)
{
	if (gstate.isModeThrough()) {
		Rasterizer::DrawTriangle(v0, v1, v2);
		return;
	}

	enum { NUM_CLIPPED_VERTICES = 33, NUM_INDICES = NUM_CLIPPED_VERTICES + 3 };

	VertexData* Vertices[NUM_INDICES];
	VertexData ClippedVertices[NUM_CLIPPED_VERTICES];
	for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i)
		Vertices[i+3] = &ClippedVertices[i];

	// TODO: Change logic when it's a backface
	Vertices[0] = &v0;
	Vertices[1] = &v1;
	Vertices[2] = &v2;

	int indices[NUM_INDICES] = { 0, 1, 2, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG,
									SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG,
									SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG };
	int numIndices = 3;

	int mask = 0;
	mask |= CalcClipMask(v0.clippos);
	mask |= CalcClipMask(v1.clippos);
	mask |= CalcClipMask(v2.clippos);

	if (mask && (gstate.clipEnable & 0x1)) {
		// discard if any vertex is outside the near clipping plane
		if (mask & CLIP_NEG_Z_BIT)
			return;

		for(int i = 0; i < 3; i += 3) {
			int vlist[2][2*6+1];
			int *inlist = vlist[0], *outlist = vlist[1];
			int n = 3;
			int numVertices = 3;

			inlist[0] = 0;
			inlist[1] = 1;
			inlist[2] = 2;

			// mark this triangle as unused in case it should be completely clipped
			indices[0] = SKIP_FLAG;
			indices[1] = SKIP_FLAG;
			indices[2] = SKIP_FLAG;

			POLY_CLIP(CLIP_POS_X_BIT, -1,  0,  0, 1);
			POLY_CLIP(CLIP_NEG_X_BIT,  1,  0,  0, 1);
			POLY_CLIP(CLIP_POS_Y_BIT,  0, -1,  0, 1);
			POLY_CLIP(CLIP_NEG_Y_BIT,  0,  1,  0, 1);
			POLY_CLIP(CLIP_POS_Z_BIT,  0,  0,  0, 1);
			POLY_CLIP(CLIP_NEG_Z_BIT,  0,  0,  1, 1);

			// transform the poly in inlist into triangles
			indices[0] = inlist[0];
			indices[1] = inlist[1];
			indices[2] = inlist[2];
			for (int j = 3; j < n; ++j) {
				indices[numIndices++] = inlist[0];
				indices[numIndices++] = inlist[j - 1];
				indices[numIndices++] = inlist[j];
			}
		}
	} else if (CalcClipMask(v0.clippos) & CalcClipMask(v1.clippos) & CalcClipMask(v2.clippos))  {
		// If clipping is disabled, only discard the current primitive
		// if all three vertices lie outside one of the clipping planes
		return;
	}

	for(int i = 0; i+3 <= numIndices; i+=3)
	{
		if(indices[i] != SKIP_FLAG)
		{
			VertexData data[3] = { *Vertices[indices[i]], *Vertices[indices[i+1]], *Vertices[indices[i+2]] };
			data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos);
			data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos);
			data[2].screenpos = TransformUnit::ClipToScreen(data[2].clippos);
			Rasterizer::DrawTriangle(data[0], data[1], data[2]);
		}
	}
}