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

📄 render.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:

static void	DrawScanLine64_ZBuf(SizeInfo *pSizeInfo,
				  Gradients const *pGradients,
				  EdgeAsm *pLeft,
				  EdgeAsm *pRight);

static void	DrawScanLine32_ZBuf(SizeInfo *pSizeInfo,
				  Gradients const *pGradients,
				  EdgeAsm *pLeft,
				  EdgeAsm *pRight);

static void	DrawScanLine16_ZBuf(SizeInfo *pSizeInfo,
				  Gradients const *pGradients,
				  EdgeAsm *pLeft,
				  EdgeAsm *pRight);

void Render_BackRotateVector(ViewVars *Cam, geVec3d *pin, geVec3d *pout)
{
	pout->X=(pin->X*Cam->Vright.X)+(pin->Y*Cam->Vup.X)+(pin->Z*Cam->Vpn.X);
	pout->Y=(pin->X*Cam->Vright.Y)+(pin->Y*Cam->Vup.Y)+(pin->Z*Cam->Vpn.Y);
	pout->Z=(pin->X*Cam->Vright.Z)+(pin->Y*Cam->Vup.Z)+(pin->Z*Cam->Vpn.Z);
}

void MConcat(geFloat in1[3][3], geFloat in2[3][3], geFloat out[3][3])
{
	int     i, j;
	for(i=0 ; i<3 ; i++) {
		for (j=0 ; j<3 ; j++) {
			out[i][j] = in1[i][0] * in2[0][j] +
				in1[i][1] * in2[1][j] +
				in1[i][2] * in2[2][j];
		}
	}
}

void MIdent(geFloat in[3][3])
{
	in[0][0]=1;	in[0][1]=0;	in[0][2]=0;
	in[1][0]=0;	in[1][1]=1;	in[1][2]=0;
	in[2][0]=0;	in[2][1]=0;	in[2][2]=1;
}

void ClearEdgeLists(ViewVars *v)
{
	int i;

	for(i=0;i < v->Height;i++)
	{
		v->NewEdges[i].pnext	=&MaxEdge;
		v->RemoveEdges[i]		=NULL;
	}
	for(i=0;i < v->FacesDone;i++)
	{
		SpanFaces[i].cur	=NULL;
		SpanFaces[i].head	=NULL;
	}
	v->FacesDone	=0;
}

void	Render_UpdateViewPos(ViewVars *v)
{
    geFloat	s, c, mtemp1[3][3], mtemp2[3][3];
	long	i;

	s			=(geFloat)sin(-v->yaw);
	c			=(geFloat)cos(-v->yaw);
	mYaw[0][0]	=c;
	mYaw[0][2]	=-s;
	mYaw[2][0]	=s;
	mYaw[2][2]	=c;

	s			=(geFloat)sin(v->pitch);
	c			=(geFloat)cos(v->pitch);
	mPitch[1][1]=c;
	mPitch[1][2]=s;
	mPitch[2][1]=-s;
	mPitch[2][2]=c;

	s			=(geFloat)sin(v->roll);
	c			=(geFloat)cos(v->roll);
	mRoll[0][0] =-c;
	mRoll[0][1] =-s;
	mRoll[1][0] =s;
	mRoll[1][1] =-c;

	MConcat(mRoll, mYaw, mtemp1);
	MConcat(mPitch, mtemp1, mtemp2);

	for(i=0;i<3;i++)
	{
		VectorToSUB(v->Vright, i)	=mtemp2[0][i];
		VectorToSUB(v->Vup, i)		=mtemp2[1][i];
		VectorToSUB(v->Vpn, i)		=mtemp2[2][i];
	}

	geVec3d_Normalize(&v->Vright);
	geVec3d_Normalize(&v->Vpn);
	geVec3d_Normalize(&v->Vup);
}

geFloat	RayDist;
Node	*RayNode;

void	Render_SetUpFrustum(ViewVars *v)
{
	geFloat	angle, s, c;
	geVec3d	n;

	angle	=(geFloat)atan(2.0f / v->FieldOfView * v->MaxScale / v->XScreenScale);
	s		=(geFloat)sin(angle);
	c		=(geFloat)cos(angle);

	//Left clip plane
	n.X	=s;
	n.Y	=0;
	n.Z	=c;
	geVec3d_Normalize(&n);
	Render_BackRotateVector(v, &n, &v->FrustPlanes[0].Normal);
	v->FrustPlanes[0].Dist	=geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[0].Normal)+CLIP_PLANE_EPSILON;
	
	// Right clip plane
	n.X	=-s;
	geVec3d_Normalize(&n);
	Render_BackRotateVector(v, &n, &v->FrustPlanes[1].Normal);
	v->FrustPlanes[1].Dist	=geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[1].Normal)+CLIP_PLANE_EPSILON;

	angle	=(geFloat)atan(2.0f / v->FieldOfView * v->MaxScale / v->YScreenScale);
	s		=(geFloat)sin(angle);
	c		=(geFloat)cos(angle);

	// Bottom clip plane
	n.X	=0;
	n.Y	=s;
	n.Z	=c;
	geVec3d_Normalize(&n);
	Render_BackRotateVector(v, &n, &v->FrustPlanes[2].Normal);
	v->FrustPlanes[2].Dist	=geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[2].Normal)+CLIP_PLANE_EPSILON;
	
	// Top clip plane
	n.Y	=-s;
	geVec3d_Normalize(&n);
	Render_BackRotateVector(v, &n, &v->FrustPlanes[3].Normal);
	v->FrustPlanes[3].Dist	=geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[3].Normal)+CLIP_PLANE_EPSILON;
}

int ClipToPlane(RenderFace *pin, Plane *pplane, RenderFace *pout)
{
	int		i, j, nextvert, curin, nextin;
	geFloat	curdot, nextdot, scale;
	geVec3d	*pinvert, *poutvert;
	
	pinvert	=pin->Points;
	poutvert=pout->Points;
	curdot	=geVec3d_DotProduct(&pin->Points[0], &pplane->Normal);
	curin	=(curdot >= pplane->Dist);

	for(i=0;i < pin->NumPoints;i++)
	{
		nextvert=(i+1) % pin->NumPoints;
		if(curin)
		{
			geVec3d_Copy(pinvert, poutvert);
			poutvert++;
		}
		nextdot	=geVec3d_DotProduct(&pin->Points[nextvert], &pplane->Normal);
		nextin	=(nextdot >= pplane->Dist);
		if(curin != nextin)
		{
			scale	=(pplane->Dist - curdot)/(nextdot-curdot);

			for(j=0;j<3;j++)
			{
				VectorToSUB(*poutvert, j)	=VectorToSUB(*pinvert, j)+
					((VectorToSUB(pin->Points[nextvert], j) - VectorToSUB(*pinvert, j))*scale);
			}

			poutvert++;
		}
		curdot	=nextdot;
		curin	=nextin;
		pinvert++;
	}
	pout->NumPoints=poutvert-pout->Points;
	if(pout->NumPoints >= 32 || pout->NumPoints < 3)
		return 0;
	else
		return 1;
}

int ClipToFrustum(Face *pin, RenderFace *pout, ViewVars *v)
{
	RenderFace	poly, cpoly;

	poly.NumPoints	=Face_GetNumPoints(pin);
	memcpy(poly.Points, Face_GetPoints(pin), sizeof(geVec3d)*poly.NumPoints);

	if(!ClipToPlane(&poly, &v->FrustPlanes[0], &cpoly)) return 0;
	if(!ClipToPlane(&cpoly, &v->FrustPlanes[1], &poly)) return 0;
	if(!ClipToPlane(&poly, &v->FrustPlanes[2], &cpoly)) return 0;
	if(!ClipToPlane(&cpoly, &v->FrustPlanes[3], pout)) return 0;
	return -1;
}

geVec3d Render_XFormVert(const ViewVars *v, const geVec3d *pin)
{
	geVec3d	out, work;
	geFloat	zinv;

	geVec3d_Subtract(pin, &v->CamPos, &work);

	out.X	=geVec3d_DotProduct(&work, &v->Vright);
	out.Y	=geVec3d_DotProduct(&work, &v->Vup);
	out.Z	=geVec3d_DotProduct(&work, &v->Vpn);

	zinv	=1.0f/out.Z;

//	out.X	=(out.X * zinv * v->MaxScale + v->XCenter);
//	out.X	=(out.X * zinv * v->MaxScale + v->XCenter);
	out.X	=(v->XCenter -(out.X * zinv * v->MaxScale));
	out.Y	=(v->YCenter -(out.Y * zinv * v->MaxScale));

	return	out;
}

void Render_ResizeView (ViewVars *v, long vx, long vy)
{
	HDC			ViewDC;

	vx=(vx+3)&~3;	//Align scan delta

	if(vx && vy)
	{
		if(v->Flags & DIBDONE)
		{
			DeleteObject(v->hDibSec);
			geRam_Free (v->pZBuffer);
		}
		else
			v->Flags|=DIBDONE;

		//Force top-down 8-bit bitmap of size WINDOW_WIDTH*WINDOW_HEIGHT.
		v->ViewBMI.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
		v->ViewBMI.bmiHeader.biPlanes       = 1;
		v->ViewBMI.bmiHeader.biBitCount     = 16;
		v->ViewBMI.bmiHeader.biCompression  = BI_RGB;
		v->ViewBMI.bmiHeader.biSizeImage    = 0;
		v->ViewBMI.bmiHeader.biClrUsed      = 0;
		v->ViewBMI.bmiHeader.biClrImportant = 0;
		v->ViewBMI.bmiHeader.biWidth        = vx;
		v->ViewBMI.bmiHeader.biHeight       = -vy;    // Minus for top-down.

		ViewDC=CreateCompatibleDC(NULL);
		assert(ViewDC);

		v->hDibSec=CreateDIBSection(ViewDC, (BITMAPINFO *)&v->ViewBMI, DIB_RGB_COLORS, (void **)&v->pBits, NULL, 0);
		assert(v->hDibSec);

		DeleteDC(ViewDC);

		//allocate a 32 bit zbuffer
		v->pZBuffer	=(uint32 *)	geRam_Allocate(sizeof(uint32) * (vx*vy));
	}

	v->FieldOfView		=2.0f;	//fixed for now?
	v->XScreenScale		=((geFloat)vx) / v->FieldOfView;
	v->YScreenScale		=((geFloat)vy) / v->FieldOfView;
	v->MaxScale			=max(v->XScreenScale, v->YScreenScale);
	v->MaxScreenScaleInv=1.0f / v->MaxScale;
	v->XCenter			=((geFloat)vx) / 2.0f - 0.5f;
	v->YCenter			=((geFloat)vy) / 2.0f - 0.5f;

	if(v->ViewType < VIEWTOP)
	{
		if(v->NewEdges)
			geRam_Free (v->NewEdges);
		if(v->RemoveEdges)
			geRam_Free (v->RemoveEdges);

		v->NewEdges			=(Edge *)geRam_Allocate(vy*sizeof(Edge));
		v->RemoveEdges		=(Edge **)geRam_Allocate(vy*sizeof(Edge *));
	}
	v->Width			=vx;
	v->Height			=vy;
}

void Render_ResetSettings(ViewVars *v, long vx, long vy)
{
	Render_ResizeView (v, vx, vy);

	// Compute and set zoom factor
	Render_SetZoom (v, (v->Width / 640.0f));

	geVec3d_Clear (&v->Vpn);
	geVec3d_Clear (&v->Vright);
	geVec3d_Clear (&v->Vup);

	v->roll = 0.0f;
	v->pitch	=M_PI;
	v->yaw	=0.0f;

	mRoll[0][0]=1;  mRoll[0][1]=0;  mRoll[0][2]=0;
	mRoll[1][0]=0;  mRoll[1][1]=1;  mRoll[1][2]=0;
	mRoll[2][0]=0;	mRoll[2][1]=0;  mRoll[2][2]=1;
	mPitch[0][0]=1; mPitch[0][1]=0;	mPitch[0][2]=0;
	mPitch[1][0]=0; mPitch[1][1]=1; mPitch[1][2]=0;
	mPitch[2][0]=0; mPitch[2][1]=0; mPitch[2][2]=1;
	mYaw[0][0]=1;	mYaw[0][1]=0;	mYaw[0][2]=0;
	mYaw[1][0]=0;	mYaw[1][1]=1;	mYaw[1][2]=0;
	mYaw[2][0]=0;	mYaw[2][1]=0;	mYaw[2][2]=1;

	geVec3d_Clear (&v->CamPos);
}

static void AddNodeEdges(Face *NodeFace,	//node face
						 const Face *OGFace,//original brush face
						 RenderFace *sf,	//screenspace clipped
						 RenderFace *sfnc,	//screenspace unclipped
						 uint32 Key,		//bspsortkey
						 ViewVars *Cam,		//viewvars
						 int RFlags);		//render flags

static void ScanEdges(ViewVars *);
static void DrawSpans(ViewVars *, HDC);

static POINT plist[64];

/*
void Render_RenderTreeOrtho(ViewVars *Cam, Node *n, HDC ViewDC)
{
	int32	i, j;

	if(!n)
		return;

	Render_RenderTreeOrtho(Cam, n->Front, ViewDC);
	Render_RenderTreeOrtho(Cam, n->Back, ViewDC);

	for(i=0;i < n->NumFaces;i++)
	{
		if((n->Flags & CLIPPEDOUT) || (n->Faces[i].Flags & INSOLID))
			continue;

		for(j=0;j < n->Faces[i].NumPoints;j++)
		{
			plist[j]	=Render_OrthoWorldToView(Cam, &n->Faces[i].Points[j]);
		}
		plist[j]	=Render_OrthoWorldToView(Cam, &n->Faces[i].Points[0]);
		Polyline(ViewDC, plist, j+1);
	}
}

void Render_RenderTreeHollowOrtho(ViewVars *Cam, Node *n, HDC ViewDC)
{
	int32	i, j;

	if(!n)
		return;

	Render_RenderTreeHollowOrtho(Cam, n->Front, ViewDC);
	Render_RenderTreeHollowOrtho(Cam, n->Back, ViewDC);

//	if(TexInf[n->TexId].Brush->bd.Flags & HOLLOW)
	{
		for(i=0;i < n->NumFaces;i++)
		{
			if((n->Flags & CLIPPEDOUT) || (n->Faces[i].Flags & INSOLID))
				continue;

			for(j=0;j < n->Faces[i].NumPoints;j++)
			{
				plist[j]	=Render_OrthoWorldToView(Cam, &n->Faces[i].Points[j]);
			}
			plist[j]	=Render_OrthoWorldToView(Cam, &n->Faces[i].Points[0]);
			Polyline(ViewDC, plist, j+1);
		}
	}
}
*/
void Render_RenderBrushFacesOrtho( const ViewVars *Cam, Brush *b, HDC ViewDC)
{
	int	i, j;

	assert (b != NULL);

	for(i=0;i < Brush_GetNumFaces(b);i++)
	{
		Face			*f		=Brush_GetFace(b, i);
		const geVec3d	*pnts	=Face_GetPoints(f);
		for(j=0;j < Face_GetNumPoints(f);j++)
		{
			plist[j]	=Render_OrthoWorldToView(Cam, &pnts[j]);
		}
		plist[j]	=plist[0]; //Render_OrthoWorldToView(Cam, &b->Faces[i].Points[0]);
		Polyline(ViewDC, plist, j+1);
	}
}

static void Render_RenderOneBrushFaceZBuffer (ViewVars *Cam, RenderFace *pFace, uint32 LineColor)
{
	int j;
	RenderFace Clipped;

	for(j=0;j < pFace->NumPoints;j++)
	{
		Clipped.Points[j]	=Render_XFormVert(Cam, &pFace->Points[j]);
	}
	for(j=0;j < pFace->NumPoints;j++)
	{
		int	k				=(j+1) % pFace->NumPoints;

		Render_LineZBuffer( Units_Round(Clipped.Points[j].X),
							Units_Round(Clipped.Points[j].Y),
							Clipped.Points[j].Z,
							Units_Round(Clipped.Points[k].X),
							Units_Round(Clipped.Points[k].Y),
							Clipped.Points[k].Z,
							((uint16)(((LineColor & 0xf8)<<7) | ((LineColor & 0xf800)>>6) | ((LineColor & 0xf80000)>>19)))
							, Cam);
	}

}

static void Render_RenderOneBrushFace (ViewVars *Cam, RenderFace *pFace, uint32 LineColor)
{
	int j;
	RenderFace Clipped;

	for(j=0;j < pFace->NumPoints;j++)
	{
		Clipped.Points[j]	=Render_XFormVert(Cam, &pFace->Points[j]);
	}
	for(j=0;j < pFace->NumPoints;j++)
	{
		int	k				=(j+1) % pFace->NumPoints;

		Render_Line 
		(
			Units_Round(Clipped.Points[j].X),
			Units_Round(Clipped.Points[j].Y),
			Units_Round(Clipped.Points[k].X),
			Units_Round(Clipped.Points[k].Y),
			((uint16)(((LineColor & 0xf8)<<7) | ((LineColor & 0xf800)>>6) | ((LineColor & 0xf80000)>>19))),
			Cam
		);
	}

}

void Render_RenderBrushFaces(ViewVars *Cam, Brush *b, uint32 LineColor)
{
	int	i;
	RenderFace	TempFace;

	if(!b)
		return;

	for(i=0;i < Brush_GetNumFaces(b);i++)
	{
		Face	*f	=Brush_GetFace(b, i);
		if(ClipToFrustum(f, &TempFace, Cam))
		{
			Render_RenderOneBrushFace (Cam, &TempFace, LineColor);
		}
	}
}

void Render_RenderBrushSelFaces(ViewVars *Cam, Brush *b, uint32 LineColor)
{
	int	i;
	RenderFace	TempFace;

	if(!b)
		return;

	for(i=0;i < Brush_GetNumFaces(b);i++)
	{
		Face	*f	=Brush_GetFace(b, i);

		if(!Face_IsSelected(f))
			continue;

		if(ClipToFrustum(f, &TempFace, Cam))
		{
			Render_RenderOneBrushFace (Cam, &TempFace, LineColor);
		}
	}
}

void Render_RenderBrushFacesZBuffer(ViewVars *Cam, Brush *b, uint32 LineColor)
{
	int			i;
	RenderFace	TempFace;

	if(!b)
		return;

	for(i=0;i < Brush_GetNumFaces(b);i++)
	{
		Face	*f	=Brush_GetFace(b, i);
		if(ClipToFrustum(f, &TempFace, Cam))
		{
			Render_RenderOneBrushFaceZBuffer (Cam, &TempFace, LineColor);
		}
	}
}


void	Render_3DTextureZBuffer(ViewVars *Cam, const geVec3d *pos, const geBitmap *bmap)
{
	int		x, y, i, Width, Height;
	int		xroll, yroll;
	int		sx, sy, ex, ey;
	geVec3d	cpos;
	uint16	*src;
	uint16	*dst;
	uint32	*zbuf, zval;
	geVec3d box[8];
	geFloat	x0, x1, y0, y1, z0, z1;
	int		dxi, dxf, dyi, dyf, xacc;

//	geBitmap_Palette	*bpal;
//	WORD WorkingPalette[256];

	//get the center position on the screen		
	float xPlus8  = (float)(pos->X + 8.0);
	float xMinus8 = (float)(pos->X - 8.0);
	float yPlus8  = (float)(pos->Y + 8.0);
	float yMinus8 = (float)(pos->Y - 8.0);
	float zPlus8  = (float)(pos->Z + 8.0);
	float zMinus8 = (float)(pos->Z - 8.0);

	geBitmap *LockedBitmap;

	x0=y0=z0	=99999.0f;
	x1=y1=z1	=-99999.0f;

	{
		geBitmap_Info info, info2;

		geBitmap_GetInfo (bmap, &info, &info2);
		Width = info.Width;
		Height = info.Height;
	}
//	Width	=Bitmap_GetWidth(bmap);
//	Height	=Bitmap_GetHeight(bmap);

	geVec3d_Set (&box[0], xPlus8,  yPlus8,  zPlus8);
	geVec3d_Set (&box[1], xMinus8, yPlus8,  zPlus8);
	geVec3d_Set (&box[2], xMinus8, yMinus8, zPlus8);
	geVec3d_Set (&box[3], xPlus8,  yMinus8, zPlus8);
	geVec3d_Set (&box[4], xPlus8,  yPlus8,  zMinus8);
	geVec3d_Set (&box[5], xMinus8, yPlus8,  zMinus8);
	geVec3d_Set (&box[6], xMinus8, yMinus8, zMinus8);
	geVec3d_Set (&box[7], xPlus8,  yMinus8, zMinus8);
	for(i=0;i < 8;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -