void DrawEntity(Entity entity) { Mesh mesh = entity.meshFilter.mesh; Transform objectTransform = entity.transform; Texture2D mainTex = entity.mainTex; for (int i = 0; i < mesh.triangles.Length; i += 3) { int a_index = mesh.triangles[i]; int b_index = mesh.triangles[i + 1]; int c_index = mesh.triangles[i + 2]; TriangleAttribute <Color> colors = new TriangleAttribute <Color>(Color.red, Color.green, Color.blue); TriangleAttribute <Vector2> uvs = new TriangleAttribute <Vector2>(mesh.uv[a_index], mesh.uv[b_index], mesh.uv[c_index]); Vector4 a = V4Point(mesh.vertices[a_index]); Vector4 b = V4Point(mesh.vertices[b_index]); Vector4 c = V4Point(mesh.vertices[c_index]); m_Transform m_objectTransform = new m_Transform(); m_objectTransform.CopyFromTransform(objectTransform); a = m_objectTransform.TransformPoint(a); b = m_objectTransform.TransformPoint(b); c = m_objectTransform.TransformPoint(c); TriangleAttribute <Vector3> pos_worlds = new TriangleAttribute <Vector3>(a, b, c); TriangleAttribute <Vector3> normals = new TriangleAttribute <Vector3>( m_objectTransform.TransformDirection(mesh.normals[a_index]), m_objectTransform.TransformDirection(mesh.normals[b_index]), m_objectTransform.TransformDirection(mesh.normals[c_index])); m_Transform cam_t = new m_Transform(); cam_t.CopyFromTransform(cam.transform); a = cam_t.InverseTransformPoint(a); b = cam_t.InverseTransformPoint(b); c = cam_t.InverseTransformPoint(c); Matrix4x4 p = GetProjectionMatrix(cam); Matrix4x4 negetive = Matrix4x4.identity; negetive.m22 = -1; Matrix4x4 total = p * negetive; a = ClipSpaceToScreenSpace(total * V4Point(a), pixelWidth, pixelHeight); b = ClipSpaceToScreenSpace(total * V4Point(b), pixelWidth, pixelHeight); c = ClipSpaceToScreenSpace(total * V4Point(c), pixelWidth, pixelHeight); a.z = a.w; b.z = b.w; c.z = c.w; Triangle3D triangle = new Triangle3D(a, b, c); //z值为摄像机空间z坐标 DrawTriangle(colorBuffer, triangle, colors, uvs, pos_worlds, normals, mainTex); } }
void TestRenderer() { Helper.display = false; List <Triangle3D> ts = bsp.GetSquence(cam.transform.position); Helper.DisplayTriangleList(ts, "bsp"); for (int i = 0; i < ts.Count; i++) { if (!FaceCulling(ts[i].normal, cam.transform.forward)) { ts.RemoveAt(i); i--; } } Helper.DisplayTriangleList(ts, "face culling"); //观察坐标系,左手坐标系 m_Transform cam_t = new m_Transform(); cam_t.CopyFromTransform(cam.transform); for (int i = 0; i < ts.Count; i++) { Triangle3D t = ts[i]; t.a = cam_t.InverseTransformPoint(t.a); t.b = cam_t.InverseTransformPoint(t.b); t.c = cam_t.InverseTransformPoint(t.c); t.normal = cam_t.InverseTransformDirection(t.normal); ts[i] = t; } int count = ts.Count; for (int i = 0; i < count; i++) { ts.AddRange(ViewSpaceFrustrumClipping(ts[0], cam)); ts.RemoveAt(0); } Helper.DisplayTriangleList(ts, "Frustrum Clipping"); List <Triangle3D> ts_ScreenSpace = new List <Triangle3D>(ts.Count); Matrix4x4 p = GetProjectionMatrix(cam); //转换到右手坐标 Matrix4x4 negetive = Matrix4x4.identity; negetive.m22 = -1; Matrix4x4 total = p * negetive; for (int i = 0; i < ts.Count; i++) { Triangle3D t = ts[i]; t.a = ClipSpaceToScreenSpace(total * V4Point(t.a), pixelWidth, pixelHeight); t.b = ClipSpaceToScreenSpace(total * V4Point(t.b), pixelWidth, pixelHeight); t.c = ClipSpaceToScreenSpace(total * V4Point(t.c), pixelWidth, pixelHeight); ts_ScreenSpace.Add(t); } Helper.DisplayTriangleList(ts_ScreenSpace, "Sceen Space"); for (int i = 0; i < ts_ScreenSpace.Count; i++) { Triangle3D t = ts_ScreenSpace[i]; Vector2[] t2 = new Vector2[3]; t2[0] = t.a; t2[1] = t.b; t2[2] = t.c; DrawTriangleScanLine(colorBuffer, t2); } }