⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics3d.cpp

📁 liu7788414
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			startxy[1] -= dxy[1];
			startuy[0] -= duy[0];
			startuy[1] -= duy[1];
			startvy[0] -= dvy[0];
			startvy[1] -= dvy[1];
			continue;
		}
		temp = recipTable[xytemp[1] - xytemp[0]];
		if (startuy[0] >= startuy[1])
			dux = -((startuy[0] - startuy[1]) * temp >>RECIPBITSHIFT);
		else
			dux = (startuy[1] - startuy[0]) * temp >>RECIPBITSHIFT;
		if (startvy[0] >= startvy[1])
			dvx = -((startvy[0] - startvy[1]) * temp >>RECIPBITSHIFT);
		else
			dvx = (startvy[1] - startvy[0]) * temp >>RECIPBITSHIFT;
		temp = (m<<SHIFT)-xytemp[0];
		startu = startuy[0] + (temp * dux >>SHIFT);
		startv = startvy[0] + (temp * dvx >>SHIFT);
		pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH + m;
		l = pos-m+n;
		while (pos <= l)	{
			if (zytemp[0] > m_pCurrentRenderTarget->m_pZBuffer[pos])	{
				m_pCurrentRenderTarget->m_pZBuffer[pos] = zytemp[0];
				DrawPixel(pos, startu>>SHIFT, startv>>SHIFT);
			}
			startu += dux;
			startv += dvx;
			pos++;
		}
		j--;
		startzy[0] -= dzy[0];
		startzy[1] -= dzy[1];
		startxy[0] -= dxy[0];
		startxy[1] -= dxy[1];
		startuy[0] -= duy[0];
		startuy[1] -= duy[1];
		startvy[0] -= dvy[0];
		startvy[1] -= dvy[1];
	}

	k = 1;
	if (ymin->y > SHIFTVALUE)
		k = ((ymin->y-1) >>SHIFT) + 1;
	if ((j<k) || !dy[1])
		return;
	dxy[1] = (dx[1] <<RECIPBITSHIFT) / dy[1] <<2;
	dzy[1] = (dz[1] <<RECIPBITSHIFT) / dy[1] <<2;
	duy[1] = (du[1] <<SHIFT) / dy[1];
	dvy[1] = (dv[1] <<SHIFT) / dy[1];
	l = ymid->y - (j<<SHIFT);
	if (midleft)	{
		startxy[0] = (ymid->x <<SHIFT) - (dxy[1] * l >>SHIFT);
		startzy[0] = (ymid->z <<SHIFT) - (dzy[1] * l >>SHIFT);
		startuy[0] = ((ymid->u <<SHIFT) - duy[1] * l) >>SHIFT;
		startvy[0] = ((ymid->v <<SHIFT) - dvy[1] * l) >>SHIFT;
		dxy[0] = dxy[1];
		dzy[0] = dzy[1];
		duy[0] = duy[1];
		dvy[0] = dvy[1];
		dxy[1] = dxy[2];
		dzy[1] = dzy[2];
		duy[1] = duy[2];
		dvy[1] = dvy[2];
	}	else	{
		startxy[1] = (ymid->x <<SHIFT) - (dxy[1] * l >>SHIFT);
		startzy[1] = (ymid->z <<SHIFT) - (dzy[1] * l >>SHIFT);
		startuy[1] = ((ymid->u <<SHIFT) - duy[1] * l) >>SHIFT;
		startvy[1] = ((ymid->v <<SHIFT) - dvy[1] * l) >>SHIFT;
		dxy[0] = dxy[2];
		dzy[0] = dzy[2];
		duy[0] = duy[2];
		dvy[0] = dvy[2];
	}

	while (j>=k)	{
		zytemp[0] = startzy[0] >>SHIFT;
		zytemp[1] = startzy[1] >>SHIFT;
		xytemp[0] = startxy[0] >>SHIFT;
		xytemp[1] = startxy[1] >>SHIFT;
		m = xytemp[0];
		n = xytemp[1];
		if ((m > (SCREEN_WIDTH-1) << SHIFT) || (n < 0))	{
			j--;
			startzy[0] -= dzy[0];
			startzy[1] -= dzy[1];
			startxy[0] -= dxy[0];
			startxy[1] -= dxy[1];
			startuy[0] -= duy[0];
			startuy[1] -= duy[1];
			startvy[0] -= dvy[0];
			startvy[1] -= dvy[1];
			continue;
		}
		if (m<0)
			m=0;
		else
			m = ((m-1) >>SHIFT) +1;
		if (n > (SCREEN_WIDTH-1)<<SHIFT)
			n = SCREEN_WIDTH;
		else
			n = n>>SHIFT;
		if (m>n)	{
			j--;
			startzy[0] -= dzy[0];
			startzy[1] -= dzy[1];
			startxy[0] -= dxy[0];
			startxy[1] -= dxy[1];
			startuy[0] -= duy[0];
			startuy[1] -= duy[1];
			startvy[0] -= dvy[0];
			startvy[1] -= dvy[1];
			continue;
		}
		temp = recipTable[xytemp[1] - xytemp[0]];
		if (startuy[0] >= startuy[1])
			dux = -((startuy[0] - startuy[1]) * temp >>RECIPBITSHIFT);
		else
			dux = (startuy[1] - startuy[0]) * temp >>RECIPBITSHIFT;
		if (startvy[0] >= startvy[1])
			dvx = -((startvy[0] - startvy[1]) * temp >>RECIPBITSHIFT);
		else
			dvx = (startvy[1] - startvy[0]) * temp >>RECIPBITSHIFT;
		temp = (m<<SHIFT)-xytemp[0];
		startu = startuy[0] + (temp * dux >>SHIFT);
		startv = startvy[0] + (temp * dvx >>SHIFT);
		pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH + m;
		l = pos-m+n;
		while (pos <= l)	{
			if (zytemp[0] > m_pCurrentRenderTarget->m_pZBuffer[pos])	{
				m_pCurrentRenderTarget->m_pZBuffer[pos] = zytemp[0];
				DrawPixel(pos, startu>>SHIFT, startv>>SHIFT);
			}
			startu += dux;
			startv += dvx;
			pos++;
		}
		j--;
		startzy[0] -= dzy[0];
		startzy[1] -= dzy[1];
		startxy[0] -= dxy[0];
		startxy[1] -= dxy[1];
		startuy[0] -= duy[0];
		startuy[1] -= duy[1];
		startvy[0] -= dvy[0];
		startvy[1] -= dvy[1];
	}
}
*/

int CGraphics3D::BBCheck(const Vertex& v1, const Vertex& v2) const
{
	const Vertex vv1 = m_matTrans.Transform(v1);
	const Vertex vv2 = m_matTrans.Transform(v2);
	Vertex temp = v1;
	temp.x = v2.x;
	const Vertex vv3 = m_matTrans.Transform(temp);
	temp.x = v1.x;
	temp.y = v2.y;
	temp.z = v2.z;
	const Vertex vv4 = m_matTrans.Transform(temp);
	if ((vv1.z <= m_zNear) && (vv2.z <= m_zNear) && (vv3.z <= m_zNear) && (vv4.z <= m_zNear))
		return false;
	if ((vv1.z <= 0) || (vv2.z <= 0) || (vv3.z <= 0) || (vv4.z <= 0))
		return true;
	// convert to 2d and judge
	const int vv1z = m_zDist * recipTable[vv1.z] >>SHIFT;
	const int vv2z = m_zDist * recipTable[vv2.z] >>SHIFT;
	const int vv3z = m_zDist * recipTable[vv3.z] >>SHIFT;
	const int vv4z = m_zDist * recipTable[vv4.z] >>SHIFT;
	const int vv1xy[2] = {vv1.x * vv1z >>RECIPBITSHIFT2, vv1.y * vv1z >>RECIPBITSHIFT2};
	const int vv2xy[2] = {vv2.x * vv2z >>RECIPBITSHIFT2, vv2.y * vv2z >>RECIPBITSHIFT2};
	const int vv3xy[2] = {vv3.x * vv3z >>RECIPBITSHIFT2, vv3.y * vv3z >>RECIPBITSHIFT2};
	const int vv4xy[2] = {vv4.x * vv4z >>RECIPBITSHIFT2, vv4.y * vv4z >>RECIPBITSHIFT2};
	if (vv1xy[0] >= SCREEN_WIDTH<<7)	{
		if ((vv2xy[0] >= SCREEN_WIDTH<<7) && (vv3xy[0] >= SCREEN_WIDTH<<7) && (vv4xy[0] >= SCREEN_WIDTH<<7))
			return false;
	}	else
		if ((vv1xy[0] < -SCREEN_WIDTH<<7) && (vv2xy[0] < -SCREEN_WIDTH<<7) && (vv3xy[0] < -SCREEN_WIDTH<<7) && (vv4xy[0] < -SCREEN_WIDTH<<7))
			return false;
	if (vv1xy[1] >= SCREEN_HEIGHT<<7)	{
		if ((vv2xy[1] >= SCREEN_HEIGHT<<7) && (vv3xy[1] >= SCREEN_HEIGHT<<7) && (vv4xy[1] >= SCREEN_HEIGHT<<7))
			return false;
	}	else
		if ((vv1xy[1] < -SCREEN_HEIGHT<<7) && (vv2xy[1] < -SCREEN_HEIGHT<<7) && (vv3xy[1] < -SCREEN_HEIGHT<<7) && (vv4xy[1] < -SCREEN_HEIGHT<<7))
			return false;
	return true;
}

int CGraphics3D::BBCheck(const Vector4s&v1) const
{
	const Vector4s vv1 = m_matTrans.Transform(v1);
	if ((vv1.z <= m_zNear))
		return false;
	// convert to 2d and judge
	return true;
}

int CGraphics3D::get2DPos(int x, int y, int z, int& xx, int& yy) const
{
	const Vector4s temp(x, y, z);
	const Vector4s temp2 = m_matView.Transform(temp);
///	SYS_ASSERT(temp2.z > 0);
	if (temp2.z < 0) 
	{
		xx = -1;
		yy = -1;
		return 0;
	}
	const int temp3 = m_zDist * recipTable[temp2.z] >>SHIFT;
	xx = temp2.x * temp3 >>RECIPBITSHIFT;
	yy = temp2.y * temp3 >>RECIPBITSHIFT;
	xx += SCREEN_WIDTH/2;
	yy = SCREEN_HEIGHT/2-yy;
	if ((xx >= 0) && (xx < SCREEN_WIDTH) && (yy >= 0) && (yy < SCREEN_HEIGHT) && 
		(m_pCurrentRenderTarget->m_pZBuffer[yy*SCREEN_WIDTH+xx] < recipTable[temp2.z]))
		return 1;
	else
		return 0;
}

void CGraphics3D::EnableBallLight(int n)
{
	m_onBallLight = n;
}

void CGraphics3D::setZDist(int zangle)
{
	SYS_ASSERT(zangle > 0 && zangle <=682);
	m_FOV = zangle;
	m_zDist = SCREEN_WIDTH/2*Cosinus(zangle/2)/Sinus(zangle/2);
	m_leftFace.x = m_zDist;
	m_rightFace.x = -m_zDist;
	m_bottomFace.y = m_zDist;
	m_upFace.y = -m_zDist;
}

int CGraphics3D::getZDist(void)
{
	return m_FOV;
}

void CGraphics3D::Skeleton(Point *pPoint, int color)
{
	Point rp[3];
	int j;

	for (j=0; j<3; j++)	{
		rp[j].x = pPoint[j].x + (SCREEN_WIDTH/2 <<SHIFT);
		rp[j].y = pPoint[j].y + (SCREEN_HEIGHT <<SHIFT)/2;
		rp[j].z = recipTable[pPoint[j].z];
		rp[j].u = pPoint[j].u;
		rp[j].v = pPoint[j].v;
	}
	pGfx->DrawLine(rp[0].x>>8, (SCREEN_HEIGHT-(rp[0].y>>8)), rp[1].x>>8, (SCREEN_HEIGHT-(rp[1].y>>8)), color?MAKERGB(0, 128, 0):MAKERGB(0, 0, 255));
	pGfx->DrawLine(rp[1].x>>8, (SCREEN_HEIGHT-(rp[1].y>>8)), rp[2].x>>8, (SCREEN_HEIGHT-(rp[2].y>>8)), color?MAKERGB(0, 128, 0):MAKERGB(0, 0, 255));
	pGfx->DrawLine(rp[2].x>>8, (SCREEN_HEIGHT-(rp[2].y>>8)), rp[0].x>>8, (SCREEN_HEIGHT-(rp[0].y>>8)), color?MAKERGB(0, 128, 0):MAKERGB(0, 0, 255));
}

void CGraphics3D::RenderTriangle2(Point *pPoint)
{
	Point rp[3];
	int i, m, n, pos, temp, startx, endx, mnchange;
	int ymin, ymax, ymid;
	int ystart, yend, undermidpt;
	int dx[3], dy[3], dz[3], dxy[3], dzy[3], duy[3], dvy[3], startxy[3], startzy[3], startuy[3], startvy[3];
	int dux, dvx, dzx, startux, startvx, startzx;

	// init conversion
	// u, v: unsigned int
	for (i=0; i<3; i++)	{
		rp[i].x = pPoint[i].x + (SCREEN_WIDTH>>1<<SHIFT);
		rp[i].y = pPoint[i].y + (SCREEN_HEIGHT<<SHIFT>>1);
		rp[i].z = pPoint[i].z;
		ASSERT_OF2(pPoint[i].u, recipTable[pPoint[i].z]);
		ASSERT_OF2(pPoint[i].v, recipTable[pPoint[i].z]);
//		if (pPoint[i].u < 0 || pPoint[i].v < 0)
//			return;
		SYS_ASSERT(pPoint[i].u >= 0);
		SYS_ASSERT(pPoint[i].v >= 0);
		rp[i].u = (unsigned int)pPoint[i].u*(unsigned int)recipTable[pPoint[i].z] >>SHIFT>>HALFSHIFT;
		rp[i].v = (unsigned int)pPoint[i].v*(unsigned int)recipTable[pPoint[i].z] >>SHIFT>>HALFSHIFT;
	}

	// render qualify
	ymin = ymax = 0;
	if (rp[0].y < rp[1].y)
		if (rp[1].y < rp[2].y)	{
			ymax = 2;
			ymin = 0;
			ymid = 1;
		}	else	{
			ymax = 1;
			if (rp[2].y > rp[0].y)	{
				ymin = 0;
				ymid = 2;
			}	else	{
				ymin = 2;
				ymid = 0;
			}
		}
	else
		if (rp[2].y > rp[0].y)	{
			ymax = 2;
			ymin = 1;
			ymid = 0;
		}	else	{
			ymax = 0;
			if (rp[1].y < rp[2].y)	{
				ymin = 1;
				ymid = 2;
			}	else	{
				ymin = 2;
				ymid = 1;
			}
		}
	if (rp[ymax].y == rp[ymin].y)
		return;
	ystart = SCREEN_HEIGHT;
	yend = 1;
	if (rp[ymax].y < ystart<<SHIFT)
		ystart = rp[ymax].y>>SHIFT;
	if (rp[ymin].y > SHIFTVALUE)
		yend = ((rp[ymin].y-1) >>SHIFT) + 1;
	if (yend > ystart)
		return;
	if ((ystart == yend) && (rp[ymid].y&SHIFTMASK))
		if ((rp[ymin].y>>SHIFT) == (rp[ymax].y>>SHIFT))
			return;

	// precalculation for line loop
	dx[0] = rp[ymax].x - rp[ymid].x;
	dx[1] = rp[ymid].x - rp[ymin].x;
	dx[2] = dx[0] + dx[1];
	dy[0] = rp[ymax].y - rp[ymid].y;
	dy[1] = rp[ymid].y - rp[ymin].y;
	dy[2] = dy[0] + dy[1];
	dz[0] = rp[ymax].z - rp[ymid].z;
	dz[1] = rp[ymid].z - rp[ymin].z;
	dz[2] = dz[0] + dz[1];

	dxy[0] = dx[0];
	dxy[1] = dx[1];
	dxy[2] = dx[2];

	dzy[0] = - dz[0] * (int)((unsigned int)recipTable[rp[ymax].z] * (unsigned int)recipTable[rp[ymid].z] >> RECIPBITSHIFT) >>SHIFT;
	dzy[1] = - dz[1] * (int)((unsigned int)recipTable[rp[ymid].z] * (unsigned int)recipTable[rp[ymin].z] >> RECIPBITSHIFT) >>SHIFT;
	dzy[2] = - dz[2] * (int)((unsigned int)recipTable[rp[ymax].z] * (unsigned int)recipTable[rp[ymin].z] >> RECIPBITSHIFT) >>SHIFT;

	duy[0] = rp[ymax].u - rp[ymid].u;
	duy[1] = rp[ymid].u - rp[ymin].u;
	duy[2] = duy[0] + duy[1];
	dvy[0] = rp[ymax].v - rp[ymid].v;
	dvy[1] = rp[ymid].v - rp[ymin].v;
	dvy[2] = dvy[0] + dvy[1];

	SYS_ASSERT(Abs(dzy[0]) < SHIFT2VALUE);
	SYS_ASSERT(Abs(dzy[1]) < SHIFT2VALUE);
	SYS_ASSERT(Abs(dzy[2]) < SHIFT2VALUE);
	SYS_ASSERT(Abs(dx[0]) < SHIFT2VALUE);
	SYS_ASSERT(Abs(dx[1]) < SHIFT2VALUE);
	SYS_ASSERT(Abs(dx[2]) < SHIFT2VALUE);

	temp = rp[ymax].y - (ystart<<SHIFT);
	ASSERT_OF(Abs(duy[2]), temp);
	ASSERT_OF(Abs(duy[1]), temp);
	ASSERT_OF(Abs(duy[0]), temp);
	ASSERT_OF(Abs(duy[2]), SHIFTVALUE);
	ASSERT_OF(Abs(duy[1]), SHIFTVALUE);
	ASSERT_OF(Abs(duy[0]), SHIFTVALUE);
	ASSERT_OF(Abs(dvy[2]), temp);
	ASSERT_OF(Abs(dvy[1]), temp);
	ASSERT_OF(Abs(dvy[0]), temp);
	ASSERT_OF(Abs(dvy[2]), SHIFTVALUE);
	ASSERT_OF(Abs(dvy[1]), SHIFTVALUE);
	ASSERT_OF(Abs(dvy[0]), SHIFTVALUE);

	dzy[2] = (dzy[2] <<RECIPBITSHIFT) / dy[2];
	dxy[2] = (dxy[2] <<RECIPBITSHIFT) / dy[2];
	startxy[2] = (rp[ymax].x <<RECIPBITSHIFT2) - (dxy[2] * temp >>SHIFT);
	startzy[2] = (recipTable[rp[ymax].z] <<RECIPBITSHIFT2) - (dzy[2] * temp >>SHIFT);
	startuy[2] = rp[ymax].u - duy[2]*temp/dy[2];
	startvy[2] = rp[ymax].v - dvy[2]*temp/dy[2];
	duy[2] = (duy[2]<<SHIFT)/dy[2];
	dvy[2] = (dvy[2]<<SHIFT)/dy[2];

	startxy[0] = startzy[0] = startuy[0] = startvy[0] = startxy[1] = startzy[1] = startuy[1] = startvy[1] = 0;
	if (ystart<<SHIFT >= rp[ymid].y)	{
		startxy[0] = rp[ymax].x <<RECIPBITSHIFT2;
		startzy[0] = recipTable[rp[ymax].z] <<RECIPBITSHIFT2;
		startuy[0] = rp[ymax].u;
		startvy[0] = rp[ymax].v;
		if (rp[ymax].y >>SHIFT != rp[ymid].y >>SHIFT)	{
			dzy[0] = (dzy[0] <<RECIPBITSHIFT) / dy[0];
			dxy[0] = (dxy[0] <<RECIPBITSHIFT) / dy[0];
			startxy[0] -= dxy[0] * temp >>SHIFT;
			startzy[0] -= dzy[0] * temp >>SHIFT;
			startuy[0] -= duy[0] * temp/dy[0];
			startvy[0] -= dvy[0] * temp/dy[0];
			duy[0] = (duy[0]<<SHIFT)/dy[0];
			dvy[0] = (dvy[0]<<SHIFT)/dy[0];
		}
	}
	temp = rp[ymid].y;
	if (temp >= yend<<SHIFT)	{
		if (temp <= ystart<<SHIFT)
			temp &= SHIFTVALUE-1;
		else
			temp -= ystart<<SHIFT;
		startxy[1] = rp[ymid].x <<RECIPBITSHIFT2;
		startzy[1] = recipTable[rp[ymid].z] <<RECIPBITSHIFT2;
		startuy[1] = rp[ymid].u;
		startvy[1] = rp[ymid].v;
		if (rp[ymin].y >>SHIFT != rp[ymid].y >>SHIFT)	{
			dzy[1] = (dzy[1] <<RECIPBITSHIFT) / dy[1];
			dxy[1] = (dxy[1] <<RECIPBITSHIFT) / dy[1];
			startxy[1] -= dxy[1] * temp >>SHIFT;
			startzy[1] -= dzy[1] * temp >>S

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -