示例#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
		// rasterization procedure
		public static void ScanLine (int y, Vertex vertexLeftTop, Vertex vertexLeftBottom, Vertex vertexRightTop, Vertex vertexRightBottom, Texture texture)
		{
			// assumes a flat triangle
			float gradientLeft = 1;
			float gradientRight = 1;

			// non flat triangle ?
			if (vertexLeftTop.projected.y != vertexLeftBottom.projected.y) {
				gradientLeft = (y - vertexLeftTop.projected.y) / (vertexLeftBottom.projected.y - vertexLeftTop.projected.y);
			}

			if (vertexRightTop.projected.y != vertexRightBottom.projected.y) {
				gradientRight = (y - vertexRightTop.projected.y) / (vertexRightBottom.projected.y - vertexRightTop.projected.y);
			}

			// find x start position and end position using the y gradient
			int left = (int)vertexLeftTop.projected.x.Interpolate (vertexLeftBottom.projected.x, gradientLeft);
			int right = (int)vertexRightTop.projected.x.Interpolate (vertexRightBottom.projected.x, gradientRight);

			// find the z start and value using the same interpolation
			float zStart = vertexLeftTop.projected.z.Interpolate (vertexLeftBottom.projected.z, gradientLeft);
			float zEnd = vertexRightTop.projected.z.Interpolate (vertexRightBottom.projected.z, gradientRight);

			// get U start and end
			float uStart = vertexLeftTop.uv.x.Interpolate (vertexLeftBottom.uv.x, gradientLeft);
			float uEnd = vertexRightTop.uv.x.Interpolate (vertexRightBottom.uv.x, gradientRight);

			// get V start and end
			float vStart = vertexLeftTop.uv.y.Interpolate (vertexLeftBottom.uv.y, gradientLeft);
			float vEnd = vertexRightTop.uv.y.Interpolate (vertexRightBottom.uv.y, gradientRight);


			for (int x = left; x < right; x++) {

				// while we do not need interpolation for horizontal pixels
				// we need it for texturing and for getting correct z value
				// zGradient name can be a bit misleading, as it will be used for UV's too
				float zGradient = ((float)x - (float)left) / ((float)right - (float)left);

				// get the z value using interpolation
				float z = zStart.Interpolate (zEnd, zGradient);

				// find texture uv coordinates using interpolation
				// we can resue the zGradient
				float u = uStart.Interpolate (uEnd, zGradient);
				float v = vStart.Interpolate (vEnd, zGradient);

				// get texture pixel color using UV system
				// note the (1f - v), it is required as V coordinate is reversed (0 on bottom, 1 on top)
				Vector3 color = texture.Map (u, 1f - v);

				// write pixel on the device, de-normalizing colors
				PutPixel (x, (int)y, z,
					(byte)(color.x * 255),
					(byte)(color.y * 255),
					(byte)(color.z * 255));
			}

		}
示例#3
0
		public Mesh (string fileName, Texture texture)
		{

			this.position = Vector3.zero;
			this.rotationEuler = Vector3.zero;
			// initialize with default scaling
			this.scale = new Vector3(1, 1, 1);

			this.vertices = new List<Vector3> ();
			this.uvs = new List<Vector2> ();
			this.normals = new List<Vector3> ();
			this.faces = new List<Triangle> ();

			this.texture = texture;

			using (StreamReader reader = new StreamReader (fileName)) {
				
				while (true) {
					string line = reader.ReadLine ();
					if (line == null)
						break;

					// manage vertices
					if (line.StartsWith ("v ")) {
						string[] items = line.Split (' ');
						// check for right handed and left handed !!!
						this.vertices.Add (new Vector3 (
							float.Parse (items [1], CultureInfo.InvariantCulture),
							float.Parse (items [2], CultureInfo.InvariantCulture),
							float.Parse (items [3], CultureInfo.InvariantCulture) * -1
						));
					}

					// manage texture coordinates (uv)
					if (line.StartsWith ("vt ")) {
						string[] items = line.Split (' ');
						this.uvs.Add (new Vector2 (
							float.Parse (items [1], CultureInfo.InvariantCulture),
							float.Parse (items [2], CultureInfo.InvariantCulture)
						));
					}

					// manage normals
					if (line.StartsWith ("vn ")) {
						string[] items = line.Split (' ');
						// check for right handed and left handed !!!
						this.normals.Add (new Vector3 (
							float.Parse (items [1], CultureInfo.InvariantCulture),
							float.Parse (items [2], CultureInfo.InvariantCulture),
							float.Parse (items [3], CultureInfo.InvariantCulture)
						));
					}

					if (line.StartsWith ("f ")) {
						string[] items = line.Split (' ');
						string []id1 = items [1].Split ('/');
						string []id2 = items [2].Split ('/');
						string []id3 = items [3].Split ('/');

						// vertex
						Vector3 av = this.vertices [int.Parse(id1[0]) - 1];
						Vector3 bv = this.vertices [int.Parse(id2[0]) - 1];
						Vector3 cv = this.vertices [int.Parse(id3[0]) - 1];

						// uv
						Vector2 auv = this.uvs [int.Parse(id1[1]) - 1];
						Vector2 buv = this.uvs [int.Parse(id2[1]) - 1];
						Vector2 cuv = this.uvs [int.Parse(id3[1]) - 1];

						// normal
						Vector3 an = this.normals [int.Parse(id1[2]) - 1];
						Vector3 bn = this.normals [int.Parse(id2[2]) - 1];
						Vector3 cn = this.normals [int.Parse(id3[2]) - 1];

						Vertex a = new Vertex (av, auv, an);
						Vertex b = new Vertex (bv, buv, bn);
						Vertex c = new Vertex (cv, cuv, cn);

						this.faces.Add (new Triangle (this, a, b, c));

					}
				}
			}

		}