📄 graphics3d.cpp
字号:
top++;
}
// near z cut
i = head;
while (list[i].z < m_zNear) {
i = next[i];
if (i == head)
break;
}
if (list[i].z < m_zNear)
return;
head = i;
while (list[next[i]].z >= m_zNear) {
i = next[i];
if (i == head)
break;
}
if (list[next[i]].z < m_zNear) {
j = next[i];
temp = (list[i].z - m_zNear) * recipTable[list[i].z - list[j].z];
if (temp >= SHIFT2VALUE>>1) {
list[top].x = list[i].x - ((list[i].x - list[j].x) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].y = list[i].y - ((list[i].y - list[j].y) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].u = list[i].u - ((list[i].u - list[j].u) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].v = list[i].v - ((list[i].v - list[j].v) * (temp >>SHIFT) >>RECIPBITSHIFT);
} else {
list[top].x = list[i].x - ((list[i].x - list[j].x) * temp >>RECIPBIT);
list[top].y = list[i].y - ((list[i].y - list[j].y) * temp >>RECIPBIT);
list[top].u = list[i].u - ((list[i].u - list[j].u) * temp >>RECIPBIT);
list[top].v = list[i].v - ((list[i].v - list[j].v) * temp >>RECIPBIT);
}
list[top].z = m_zNear;
next[top] = j;
next[i] = top;
i = head = top;
top++;
while (list[next[i]].z < m_zNear)
i = next[i];
j = next[i];
temp = (list[j].z - m_zNear) * recipTable[list[j].z - list[i].z];
if (temp >= SHIFT2VALUE>>1) {
list[top].x = list[j].x - ((list[j].x - list[i].x) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].y = list[j].y - ((list[j].y - list[i].y) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].u = list[j].u - ((list[j].u - list[i].u) * (temp >>SHIFT) >>RECIPBITSHIFT);
list[top].v = list[j].v - ((list[j].v - list[i].v) * (temp >>SHIFT) >>RECIPBITSHIFT);
} else {
list[top].x = list[j].x - ((list[j].x - list[i].x) * temp >>RECIPBIT);
list[top].y = list[j].y - ((list[j].y - list[i].y) * temp >>RECIPBIT);
list[top].u = list[j].u - ((list[j].u - list[i].u) * temp >>RECIPBIT);
list[top].v = list[j].v - ((list[j].v - list[i].v) * temp >>RECIPBIT);
}
list[top].z = m_zNear;
next[head] = top;
next[top] = j;
top++;
}
// render
j = head;
zmax = zmin = list[j].z;
for (i=2; i>=0; i--) {
temp = m_zDist * recipTable[list[j].z];
rp[i].x = list[j].x * temp >>RECIPBITSHIFT;
rp[i].y = list[j].y * temp >>RECIPBITSHIFT;
rp[i].z = list[j].z;
rp[i].u = list[j].u;
rp[i].v = list[j].v;
if (rp[i].z > zmax)
zmax = rp[i].z;
else
if (rp[i].z < zmin)
zmin = rp[i].z;
j = next[j];
}
// first triangle
if (m_skeleton)
if (m_renderParam & RP_FLAT)
Skeleton(rp, 1);
else
if (zmin >= (zmax - zmin) * ZRATIOIGNORE)
Skeleton(rp, 1);
else
Skeleton(rp);
else
if (m_renderParam & RP_FLAT)
RenderFlatTriangle(rp);
else
if (zmin >= (zmax - zmin) * ZRATIOIGNORE)
RenderFlatTriangle(rp);
else
RenderTriangle2(rp);
i = 0;
// other triangle
while (j != head) {
temp = m_zDist * recipTable[list[j].z];
i = (i+1)&1;
rp[i].x = list[j].x * temp >>RECIPBITSHIFT;
rp[i].y = list[j].y * temp >>RECIPBITSHIFT;
rp[i].z = list[j].z;
rp[i].u = list[j].u;
rp[i].v = list[j].v;
j = next[j];
if (rp[0].z > rp[1].z)
if (rp[0].z > rp[2].z) {
zmax = 0;
if (rp[1].z > rp[2].z)
zmin = 2;
else
zmin = 1;
} else {
zmax = 2;
zmin = 1;
}
else
if (rp[1].z > rp[2].z) {
zmax = 1;
if (rp[0].z > rp[2].z)
zmin = 2;
else
zmin = 0;
} else {
zmax = 2;
zmin = 0;
}
if (m_skeleton)
if (m_renderParam & RP_FLAT)
Skeleton(rp, 1);
else
if (rp[zmin].z >= (rp[zmax].z - rp[zmin].z) * ZRATIOIGNORE)
Skeleton(rp, 1);
else
Skeleton(rp);
else
if (m_renderParam & RP_FLAT)
RenderFlatTriangle(rp);
else
if (rp[zmin].z >= (rp[zmax].z - rp[zmin].z) * ZRATIOIGNORE)
RenderFlatTriangle(rp);
else
RenderTriangle2(rp);
}
}
void CGraphics3D::RenderIndexdPrimitives(Vertex *pVertics, Texcoord *pTexcoords, Face *pindics, int length)
{
Vector4s *vInCamera, vertex, vertex2;
vInCamera = (Vector4s *)SMemory->StackMalloc(2000*sizeof(Vector4s));
Point rp[3];
Vertex *v;
int i, j, temp, temp2;
m_random++;
if (m_renderParam & RP_MIRROR)
for (i=0; i<length; i++){
// back face
temp = i*9;
v = &pVertics[pindics[i].ver[0]];
vertex.x = pindics[i].normalx;
vertex.y = pindics[i].normaly;
vertex.z = pindics[i].normalz;
vertex2 = m_matInvWorld.TransformNormal(vertex);
m_matInvWorld.Transform(*v, &vertex);
vertex -= m_eye;
if (vertex * vertex2 >=0)
continue;
// transform to camera space
j=0;
while (j<3) {
temp2 = pindics[i].tex[j];
temp = pindics[i].ver[j];
m_matInvTrans.Transform(pVertics[temp], &vertex);
rp[j].x = vertex.x;
rp[j].y = vertex.y;
rp[j].z = vertex.z;
rp[j].u = pTexcoords[temp2].u <<m_curTexture->m_shift;
rp[j].v = pTexcoords[temp2].v <<m_curTexture->m_shift;
j++;
}
if (m_renderParam & RP_NOFRUSTUM)
if (m_renderParam & RP_FLAT) {
for (j=0; j<3; j++) {
temp = m_zDist * recipTable[rp[j].z];
rp[j].x = rp[j].x * temp >>RECIPBITSHIFT;
rp[j].y = rp[j].y * temp >>RECIPBITSHIFT;
}
if (m_skeleton)
Skeleton(rp, 1);
else
RenderFlatTriangle(rp);
continue;
} else {
// reserved;
}
FrustumCut(rp);
}
else
for (i=0; i<length; i++){
// back face
vertex.x = pindics[i].normalx;
vertex.y = pindics[i].normaly;
vertex.z = pindics[i].normalz;
vertex2 = m_matTrans.TransformNormal(vertex);
temp = pindics[i].ver[0];
if (vInCamera[temp].s != m_random) {
m_matTrans.Transform(pVertics[temp], &vInCamera[temp]);
vInCamera[temp].s = m_random;
}
m_faceLight = vInCamera[temp] * vertex2;
if (m_faceLight >=0)
continue;
if (m_renderParam & RP_LIGHTNING) {
vertex.Init(-1, 0, 1);
vertex.Normalize();
m_faceLight = (1-vertex * vertex2)>>COS_SIN_SHIFT;
if (m_faceLight < 0)
m_faceLight = 0;
}
// transform to camera space
j=0;
while (j<3) {
temp2 = pindics[i].tex[j];
temp = pindics[i].ver[j];
if (vInCamera[temp].s != m_random) {
m_matTrans.Transform(pVertics[temp], &vInCamera[temp]);
vInCamera[temp].s = m_random;
}
rp[j].x = vInCamera[temp].x;
rp[j].y = vInCamera[temp].y;
rp[j].z = vInCamera[temp].z;
rp[j].u = pTexcoords[temp2].u <<m_curTexture->m_shift;
rp[j].v = pTexcoords[temp2].v <<m_curTexture->m_shift;
j++;
}
if (m_renderParam & RP_NOFRUSTUM)
if (m_renderParam & RP_FLAT) {
for (j=0; j<3; j++) {
temp = m_zDist * recipTable[rp[j].z];
rp[j].x = rp[j].x * temp >>RECIPBITSHIFT;
rp[j].y = rp[j].y * temp >>RECIPBITSHIFT;
}
if (m_skeleton)
Skeleton(rp, 1);
else
RenderFlatTriangle(rp);
continue;
} else {
// reserved;
}
FrustumCut(rp);
}
SMemory->StackFree(NULL);
}
/*
void CGraphics3D::RenderFlatTriangle(Point *pPoint)
{
Point rp[3], *ymax, *ymid, *ymin;
int j, k, m, n, l, temp, midleft;
int dx[3], du[3], dv[3];
int dy[3], dxy[3], dzy[3], startxy[2], startzy[2], zytemp[2], xytemp[2];
int dz[3], duy[3], dvy[3], startuy[2], startvy[2];
int startu, startv;
int dux, dvx;
int pos;
m_flatRendered++;
for (j=0; j<3; j++) {
rp[j].x = pPoint[j].x + (SCREEN_WIDTH>>1 <<SHIFT);
rp[j].y = pPoint[j].y + (SCREEN_HEIGHT>>1 <<SHIFT);
rp[j].z = recipTable[pPoint[j].z];
rp[j].u = pPoint[j].u;
rp[j].v = pPoint[j].v;
}
if (rp[0].y < rp[1].y)
if (rp[1].y < rp[2].y) {
ymax = rp+2;
ymin = rp;
ymid = rp+1;
} else {
ymax = rp+1;
if (rp[2].y > rp[0].y) {
ymin = rp;
ymid = rp+2;
} else {
ymin = rp+2;
ymid = rp;
}
}
else
if (rp[2].y > rp[0].y) {
ymax = rp+2;
ymin = rp+1;
ymid = rp;
} else {
ymax = rp;
if (rp[1].y < rp[2].y) {
ymin = rp+1;
ymid = rp+2;
} else {
ymin = rp+2;
ymid = rp+1;
}
}
if (ymax->y == ymin->y)
return;
j = SCREEN_HEIGHT;
k = 1;
if (ymax->y < j <<SHIFT)
j = ymax->y >>SHIFT;
if (ymid->y > SHIFTVALUE)
k = ((ymid->y-1) >>SHIFT) + 1;
dx[0] = ymax->x - ymid->x;
dx[1] = ymid->x - ymin->x;
dx[2] = dx[0] + dx[1];
dy[0] = ymax->y - ymid->y;
dy[1] = ymid->y - ymin->y;
dy[2] = dy[0] + dy[1];
dz[0] = ymax->z - ymid->z;
dz[1] = ymid->z - ymin->z;
dz[2] = dz[0] + dz[1];
du[0] = ymax->u - ymid->u;
du[1] = ymid->u - ymin->u;
du[2] = du[0] + du[1];
dv[0] = ymax->v - ymid->v;
dv[1] = ymid->v - ymin->v;
dv[2] = dv[0] + dv[1];
dxy[2] = (dx[2] <<RECIPBITSHIFT) / dy[2] <<2;
dzy[2] = (dz[2] <<RECIPBITSHIFT) / dy[2] <<2;
duy[2] = (du[2] <<SHIFT) / dy[2];
dvy[2] = (dv[2] <<SHIFT) / dy[2];
if (!dy[0])
if (ymax->x > ymid->x)
midleft = true;
else
midleft = false;
else {
dxy[0] = (dx[0] <<RECIPBITSHIFT) / dy[0] <<2;
dzy[0] = (dz[0] <<RECIPBITSHIFT) / dy[0] <<2;
duy[0] = (du[0] <<SHIFT) / dy[0];
dvy[0] = (dv[0] <<SHIFT) / dy[0];
if (dxy[0] > dxy[2])
midleft = true;
else
midleft = false;
}
l = ymax->y - (j<<SHIFT);
if (midleft) {
startxy[1] = (ymax->x <<SHIFT) - (dxy[2] * l >>SHIFT);
startzy[1] = (ymax->z <<SHIFT) - (dzy[2] * l >>SHIFT);
startuy[1] = ((ymax->u <<SHIFT) - duy[2] * l) >>SHIFT;
startvy[1] = ((ymax->v <<SHIFT) - dvy[2] * l) >>SHIFT;
} else {
startxy[0] = (ymax->x <<SHIFT) - (dxy[2] * l >>SHIFT);
startzy[0] = (ymax->z <<SHIFT) - (dzy[2] * l >>SHIFT);
startuy[0] = ((ymax->u <<SHIFT) - duy[2] * l) >>SHIFT;
startvy[0] = ((ymax->v <<SHIFT) - dvy[2] * l) >>SHIFT;
}
if (j>=k) {
if (midleft) {
startxy[0] = (ymax->x <<SHIFT) - (dxy[0] * l >>SHIFT);
startzy[0] = (ymax->z <<SHIFT) - (dzy[0] * l >>SHIFT);
startuy[0] = ((ymax->u <<SHIFT) - duy[0] * l) >>SHIFT;
startvy[0] = ((ymax->v <<SHIFT) - dvy[0] * l) >>SHIFT;
dxy[1] = dxy[2];
dzy[1] = dzy[2];
duy[1] = duy[2];
dvy[1] = dvy[2];
} else {
startxy[1] = (ymax->x <<SHIFT) - (dxy[0] * l >>SHIFT);
startzy[1] = (ymax->z <<SHIFT) - (dzy[0] * l >>SHIFT);
startuy[1] = ((ymax->u <<SHIFT) - duy[0] * l) >>SHIFT;
startvy[1] = ((ymax->v <<SHIFT) - dvy[0] * l) >>SHIFT;
dxy[1] = dxy[0];
dxy[0] = dxy[2];
dzy[1] = dzy[0];
dzy[0] = dzy[2];
duy[1] = duy[0];
duy[0] = duy[2];
dvy[1] = dvy[0];
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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -