Esempio n. 1
0
void ProcessLine(VertexData& v0, VertexData& v1)
{
	if (gstate.isModeThrough()) {
		// Actually, should clip this one too so we don't need to do bounds checks in the rasterizer.
		Rasterizer::DrawLine(v0, v1);
		return;
	}

	VertexData *Vertices[2] = {&v0, &v1};

	int mask0 = CalcClipMask(v0.clippos);
	int mask1 = CalcClipMask(v1.clippos);
	int mask = mask0 | mask1;

	if (mask0 & mask1) {
		// Even if clipping is disabled, we can discard if the line is entirely outside.
		return;
	}

	if (mask) {
		CLIP_LINE(CLIP_POS_X_BIT, -1,  0,  0, 1);
		CLIP_LINE(CLIP_NEG_X_BIT,  1,  0,  0, 1);
		CLIP_LINE(CLIP_POS_Y_BIT,  0, -1,  0, 1);
		CLIP_LINE(CLIP_NEG_Y_BIT,  0,  1,  0, 1);
		CLIP_LINE(CLIP_POS_Z_BIT,  0,  0,  0, 1);
		CLIP_LINE(CLIP_NEG_Z_BIT,  0,  0,  1, 1);
	}

	VertexData data[2] = { *Vertices[0], *Vertices[1] };
	data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos);
	data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos);
	Rasterizer::DrawLine(data[0], data[1]);
}
Esempio n. 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];
				}
			}
		}
	}
Esempio n. 3
0
	void ClipLine(int *indices)
	{
		int mask = 0;
		int clip_mask[2] = { 0, 0 };

		for (int i = 0; i < 2; ++i)
		{
			clip_mask[i] = CalcClipMask(Vertices[i]);
			mask |= clip_mask[i];
		}

		if (mask == 0)
			return;

		float t0 = 0;
		float t1 = 0;

		// Mark unused in case of early termination
		// of the macros below. (When fully clipped)
		indices[0] = SKIP_FLAG;
		indices[1] = SKIP_FLAG;

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

		// Restore the old values as this line
		// was not fully clipped.
		indices[0] = 0;
		indices[1] = 1;

		int numVertices = 2;

		if (clip_mask[0])
		{
			indices[0] = numVertices;
			AddInterpolatedVertex(t0, 0, 1, numVertices);
		}

		if (clip_mask[1])
		{
			indices[1] = numVertices;
			AddInterpolatedVertex(t1, 1, 0, numVertices);
		}
	}
Esempio n. 4
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]);
		}
	}
}
Esempio n. 5
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]);
		}
	}
}