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

📄 graphics3d.cpp

📁 liu7788414
💻 CPP
📖 第 1 页 / 共 5 页
字号:
							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 + -