📄 graphics3d.cpp
字号:
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 + -