📄 graphics3d.cpp
字号:
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
// DrawPixel(pos, startu>>SHIFT, startv>>SHIFT);
m_pCurrentRenderTarget->m_pColorBuffer[pos] = pData[(((startv>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startu>>SHIFT)&m_curTexture->m_mask)];
// m_pixelWritten++;
}
startu += dux;
startv += dvx;
pos++;
}
} else
while (pos <= endx) {
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
// DrawPixel(pos, startu>>SHIFT, startv>>SHIFT);
m_pCurrentRenderTarget->m_pColorBuffer[pos] = m_curTexture->m_ppalData[m_curTexture->m_pData[(((startv>>SHIFT)&m_curTexture->m_mask)<<m_curTexture->m_shift)|((startu>>SHIFT)&m_curTexture->m_mask)]];
// m_pixelWritten++;
}
startu += dux;
startv += dvx;
pos++;
}
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];
}
}
void CGraphics3D::DrawBall()
{
Vector4s vertex, rp, eye2rp, rpScreen, vertex2;
int radius, radScreen, radScreen2;
int i, j, k, mid, startx, endx, lx, rx, ny, nx, delta, ln, rn, nindex;
int u, v, r, g, b;
unsigned short color;
int temp, temp1, temp2, stemp, sstemp;
int pos;
CMatrix44 matmidworld, matworldself, matmidself;
vertex.Init(0, 0, 0);
rp = m_matTransCamera.Transform(vertex);
radius = 10;
// simple near/far cut
if (rp.z <= m_zNear+radius)
return;
temp = m_zDist * recipTable[rp.z] >>SHIFT;
rpScreen.x = (rp.x * temp >>RECIPBITSHIFT2) + (SCREEN_WIDTH>>1<<SHIFT);
rpScreen.y = (rp.y * temp >>RECIPBITSHIFT2) + (SCREEN_HEIGHT>>1<<SHIFT);
radScreen = radius * temp >>RECIPBITSHIFT2;
j = rpScreen.y + radScreen;
k = rpScreen.y - radScreen;
if (j > SCREEN_HEIGHT<<SHIFT)
j = SCREEN_HEIGHT;
else
j = j>>SHIFT;
if (k < SHIFTVALUE)
k = 1;
else
k = ((k-1) >>SHIFT) +1;
if ((j<=1) || (k>=SCREEN_HEIGHT))
return;
if (rpScreen.x + radScreen <= 0)
return;
if (rpScreen.x - radScreen >= (SCREEN_WIDTH-1)<<SHIFT)
return;
// precalculation
mid = (rpScreen.y >>SHIFT<<SHIFT) +SHIFTVALUE;
lx = rpScreen.x>>SHIFT;
rx = lx+1;
if (lx >= SCREEN_WIDTH)
lx = SCREEN_WIDTH-1;
if (rx < 0)
rx = 0;
startx = rx;
endx = lx;
radScreen2 = radScreen*radScreen;
delta = SHIFT2VALUE*RAD_FRAG/radScreen;
ny = ((j<<SHIFT2)-(rpScreen.y<<SHIFT))*RAD_FRAG/radScreen;
ln = ((rpScreen.x<<SHIFT)-(lx<<SHIFT2))*RAD_FRAG/radScreen;
rn = delta-ln;
// calculate matrix of screen_middle -> view -> world -> self
eye2rp = rp;
eye2rp.Normalize();
vertex = m_matWorld.Transform(Vector4s(0, 0, 0));
const int lcount = 3;
_light l[lcount];
if (m_onBallLight == -1)
m_onBallLight = lcount;
// init light
l[0].pos.Init(200, 500, 600);
l[1].pos.Init(200, -500, 600);
l[2].pos.Init(200, 1500, 600);
for (i=0; i<m_onBallLight; i++) {
l[i].ball2pos = l[i].pos - vertex;
l[i].dist = Abs(l[i].ball2pos.x) + Abs(l[i].ball2pos.y);
if (l[i].dist < 512)
l[i].dist = 512;
else
if (l[i].dist > 2048)
l[i].dist = 2048;
l[i].dist = (512 <<SHIFT) / l[i].dist;
l[i].ball2pos.Normalize();
l[i].vn = m_eye - vertex;
l[i].vn.Normalize();
l[i].vn += l[i].ball2pos;
l[i].vn.Normalize();
}
temp = Atan2i(eye2rp.z, eye2rp.x);
matworldself.DefRotateY(temp);
temp = FSqrt((1<<COS_SIN_SHIFT<<COS_SIN_SHIFT) - eye2rp.y * eye2rp.y, temp1);
temp = Atan2i(temp>>temp1, eye2rp.y);
matworldself.RotateX(ANGLE2PI-temp);
matmidworld = m_matView;
matmidworld.Transpose();
matmidworld.PostMultiply(&matworldself);
matworldself = m_matWorld;
matworldself.Transpose();
matmidself = matworldself;
matmidself.PostMultiply(&matmidworld);
unsigned short *pData = (unsigned short *)m_curTexture->m_pData;
unsigned short *pData2 = NULL;
if (m_envTexture)
pData2 = (unsigned short *)m_envTexture->m_pData;
// divide into upper / lower part
if (mid<SHIFTVALUE)
mid = SHIFTVALUE;
while ((j<<SHIFT)>=mid) {
// calc range
startx --;
endx ++;
temp1 = rpScreen.x - (startx<<SHIFT);
temp2 = (j<<SHIFT) -rpScreen.y;
temp2 *= temp2;
temp = temp1*temp1 + temp2;
while ((temp <= radScreen2) && (startx >= 0)) {
startx --;
temp += (temp1<<SHIFT<<1) + SHIFT2VALUE;
temp1 += SHIFTVALUE;
}
startx ++;
temp1 = (endx<<SHIFT) -rpScreen.x;
temp = temp1*temp1 + temp2;
while ((temp <= radScreen2) && (endx < SCREEN_WIDTH)) {
endx ++;
temp += (temp1<<SHIFT<<1) + SHIFT2VALUE;
temp1 += SHIFTVALUE;
}
endx --;
if (startx<0)
startx = 0;
if (endx >= SCREEN_WIDTH)
endx = SCREEN_WIDTH-1;
pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH + lx;
temp1 = pos+startx-lx;
temp = recipTable[rp.z-3];
nindex = ny>>SHIFT<<SHIFT<<5;
nx = nindex + ln;
// up left/right part
if (m_renderParam & RP_MIRROR)
while (pos >= temp1) {
if ((m_pCurrentRenderTarget->m_pColorBuffer[pos]) && (temp > m_pCurrentRenderTarget->m_pMirrorBuffer[pos])) {
m_pCurrentRenderTarget->m_pMirrorBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex.x = -vertex.x;
vertex2 = matmidself.TransformNormal(vertex);
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_curTexture->m_shift>>11;
color = m_pCurrentRenderTarget->m_pColorBuffer[pos];
r = RCOLOR(color);
g = GCOLOR(color);
b = BCOLOR(color);
color = pData[(v<<m_curTexture->m_shift)|u];
int r2 = RCOLOR(color);
int g2 = GCOLOR(color);
int b2 = 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);
}
pos --;
nx += delta;
}
else
while (pos >= temp1) {
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex.x = -vertex.x;
vertex2 = matmidworld.TransformNormal(vertex);
sstemp = 0;
for (i=0; i<m_onBallLight; i++) {
temp2 = l[i].ball2pos * vertex2>>COS_SIN_SHIFT<<SHIFT>>COS_SIN_SHIFT;
if (temp2 >= 0) {
stemp = (l[i].vn * vertex2 >>COS_SIN_SHIFT);
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = (stemp*stemp >>COS_SIN_SHIFT <<SHIFT >>COS_SIN_SHIFT) *l[i].dist >>SHIFT;
sstemp += stemp;
}
}
if (pData2) {
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_envTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_envTexture->m_shift>>11;
color = pData2[(v<<m_envTexture->m_shift)|u];
b = (BCOLOR(color)>>1) + sstemp;
g = (GCOLOR(color)>>1) + sstemp;
r = (RCOLOR(color)>>1) + sstemp;
} else
b = g = r = sstemp;
vertex = matworldself.TransformNormal(vertex2);
v = (vertex.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex.x, vertex.y)<<m_curTexture->m_shift>>11;
color = pData[(v<<m_curTexture->m_shift)|u];
b += (BCOLOR(color)>>1);
g += (GCOLOR(color)>>1);
r += (RCOLOR(color)>>1);
if (b>255)
b = 255;
if (g>255)
g = 255;
if (r>255)
r = 255;
m_pCurrentRenderTarget->m_pColorBuffer[pos] = MAKERGB(r, g, b);
}
pos --;
nx += delta;
}
// up right
pos = (SCREEN_HEIGHT-j)*SCREEN_WIDTH+rx;
temp1 = pos-rx+endx;
nx = nindex + rn;
if (m_renderParam & RP_MIRROR)
while (pos <= temp1) {
if ((m_pCurrentRenderTarget->m_pColorBuffer[pos]) && (temp > m_pCurrentRenderTarget->m_pMirrorBuffer[pos])) {
m_pCurrentRenderTarget->m_pMirrorBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex2 = matmidself.TransformNormal(vertex);
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_curTexture->m_shift>>11;
color = m_pCurrentRenderTarget->m_pColorBuffer[pos];
r = RCOLOR(color);
g = GCOLOR(color);
b = BCOLOR(color);
color = pData[(v<<m_curTexture->m_shift)|u];
int r2 = RCOLOR(color);
int g2 = GCOLOR(color);
int b2 = 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);
}
pos ++;
nx += delta;
}
else
while (pos <= temp1) {
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex2 = matmidworld.TransformNormal(vertex);
sstemp = 0;
for (i=0; i<m_onBallLight; i++) {
temp2 = l[i].ball2pos * vertex2>>COS_SIN_SHIFT<<SHIFT>>COS_SIN_SHIFT;
if (temp2 >= 0) {
stemp = (l[i].vn * vertex2 >>COS_SIN_SHIFT);
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = (stemp*stemp >>COS_SIN_SHIFT <<SHIFT >>COS_SIN_SHIFT) *l[i].dist >>SHIFT;
sstemp += stemp;
}
}
if (pData2) {
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_envTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_envTexture->m_shift>>11;
color = pData2[(v<<m_envTexture->m_shift)|u];
b = (BCOLOR(color)>>1) + sstemp;
g = (GCOLOR(color)>>1) + sstemp;
r = (RCOLOR(color)>>1) + sstemp;
} else
b = g = r = sstemp;
vertex = matworldself.TransformNormal(vertex2);
v = (vertex.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex.x, vertex.y)<<m_curTexture->m_shift>>11;
color = pData[(v<<m_curTexture->m_shift)|u];
b += (BCOLOR(color)>>1);
g += (GCOLOR(color)>>1);
r += (RCOLOR(color)>>1);
if (b>255)
b = 255;
if (g>255)
g = 255;
if (r>255)
r = 255;
m_pCurrentRenderTarget->m_pColorBuffer[pos] = MAKERGB(r, g, b);
}
pos ++;
nx += delta;
}
j--;
ny -= delta;
}
startx = rx;
endx = lx;
ny = ((rpScreen.y<<SHIFT)-(k<<SHIFT2))*RAD_FRAG/radScreen;
if (mid >= SCREEN_HEIGHT<<SHIFT)
mid = SCREEN_HEIGHT<<SHIFT;
if (k<1)
k = 1;
// bottom part
while ((k<<SHIFT)<mid) {
// calc range
startx --;
endx ++;
temp1 = rpScreen.x - (startx<<SHIFT);
temp2 = (k<<SHIFT) -rpScreen.y;
temp2 *= temp2;
temp = temp1*temp1 + temp2;
while ((temp <= radScreen2) && (startx >= 0)) {
startx --;
temp += (temp1<<SHIFT<<1) + SHIFT2VALUE;
temp1 += SHIFTVALUE;
}
startx ++;
temp1 = (endx<<SHIFT) -rpScreen.x;
temp = temp1*temp1 + temp2;
while ((temp <= radScreen2) && (endx < SCREEN_WIDTH)) {
endx ++;
temp += (temp1<<SHIFT<<1) + SHIFT2VALUE;
temp1 += SHIFTVALUE;
}
endx --;
if (startx<0)
startx = 0;
if (endx >= SCREEN_WIDTH)
endx = SCREEN_WIDTH-1;
pos = (SCREEN_HEIGHT-k)*SCREEN_WIDTH + lx;
temp1 = pos+startx-lx;
temp = recipTable[rp.z-3];
nindex = ny>>SHIFT<<SHIFT<<5;
nx = nindex + ln;
// bottom left/right part
if (m_renderParam & RP_MIRROR)
while (pos >= temp1) {
if ((m_pCurrentRenderTarget->m_pColorBuffer[pos]) && (temp > m_pCurrentRenderTarget->m_pMirrorBuffer[pos])) {
m_pCurrentRenderTarget->m_pMirrorBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex.x = -vertex.x;
vertex.y = -vertex.y;
vertex2 = matmidself.TransformNormal(vertex);
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_curTexture->m_shift>>11;
color = m_pCurrentRenderTarget->m_pColorBuffer[pos];
r = RCOLOR(color);
g = GCOLOR(color);
b = BCOLOR(color);
color = pData[(v<<m_curTexture->m_shift)|u];
int r2 = RCOLOR(color);
int g2 = GCOLOR(color);
int b2 = 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);
}
pos --;
nx += delta;
}
else
while (pos >= temp1) {
if (temp > m_pCurrentRenderTarget->m_pZBuffer[pos]) {
m_pCurrentRenderTarget->m_pZBuffer[pos] = temp;
vertex = SphereNormal[nx>>SHIFT];
vertex.x = -vertex.x;
vertex.y = -vertex.y;
vertex2 = matmidworld.TransformNormal(vertex);
sstemp = 0;
for (i=0; i<m_onBallLight; i++) {
temp2 = l[i].ball2pos * vertex2>>COS_SIN_SHIFT<<SHIFT>>COS_SIN_SHIFT;
if (temp2 >= 0) {
stemp = (l[i].vn * vertex2 >>COS_SIN_SHIFT);
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = stemp*stemp >>COS_SIN_SHIFT;
stemp = (stemp*stemp >>COS_SIN_SHIFT <<SHIFT >>COS_SIN_SHIFT) *l[i].dist >>SHIFT;
sstemp += stemp;
}
}
if (pData2) {
v = (vertex2.z+(1<<COS_SIN_SHIFT))<<m_envTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex2.x, vertex2.y)<<m_envTexture->m_shift>>11;
color = pData2[(v<<m_envTexture->m_shift)|u];
b = (BCOLOR(color)>>1) + sstemp;
g = (GCOLOR(color)>>1) + sstemp;
r = (RCOLOR(color)>>1) + sstemp;
} else
b = g = r = sstemp;
vertex = matworldself.TransformNormal(vertex2);
v = (vertex.z+(1<<COS_SIN_SHIFT))<<m_curTexture->m_shift>>COS_SIN_SHIFT>>1;
u = Atan2i(vertex.x, vertex.y)<<m_curTexture->m_shift>>11;
color = pData[(v<<m_curTexture->m_shift)|u];
b += (BCOLOR(color)>>1);
g += (GCOLOR(color)>>1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -