public MainForm() { InitForm(); screen = new Bitmap(Defaults.WIDTH, Defaults.HEIGHT); renderer = new Renderer(screen, BackgroundColor); mesh = WaveObjHelper.ReadMeshFromFile(appPath + @"3dModels\bear.obj"); //mesh.RecalculateNormals(); Bitmap texture = Paloma.TargaImage.LoadTargaImage(appPath + @"3dModels\bear.tga"); SceneObject sObject = new SceneObject { mesh = mesh, material = new Material(texture, RenderType.RegularWithWireframe), uniformScale = 20f, rotation = new Float3(40, 150, 0), localPosition = new Float3(0, -210, 550) }; renderer.Render(sObject, viewDirection, lightDirection, true); }
public Bitmap Draw(Mesh mesh, int screenWidth, int screenHeight, params object[] uniforms) { float scaleFactor = 300; Float3x3 S = Float3x3.identity * scaleFactor; Float3x3 R = Float3x3.getRotationMatrix(0, 0, 0); for (int i = 0; i < mesh.Vertices.Count; i++) { Float3 scaled = mesh.Vertices[i].mul(S); scaled = scaled.mul(R); mesh.Vertices[i] = new Float3(scaled.x + WIDTH / 2, scaled.y + HEIGHT / 2, scaled.z); } for (int i = 0; i < mesh.Vertices.Count; i++) { Float3 v = mesh.Vertices[i]; screen.elDrawPoint(v.x, v.y, color); } int c = mesh.Triangles.Count; for (int i = 0; i < c; i++) { Triangle t = mesh.Triangles[i]; Float3 v1 = mesh.Vertices[t[0] - 1]; Float3 v2 = mesh.Vertices[t[1] - 1]; Float3 v3 = mesh.Vertices[t[2] - 1]; screen.elDrawTriangle(v1, v2, v3, getRandomColor()); //screen.elDrawLine(v1.x, v1.y, v2.x, v2.y, color); //screen.elDrawLine(v2.x, v2.y, v3.x, v3.y, color); //screen.elDrawLine(v3.x, v3.y, v1.x, v1.y, color); } return null; }
private void RenderWireframe(Mesh mesh, Color color) { for (int i = 0; i < mesh.Triangles.Count; i++) { Triangle t = mesh.Triangles[i]; Float3 v1 = mesh.Vertices[t[0] - 1].position; Float3 v2 = mesh.Vertices[t[1] - 1].position; Float3 v3 = mesh.Vertices[t[2] - 1].position; bitmap.elDrawLine(v1.xy, v2.xy, color); bitmap.elDrawLine(v2.xy, v3.xy, color); bitmap.elDrawLine(v3.xy, v1.xy, color); } }
private void RenderRegular(Mesh mesh, Material material, Float3 lightDirection) { rasterizer.Rasterize(mesh, material, lightDirection); // FRAGMENT SHADER for (int x = 0; x < Defaults.WIDTH; x++) for (int y = 0; y < Defaults.HEIGHT; y++) bitmap.elDrawPoint(x, y, zBuffer[x, y].color); }
private void DrawVertexNormals(Mesh mesh, Color color) { for (int i = 0; i < mesh.Vertices.Count; i++) { Vertex v = mesh.Vertices[i]; bitmap.elDrawLine(v.position, (v.position + v.normal * 30), color); } }
public void Rasterize(Mesh mesh, Material material, Float3 lightDirection) { // set interpolated color for (int i = 0; i < mesh.Triangles.Count; i++) { Triangle t = mesh.Triangles[i]; Vertex v1 = mesh.Vertices[t[0] - 1]; Vertex v2 = mesh.Vertices[t[1] - 1]; Vertex v3 = mesh.Vertices[t[2] - 1]; //v2.normal = v1.normal; //v3.normal = v1.normal; int cc1 = (int)(getLamberComponent(v1.normal, lightDirection) * 255); int cc2 = (int)(getLamberComponent(v2.normal, lightDirection) * 255); int cc3 = (int)(getLamberComponent(v3.normal, lightDirection) * 255); v1.color = Color.FromArgb(cc1, cc1, cc1);//.lerpTo(Color.Green, 0.5f); v2.color = Color.FromArgb(cc2, cc2, cc2);//.lerpTo(Color.Blue, 0.5f); v3.color = Color.FromArgb(cc3, cc3, cc3);//.lerpTo(Color.Red, 0.5f); } for (int i = 0; i < mesh.Triangles.Count; i++) { Triangle t = mesh.Triangles[i]; Vertex v1 = mesh.Vertices[t[0] - 1]; Vertex v2 = mesh.Vertices[t[1] - 1]; Vertex v3 = mesh.Vertices[t[2] - 1]; RenderTriangle2(v1, v2, v3, material, lightDirection); } }
public static Mesh ReadMeshFromFile(string filePath) { Mesh result = new Mesh(); string[] lines = File.ReadAllLines(filePath); List<Float3> normals = new List<Float3>(); List<Float3> vPositions = new List<Float3>(); List<Float2> uvs = new List<Float2>(); List<WObjTriangle> wTriangles = new List<WObjTriangle>(); for (int i = 0; i < lines.Length; i++) { if (lines[i].Length == 0) continue; string[] lineParts = ReplaceMultipleSpaces(lines[i]).Split(' '); // vertex positions if (lineParts[0] == "v") { Float3 position = new Float3(float.Parse(lineParts[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(lineParts[2], System.Globalization.CultureInfo.InvariantCulture), float.Parse(lineParts[3], System.Globalization.CultureInfo.InvariantCulture) ); vPositions.Add(position); } // uv coordinates if (lineParts[0] == "vt") { Float2 uv = new Float2(float.Parse(lineParts[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(lineParts[2], System.Globalization.CultureInfo.InvariantCulture)); uvs.Add(uv); } // normals if (lineParts[0] == "vn") { Float3 normal = new Float3(float.Parse(lineParts[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(lineParts[2], System.Globalization.CultureInfo.InvariantCulture), float.Parse(lineParts[3], System.Globalization.CultureInfo.InvariantCulture) ); normals.Add(normal); } if (lineParts[0] == "f") { string[] f1 = lineParts[1].Split('/'); string[] f2 = lineParts[2].Split('/'); string[] f3 = lineParts[3].Split('/'); int v1 = int.Parse(f1[0]); int v2 = int.Parse(f2[0]); int v3 = int.Parse(f3[0]); int t1 = -1; int t2 = -1; int t3 = -1; // if texture coordinates specified if (f1.Length > 1) { if (!string.IsNullOrEmpty(f1[1])) t1 = int.Parse(f1[1]); if (!string.IsNullOrEmpty(f2[1])) t2 = int.Parse(f2[1]); if (!string.IsNullOrEmpty(f3[1])) t3 = int.Parse(f3[1]); } int n1 = 0, n2 = 0, n3 = 0; // if normals specified if (f1.Length > 2) { n1 = int.Parse(f1[2]); n2 = int.Parse(f2[2]); n3 = int.Parse(f3[2]); } wTriangles.Add(new WObjTriangle(v1, v2, v3, n1, n2, n3, t1, t2, t3)); result.Triangles.Add(new Triangle(v1, v2, v3)); } } result.Vertices = new List<Vertex>(); for(int i = 0; i < vPositions.Count; i++) { result.Vertices.Add(new Vertex(vPositions[i])); } for(int i = 0; i < wTriangles.Count; i++) { WObjTriangle wTriangle = wTriangles[i]; Vertex v1 = result.Vertices[wTriangle.v1 - 1]; Vertex v2 = result.Vertices[wTriangle.v2 - 1]; Vertex v3 = result.Vertices[wTriangle.v3 - 1]; if(normals.Count > 0) { v1.normal = normals[wTriangle.n1 - 1]; v2.normal = normals[wTriangle.n2 - 1]; v3.normal = normals[wTriangle.n3 - 1]; } if (uvs.Count > 0) { if (wTriangle.uv1 < 0 || wTriangle.uv2 < 0 || wTriangle.uv3 < 0) continue; v1.uv = uvs[wTriangle.uv1 - 1]; v2.uv = uvs[wTriangle.uv2 - 1]; v3.uv = uvs[wTriangle.uv3 - 1]; } } return result; }