📄 graphics3d.cpp
字号:
#include "Graphics3D.h"
#include "..\system\fsqrt.h"
#include "..\system\gfx.h"
extern CSimpleMemory *SMemory;
extern CGfx *pGfx;
struct _light{
Vector4s pos;
Vector4s ball2pos;
Vector4s vn;
int dist;
};
CGraphics3D::~CGraphics3D()
{
delete [] m_pTextures;
//m_pEngine = NULL;
m_pTextures = NULL;
m_textureCount = 0;
m_pCurrentRenderTarget = NULL;
}
CGraphics3D::CGraphics3D(void)
{
m_textureCount = 0;
//m_pEngine = pEngine;
m_pCurrentRenderTarget = NULL;
m_pTextures = new CTexture[MAXTEXTURES];
m_random = 2350;
m_zDist = 450;
m_zNear = 65;
m_zFar = 4000;
m_leftFace.y = m_rightFace.y = 0;
m_leftFace.z = m_rightFace.z = SCREEN_WIDTH>>1;
m_leftFace.x = m_zDist;
m_rightFace.x = -m_zDist;
m_bottomFace.x = m_upFace.x = 0;
m_bottomFace.z = m_upFace.z = (SCREEN_HEIGHT+1)>>1;
m_bottomFace.y = m_zDist;
m_upFace.y = -m_zDist;
recipTable = (int*)SMemory->GlobalMalloc(ZBUFFERVALUE*sizeof(int));
for (int i=1; i<ZBUFFERVALUE; i++)
recipTable[i] = RECIPVALUE/i;
recipTable[0] = 1;
m_onBallLight = -1;
m_skeleton = false;
}
char CGraphics3D::LoadTexture(char *str, int bIndex)
{
int i = 0;
while (i<m_textureCount) {
if (!STRCMP(str, m_TextureNames[i])) {
return i;
}
i++;
}
SYS_ASSERT( MAXTEXTURES > m_textureCount);
if (m_pTextures[m_textureCount].LoadTexData(str, bIndex))
{
STRCPY(m_TextureNames[i], str, STRLEN(str));
m_textureCount++;
}
return m_textureCount-1;
}
void CGraphics3D::SetMatrix(int type, CMatrix44 *mat)
{
switch (type) {
case 0:
m_matWorld = *mat;
break;
case 1:
m_matView = *mat;
break;
}
m_matTransCamera = m_matView;
m_matTransCamera.PostMultiply(&m_matWorld);
if (m_renderParam & RP_MIRROR) {
m_matInvWorld.Identity();
m_matInvWorld.m[8] = -COS_SIN_MUL;
m_matInvWorld.PostMultiply(&m_matWorld);
m_matInvCamera = m_matView;
m_matInvCamera.PostMultiply(&m_matInvWorld);
}
}
void CGraphics3D::SetTexture(int index)
{
m_curTextureid = index;
m_curTexture = &m_pTextures[index];
}
void CGraphics3D::SetEnvTexture(int index)
{
m_envTextureid = index;
m_envTexture = &m_pTextures[index];
}
void CGraphics3D::SetTexture(CTexture*const t)
{
m_curTexture = t;
}
void CGraphics3D::SetEye(Vector4s *v)
{
m_eye = *v;
}
void CGraphics3D::RenderFlatTriangle(Point *pPoint)
{
Point rp[3];
int j, k, m, n, l, temp;
int ymax, ymin, ymid;
int dy[3], dxy[3], dzy, startxy[3];
int duy[3], dvy[3], startuy[3], startvy[3];
int startx, endx, startu, endu, startv, endv, z;
int dux, dvx;
int mnchange;
int pos;
m_flatRendered++;
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;
}
// init calc
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;
j = SCREEN_HEIGHT;
k = 1;
if (rp[ymax].y < j <<SHIFT)
j = rp[ymax].y >>SHIFT;
if (rp[ymin].y > SHIFTVALUE)
k = ((rp[ymin].y-1) >>SHIFT) + 1;
if (k > j)
return;
if (j == k)
if (rp[ymid].y&SHIFTMASK != 0)
if ((rp[ymin].y >>SHIFT == j) && (rp[ymax].y >>SHIFT == j))
return;
// precalculation
dxy[0] = rp[ymax].x - rp[ymid].x;
dxy[1] = rp[ymid].x - rp[ymin].x;
dxy[2] = dxy[0] + dxy[1];
dy[0] = rp[ymax].y - rp[ymid].y;
dy[1] = rp[ymid].y - rp[ymin].y;
dy[2] = dy[0] + dy[1];
z = rp[ymax].z - rp[ymin].z;
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];
dzy = (z <<SHIFT2) / dy[2];
dxy[2] = (dxy[2] <<RECIPBITSHIFT) / dy[2];
duy[2] = (duy[2] <<SHIFT) / dy[2];
dvy[2] = (dvy[2] <<SHIFT) / dy[2];
l = rp[ymax].y - (j<<SHIFT);
startxy[2] = (rp[ymax].x <<RECIPBITSHIFT2) - (dxy[2] * l >>SHIFT);
z = (rp[ymax].z <<SHIFT) - (dzy * l >>SHIFT);
startuy[2] = (rp[ymax].u <<SHIFT) - duy[2] * l;
startvy[2] = (rp[ymax].v <<SHIFT) - dvy[2] * l;
startxy[0] = startuy[0] = startvy[0] = startxy[1] = startuy[1] = startvy[1] = 0;
if (j<<SHIFT >= rp[ymid].y) {
startxy[0] = rp[ymax].x <<RECIPBITSHIFT2;
startuy[0] = rp[ymax].u <<SHIFT;
startvy[0] = rp[ymax].v <<SHIFT;
if (dy[0]) {
dxy[0] = (dxy[0] <<RECIPBITSHIFT) / dy[0];
duy[0] = (duy[0] <<SHIFT) / dy[0];
dvy[0] = (dvy[0] <<SHIFT) / dy[0];
startxy[0] -= dxy[0] * l >>SHIFT;
startuy[0] -= duy[0] * l;
startvy[0] -= dvy[0] * l;
}
}
l = rp[ymid].y;
if (l >= k<<SHIFT) {
if (l <= j<<SHIFT)
l &= SHIFTMASK;
else
l -= j<<SHIFT;
startxy[1] = rp[ymid].x <<RECIPBITSHIFT2;
startuy[1] = rp[ymid].u <<SHIFT;
startvy[1] = rp[ymid].v <<SHIFT;
if (dy[1]) {
dxy[1] = (dxy[1] <<RECIPBITSHIFT) / dy[1];
duy[1] = (duy[1] <<SHIFT) / dy[1];
dvy[1] = (dvy[1] <<SHIFT) / dy[1];
startxy[1] -= dxy[1] * l >>SHIFT;
startuy[1] -= duy[1] * l;
startvy[1] -= dvy[1] * l;
}
}
startuy[0] >>= SHIFT;
startuy[1] >>= SHIFT;
startuy[2] >>= SHIFT;
startvy[0] >>= SHIFT;
startvy[1] >>= SHIFT;
startvy[2] >>= SHIFT;
// from top to bottom
while (j>=k) {
if (j<<SHIFT > rp[ymid].y)
l = 0;
else
if (j<<SHIFT < rp[ymid].y)
l = 1;
else
if (dy[1])
l = 1;
else
l = 0;
z -= dzy;
m = startxy[l] >>RECIPBITSHIFT2;
n = startxy[2] >>RECIPBITSHIFT2;
mnchange = false;
if (m > n) {
temp = m;
m = n;
n = temp;
mnchange = true;
}
if ((m > (SCREEN_WIDTH-1) << SHIFT) || (n < 0)) {
j--;
startxy[2] -= dxy[2];
startuy[2] -= duy[2];
startvy[2] -= dvy[2];
startxy[l] -= dxy[l];
startuy[l] -= duy[l];
startvy[l] -= dvy[l];
continue;
}
startx = m;
if (startx <= 0)
startx = 0;
else
startx = ((startx-1) >> SHIFT) +1;
endx = n;
if (endx > (SCREEN_WIDTH-1) << SHIFT)
endx = SCREEN_WIDTH-1;
else
endx = endx >> SHIFT;
if (startx > endx) {
j--;
startxy[2] -= dxy[2];
startuy[2] -= duy[2];
startvy[2] -= dvy[2];
startxy[l] -= dxy[l];
startuy[l] -= duy[l];
startvy[l] -= dvy[l];
continue;
}
// single point
if (startx == endx) {
pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH + startx;
temp = z>>SHIFT;
if (m_renderParam & RP_MIRROR) {
if ((m_pCurrentRenderTarget->m_pColorBuffer[pos]) && (temp > m_pCurrentRenderTarget->m_pMirrorBuffer[pos])) {
int color = m_curTexture->m_ppalData[m_curTexture->m_pData[(((startvy[l]>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startuy[l]>>SHIFT)&m_curTexture->m_mask)]];
if ((m_renderParam & RP_COLORKEY) && (color == COLORKEY));
else {
m_pCurrentRenderTarget->m_pMirrorBuffer[pos] = temp;
int r2 = RCOLOR(color);
int g2 = GCOLOR(color);
int b2 = BCOLOR(color);
color = m_pCurrentRenderTarget->m_pColorBuffer[pos];
int r = RCOLOR(color);
int g = GCOLOR(color);
int b = BCOLOR(color);
r = (r*6 + r2*2) >>3;
g = (g*6 + g2*2) >>3;
b = (b*6 + b2*2) >>3;
m_pCurrentRenderTarget->m_pColorBuffer[pos] = MAKERGB(r, g, b);
}
}
} else
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
// DrawPixel(pos, startu>>SHIFT, startv>>SHIFT);
// m_pixelWritten++;
const unsigned short ctemp = m_curTexture->m_ppalData[m_curTexture->m_pData[(((startvy[l]>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startuy[l]>>SHIFT)&m_curTexture->m_mask)]];
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
if ((m_renderParam & RP_COLORKEY) && (ctemp == COLORKEY));
else
m_pCurrentRenderTarget->m_pColorBuffer[pos] = ctemp;
}
j--;
startxy[2] -= dxy[2];
startuy[2] -= duy[2];
startvy[2] -= dvy[2];
startxy[l] -= dxy[l];
startuy[l] -= duy[l];
startvy[l] -= dvy[l];
continue;
}
// line, ignore z
if (mnchange) {
startu = startuy[2];
endu = startuy[l];
startv = startvy[2];
endv = startvy[l];
temp = (startxy[l] - startxy[2]) >>RECIPBITSHIFT2;
} else {
startu = startuy[l];
endu = startuy[2];
startv = startvy[l];
endv = startvy[2];
temp = (startxy[2] - startxy[l]) >>RECIPBITSHIFT2;
}
if (temp >= SHIFT2VALUE) {
if (startu >= endu)
dux = -((startu - endu) * recipTable[temp >>SHIFT] >>RECIPBIT);
else
dux = (endu - startu) * recipTable[temp >>SHIFT] >>RECIPBIT;
if (startv >= endv)
dvx = -((startv - endv) * recipTable[temp >>SHIFT] >>RECIPBIT);
else
dvx = (endv - startv) * recipTable[temp >>SHIFT] >>RECIPBIT;
} else {
if (startu >= endu)
dux = -((startu - endu) * recipTable[temp] >>RECIPBITSHIFT);
else
dux = (endu - startu) * recipTable[temp] >>RECIPBITSHIFT;
if (startv >= endv)
dvx = -((startv - endv) * recipTable[temp] >>RECIPBITSHIFT);
else
dvx = (endv - startv) * recipTable[temp] >>RECIPBITSHIFT;
}
startu += ((startx<<SHIFT)-m) * dux >>SHIFT;
startv += ((startx<<SHIFT)-m) * dvx >>SHIFT;
temp = z >>SHIFT;
pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH + startx;
endx = pos-startx+endx;
if (m_renderParam & RP_MIRROR) {
while (pos <= endx) {
if ((m_pCurrentRenderTarget->m_pColorBuffer[pos]) && (temp > m_pCurrentRenderTarget->m_pMirrorBuffer[pos])) {
int color = m_curTexture->m_ppalData[m_curTexture->m_pData[(((startv>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startu>>SHIFT)&m_curTexture->m_mask)]];
if ((m_renderParam & RP_COLORKEY) && (color == COLORKEY));
else {
m_pCurrentRenderTarget->m_pMirrorBuffer[pos] = temp;
int r2 = RCOLOR(color);
int g2 = GCOLOR(color);
int b2 = BCOLOR(color);
color = m_pCurrentRenderTarget->m_pColorBuffer[pos];
int r = RCOLOR(color);
int g = GCOLOR(color);
int b = BCOLOR(color);
r = (r*6 + r2*2) >>3;
g = (g*6 + g2*2) >>3;
b = (b*6 + b2*2) >>3;
m_pCurrentRenderTarget->m_pColorBuffer[pos] = MAKERGB(r, g, b);
}
}
startu += dux;
startv += dvx;
pos++;
}
} else
if (m_renderParam & RP_COLORKEY)
while (pos <= endx) {
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
const unsigned short ctemp = m_curTexture->m_ppalData[m_curTexture->m_pData[(((startv>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startu>>SHIFT)&m_curTexture->m_mask)]];
if (ctemp != COLORKEY) {
m_pCurrentRenderTarget->m_pColorBuffer[pos] = ctemp;
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
}
}
startu += dux;
startv += dvx;
pos++;
}
else
if (m_renderParam & RP_EXTENDED) {
unsigned short *pData = (unsigned short *)m_curTexture->m_pData;
while (pos <= endx) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -