예제 #1
0
파일: Camera.c 프로젝트: 5432935/genesis3d
//========================================================================================
//	geCamera_ScreenPointToWorld
//========================================================================================
GENESISAPI void GENESISCC geCamera_ScreenPointToWorld (	const geCamera	*Camera,
														int32			 ScreenX,
														int32			 ScreenY,
														geVec3d			*Vector)
// Takes a screen X and Y pair, and a camera and generates a vector pointing
// in the direction from the camera position to the screen point.
{
	geVec3d In,Left,Up;
	geVec3d ScaledIn,ScaledLeft,ScaledUp ;
	geFloat	XCenter ;
	geFloat	YCenter ;
	geFloat	Scale ;
	const geXForm3d *pM;

	pM = &(Camera->TransposeXForm);
	XCenter = Camera->XCenter ;
	YCenter = Camera->YCenter ;
	Scale   = Camera->Scale ;

	geXForm3d_GetIn( pM, &In ) ;
	geXForm3d_GetLeft( pM, &Left ) ;
	geXForm3d_GetUp( pM, &Up ) ;
	
	geVec3d_Scale(&In,   Scale, &ScaledIn);
	geVec3d_Scale(&Left, XCenter - ((geFloat)ScreenX), &ScaledLeft );
	geVec3d_Scale(&Up,   YCenter - ((geFloat)ScreenY), &ScaledUp   );

	geVec3d_Copy(&ScaledIn, Vector);
	geVec3d_Add(Vector,		&ScaledLeft,	Vector );
	geVec3d_Add(Vector,		&ScaledUp,		Vector );
	geVec3d_Normalize(Vector);
}
예제 #2
0
//=====================================================================================
//	RenderTexturedPoint
//=====================================================================================
static geBoolean RenderTexturedPoint(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera)
{
	assert(geWorld_PolyIsValid(Poly));

	if (MirrorRecursion > 0)
	{
		GE_LVertex		*pVerts, Save;
		geVec3d			Up, Left, Start;
		geFloat			Scale, XScale, YScale;
		const geXForm3d	*MXForm;

		pVerts = Poly->Verts;

		Poly->NumVerts = 4;

		Start.X = pVerts[0].X;
		Start.Y = pVerts[0].Y;
		Start.Z = pVerts[0].Z;

		Save = pVerts[1] = pVerts[2] = pVerts[3] = pVerts[0];

		MXForm = geCamera_GetWorldSpaceXForm(Camera);

		geXForm3d_GetLeft(MXForm, &Left);
		geXForm3d_GetUp(MXForm, &Up);

		Scale = Poly->Scale * 0.5f;

		XScale = (geFloat)geBitmap_Width(Poly->Bitmap) * Scale;
		YScale = (geFloat)geBitmap_Height(Poly->Bitmap) * Scale;

		geVec3d_Scale(&Left, XScale, &Left);
		geVec3d_Scale(&Up, YScale, &Up);

		pVerts->X = Start.X - Left.X + Up.X;
		pVerts->Y = Start.Y - Left.Y + Up.Y;
		pVerts->Z = Start.Z - Left.Z + Up.Z;
		pVerts->u = 0.0f;
		pVerts->v = 0.0f;

		pVerts++;
	
		pVerts->X = Start.X + Left.X + Up.X;
		pVerts->Y = Start.Y + Left.Y + Up.Y;
		pVerts->Z = Start.Z + Left.Z + Up.Z;
		pVerts->u = 1.0f;
		pVerts->v = 0.0f;
	
		pVerts++;
	
		pVerts->X = Start.X + Left.X - Up.X;
		pVerts->Y = Start.Y + Left.Y - Up.Y;
		pVerts->Z = Start.Z + Left.Z - Up.Z;
		pVerts->u = 1.0f;
		pVerts->v = 1.0f;

		pVerts++;
	
		pVerts->X = Start.X - Left.X - Up.X;
		pVerts->Y = Start.Y - Left.Y - Up.Y;
		pVerts->Z = Start.Z - Left.Z - Up.Z;
		pVerts->u = 1.0f;
		pVerts->v = 0.0f;

		RenderTexturedPoly(RDriver, Poly, FInfo, Camera);

		Poly->NumVerts = 1;		// Restore the poly
		Poly->Verts[0] = Save;
	}
	else
	{
		//GFX_Plane		*Planes;
		geVec3d			Src, Dest;
		GE_LVertex		*pVerts;
		DRV_TLVertex	ScreenPnts[4];
		geBitmap		*Bitmap;
		geFloat			Sx, Sy, z, UVAdd, Width, Height;
		geFloat			Left, Right, Top, Bottom;
		geFloat			Scale;
		uint32			RenderFlags;
		int32			i;
		
		assert(Poly != NULL);
		assert(Camera != NULL);

		pVerts = &Poly->Verts[0];
	
		// Xform the point 
		Src.X = pVerts->X;
		Src.Y = pVerts->Y;
		Src.Z = pVerts->Z;

		geCamera_Transform(Camera,&Src,&Dest);

		geCamera_Project(Camera, &Dest, &Src);

		for (i=0; i<4; i++)
		{
			ScreenPnts[i].x = Src.X;
			ScreenPnts[i].y = Src.Y;
			ScreenPnts[i].z = Src.Z;
			ScreenPnts[i].r = pVerts->r;
			ScreenPnts[i].g = pVerts->g;
			ScreenPnts[i].b = pVerts->b;
			ScreenPnts[i].a = pVerts->a;
		}
	
		z = -Dest.Z;

		if (z < 1)
			return GE_TRUE;

		{
			geRect Rect;
			geCamera_GetClippingRect(Camera,&Rect);

			Left   = (geFloat)Rect.Left;
			Right  = (geFloat)Rect.Right+1.0f;
			Top    = (geFloat)Rect.Top;
			Bottom = (geFloat)Rect.Bottom+1.0f;
		}

		Scale = ((geCamera_GetScale(Camera) / z) * Poly->Scale);

		Bitmap = Poly->Bitmap;
		Width = (geFloat)geBitmap_Width(Bitmap) * Scale;
		Height = (geFloat)geBitmap_Height(Bitmap) * Scale;

		Sx = Width * 0.5f;
		Sy = Height * 0.5f;

		// Build the screen poly from the point
		ScreenPnts[0].x -= Sx;
		ScreenPnts[0].y -= Sy;

		ScreenPnts[1].x += Sx;
		ScreenPnts[1].y -= Sy;

		ScreenPnts[2].x += Sx;
		ScreenPnts[2].y += Sy;

		ScreenPnts[3].x -= Sx;
		ScreenPnts[3].y += Sy;

		ScreenPnts[0].u = 0.0f + pVerts->u;
		ScreenPnts[0].v = 0.0f + pVerts->v;
		ScreenPnts[1].u = 1.0f + pVerts->u;
		ScreenPnts[1].v = 0.0f + pVerts->v;
		ScreenPnts[2].u = 1.0f + pVerts->u;
		ScreenPnts[2].v = 1.0f + pVerts->v;
		ScreenPnts[3].u = 0.0f + pVerts->u;
		ScreenPnts[3].v = 1.0f + pVerts->v;

		// Now, clip it against the 2d camera viewport
		if (ScreenPnts[0].x < Left)
		{
			if (ScreenPnts[1].x <= Left)
				return GE_TRUE;

			UVAdd = (Left-ScreenPnts[0].x) / Width;
			Width -= Left-ScreenPnts[0].x;
		
			ScreenPnts[0].u += UVAdd;
			ScreenPnts[3].u += UVAdd;

			ScreenPnts[0].x = Left;
			ScreenPnts[3].x = Left;
		}
		if (ScreenPnts[0].y < Top)
		{
			if (ScreenPnts[2].y <= Top)
				return GE_TRUE;

			UVAdd = (Top-ScreenPnts[0].y) / Height;
			Height -= (Top-ScreenPnts[0].y);
		
			ScreenPnts[0].v += UVAdd;
			ScreenPnts[1].v += UVAdd;

			ScreenPnts[0].y = Top;
			ScreenPnts[1].y = Top;
		}
		if (ScreenPnts[1].x >= Right)
		{
			if (ScreenPnts[0].x >= Right)
				return GE_TRUE;
	
			UVAdd = (ScreenPnts[1].x-Right) / Width;
			Width -= (ScreenPnts[1].x-Right);
		
			ScreenPnts[1].u -= UVAdd;
			ScreenPnts[2].u -= UVAdd;
		
			ScreenPnts[1].x	= Right-1;
			ScreenPnts[2].x	= Right-1;
		}
		if (ScreenPnts[2].y >= Bottom)
		{
			if (ScreenPnts[0].y >= Bottom)
				return GE_TRUE;

			UVAdd = (ScreenPnts[2].y-Bottom) / Height;
			Height -= (ScreenPnts[2].x-Bottom);
		
			ScreenPnts[2].v -= UVAdd;
			ScreenPnts[3].v -= UVAdd;

			ScreenPnts[2].y	= Bottom-1;
			ScreenPnts[3].y	= Bottom-1;
		}

		// Lastly, render it...
		ScreenPnts[0].a = pVerts->a;
		// Fixed bug where i fogot to set RGB's...
		ScreenPnts[0].r = pVerts->r;
		ScreenPnts[0].g = pVerts->g;
		ScreenPnts[0].b = pVerts->b;

		if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_OTHERS)
			RenderFlags = DRV_RENDER_NO_ZWRITE;
		else
			RenderFlags = 0;

		if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_SELF)
			RenderFlags |= DRV_RENDER_NO_ZMASK;

		if (pVerts->a != 255.0f)
			RenderFlags |= DRV_RENDER_ALPHA;

/* 01/30/2003 Wendell Buckner 
     Driver render flush is probably causing a slow down! */
		if (Poly->RenderFlags & GE_RENDER_DEPTH_SORT_BF)    
			RenderFlags |= DRV_RENDER_FLUSH;                 

		if (Poly->RenderFlags & GE_RENDER_CLAMP_UV)
			RenderFlags |= DRV_RENDER_CLAMP_UV;

		if (Poly->RenderFlags & GE_RENDER_NO_FOG) // skybox fog
			RenderFlags |= DRV_RENDER_POLY_NO_FOG;


		assert(geWorld_HasBitmap(gWorld, Bitmap));
		assert(geBitmap_GetTHandle(Bitmap));

/* 08/08/2004 Wendell Buckner
     BUG FIX: Allways call geBitmap_SetRenderFlags() before calling a textured rendering function(for embm, dot3, & etc...). */
		geBitmap_SetRenderFlags(Bitmap, &RenderFlags);

		RDriver->RenderMiscTexturePoly((DRV_TLVertex*)ScreenPnts, 4, geBitmap_GetTHandle(Bitmap), RenderFlags);
	}

	return GE_TRUE;
}