示例#1
0
		public static void Main (string[] args)
		{

			Device.Init (1024, 576, "Software Renderer");

			// initialize a camera with 60 degrees field of view
			// the second argument is the position of the camera (left handed)
			Camera camera = new Camera (60, new Vector3 (0, 0, -10));

			// load the storm trooper texture
			Texture stormTrooperTexture = new Texture("../../Assets/Stormtrooper.png");

			// load the stormtrooper mesh, and apply the specified texture
			Mesh stormTrooper = new Mesh ("../../Assets/Stormtrooper.obj", stormTrooperTexture);

			// scale in half
			stormTrooper.scale = new Vector3 (0.5f, 0.5f, 0.5f);
			// place y at -1 to have better view of the storm tropper
			stormTrooper.position = new Vector3 (0, -1, 0);
			// start with a 0 rotation
			stormTrooper.rotationEuler = new Vector3 (0, 0, 0);

			float z = camera.position.z;
			float y = stormTrooper.rotationEuler.y;

			while (Device.Active) {
				// red background (remember, colors are not normalized in device space)
				Device.Clear (255, 0, 0);

				// input management, we rotate the mesh with left and right, and we zoom in/out with up and down
				if (Device.GetKey (KeyCode.Right))
					y+=3;

				if (Device.GetKey (KeyCode.Left))
					y-=3;

				if (Device.GetKey (KeyCode.Up))
					z+=1;

				if (Device.GetKey (KeyCode.Down))
					z-=1;

				// set z of the camera
				camera.position = new Vector3 (0, 0, z);

				// apply rotation to the model
				stormTrooper.rotationEuler = new Vector3(0, y, 0);

				// draw the model
				stormTrooper.Draw (camera);

				// update the screen
				Device.Update ();
			}
		}
示例#2
0
		// apply perspective projection to vector using the specified camera
		public static Vector3 Project (this Vector3 v, Camera camera)
		{
			Vector3 v3;
			float angle = camera.fov / 2 * Deg2Rad;

			// 1f/tan(alpha)
			float distanceFromCamera = (float)Math.Tan (angle);

			v3.y = v.y / (distanceFromCamera * v.z);
			v3.x = v.x / (aspectRatio * distanceFromCamera * v.z);
			// hold the original z value, as it will be used by z-buffering
			v3.z = v.z;

			return v3;
		}
示例#3
0
		// draw a 3d triangle in a 2d space
		public void Draw (Camera camera)
		{

			// transform local coordinates in world coordinates
			// remember: scaling is vector multiplication, translation is vector addition
			Vector3 aWorld = this.a.coordinates.Rotate(mesh.rotationEuler) * mesh.scale + mesh.position;
			Vector3 bWorld = this.b.coordinates.Rotate(mesh.rotationEuler) * mesh.scale + mesh.position;
			Vector3 cWorld = this.c.coordinates.Rotate(mesh.rotationEuler) * mesh.scale + mesh.position;

			// apply camera trasnformations (remember they are always inverted)
			Vector3 aCamera = aWorld - (camera.position);
			Vector3 bCamera = bWorld - (camera.position);
			Vector3 cCamera = cWorld - (camera.position);

			// project 3d vertices (in camera space) on 2d surface
			this.a.projected = aCamera.Project (camera).NDCtoPixel ();
			this.b.projected = bCamera.Project (camera).NDCtoPixel ();
			this.c.projected = cCamera.Project (camera).NDCtoPixel ();


			// now we have 2d triangles, time to rasterize them
			// first step is ordering vertices from top to bottom


			// order vertices (using projected coordinates [x and y are pixels, z is a copy of the camera transformation])
			Vertex p1 = this.a;
			Vertex p2 = this.b;
			Vertex p3 = this.c;

			// we use a dumb swapping algorithm for performances
			if (p1.projected.y > p2.projected.y) {
				var tmp = p2;
				p2 = p1;
				p1 = tmp;
			}
			if (p2.projected.y > p3.projected.y) {
				var tmp = p2;
				p2 = p3;
				p3 = tmp;
			}
			if (p1.projected.y > p2.projected.y) {
				var tmp = p2;
				p2 = p1;
				p1 = tmp;
			}
				
			// find slopes of the triangle edges, it is required to understand if P2 is on the left or on the right
			float slopeP1P2 = (p2.projected.x - p1.projected.x) / (p2.projected.y - p1.projected.y);
			float slopeP1P3 = (p3.projected.x - p1.projected.x) / (p3.projected.y - p1.projected.y);

			// iterate y from p1 to p3
			for (int y = (int)p1.projected.y; y <= (int)p3.projected.y; y++) {
				// p2 on the left
				if (slopeP1P3 > slopeP1P2) {
					if (y < p2.projected.y) {
						Device.ScanLine (y, p1, p2, p1, p3, mesh.texture);
					} else {
						Device.ScanLine (y, p2, p3, p1, p3, mesh.texture);
					}
				} else {

					//p2 on the right
					if (y < p2.projected.y) {
						Device.ScanLine (y, p1, p3, p1, p2, mesh.texture);
					} else {
						Device.ScanLine (y, p1, p3, p2, p3, mesh.texture);
					}
				}
			}

		}
示例#4
0
		public void Draw (Camera camera)
		{
			foreach (Triangle face in this.faces) {
				face.Draw (camera);
			}
		}