public VertexBuffer(Vertex[] data) { this.data = new Vertex[data.Count()]; for (int i = 0; i < data.Count(); i++ ) { Vertex v = data[i]; Vertex newV = new Vertex(); newV.pos = v.pos; newV.normal = v.normal; newV.color = v.color; newV.uv = v.uv; this.data[i] = newV; } }
public List<Pass.PassData> PaserObj(string objName) { List<Pass.PassData> datalist = new List<Pass.PassData>(); Dictionary<string, Material> matDic = new Dictionary<string,Material>(); foreach (string line in System.IO.File.ReadAllLines(objName)) { if (line.StartsWith("mtllib")) { string matLibName = line.Substring(7); matDic = parseMat("media/" + matLibName); } else if (line.StartsWith("vt")) { string[] tempAry = line.Split(new char[1] { ' ' }); tempAry = Array.FindAll<string>(tempAry, x => { float temp; return float.TryParse(x, out temp); }); SlimDX.Vector2 uv = new SlimDX.Vector2(); uv.X = System.Convert.ToSingle(tempAry[0]); uv.Y = 1.0f - System.Convert.ToSingle(tempAry[1]); uvList.Add(uv); } else if (line.StartsWith("vn")) { string[] tempAry = line.Split(new char[1] { ' ' }); tempAry = Array.FindAll<string>(tempAry, x => { float temp; return float.TryParse(x, out temp); }); SlimDX.Vector4 normal = new SlimDX.Vector4(); normal.X = System.Convert.ToSingle(tempAry[0]); normal.Y = System.Convert.ToSingle(tempAry[1]); normal.Z = System.Convert.ToSingle(tempAry[2])-1.0f; normalList.Add(normal); } else if (line.StartsWith("v")) { string[] tempAry = line.Split(new char[1] { ' ' }); tempAry = Array.FindAll<string>(tempAry, x => { float temp; return float.TryParse(x, out temp); }); SlimDX.Vector4 pos = new SlimDX.Vector4(); pos.X = System.Convert.ToSingle(tempAry[0]); pos.Y = System.Convert.ToSingle(tempAry[1]); pos.Z = System.Convert.ToSingle(tempAry[2])*(-1.0f); pos.W = 1.0f; posList.Add(pos); } } List<Vertex> vertexList = new List<Vertex>(); List<int[]> triangleIndexList = new List<int[]>(); Material m = null; Pass.PassData data = null; Dictionary<string, int> cache = new Dictionary<string, int>(); int dataCount = 0; foreach (string line in System.IO.File.ReadAllLines(objName)) { if (line.StartsWith("usemtl")) { if (data != null) { data.triangleIndexs = triangleIndexList; data.vertexs = vertexList.ToArray(); data.materail = m; datalist.Add(data); dataCount++; System.Console.WriteLine(dataCount); } data = new Pass.PassData(); string[] tempAry = line.Split(new char[1] { ' ' }); string matName = tempAry[1]; m = matDic[matName]; vertexList = new List<Vertex>(); triangleIndexList = new List<int[]>(); cache.Clear(); } else if (line.StartsWith("f")) { string[] tempAry = line.Split(new char[1] { ' ' }); int[] indexs = new int[3]; for (int i=3; i>=1; i--) { string s = tempAry[i]; if (string.IsNullOrWhiteSpace(s) || string.IsNullOrEmpty(s)) continue; string[] IndexAry = s.Split(new char[1] { '/' }); if (IndexAry.Length == 1) { int posIndex = Convert.ToInt32(IndexAry[0]) - 1; string cacheString = "pos" + posIndex.ToString(); if (cache.ContainsKey(cacheString)) { int index = cache[cacheString]; indexs[i] = index; } else { Vertex newVertex = new Vertex(); newVertex.pos = posList[posIndex]; vertexList.Add(newVertex); indexs[i] = vertexList.Count - 1; cache[cacheString] = vertexList.Count - 1; } //triangleIndexList.Add(indexs); } else if (IndexAry.Length == 2) { int posIndex = Convert.ToInt32(IndexAry[0]) - 1; int uvIndex = Convert.ToInt32(IndexAry[1]) - 1; string cacheString = "pos" + posIndex.ToString() + "uv" + uvIndex.ToString(); if (cache.ContainsKey(cacheString)) { int index = cache[cacheString]; indexs[i] = index; } else { Vertex newVertex = new Vertex(); newVertex.pos = posList[posIndex]; newVertex.uv = uvList[uvIndex]; vertexList.Add(newVertex); indexs[i] = vertexList.Count - 1; cache[cacheString] = vertexList.Count - 1; } //triangleIndexList.Add(indexs); } else if (IndexAry.Length == 3) { int posIndex = Convert.ToInt32(IndexAry[0]) - 1; int uvIndex = Convert.ToInt32(IndexAry[1]) - 1; int normalIndex = Convert.ToInt32(IndexAry[2]) - 1; string cacheString = "pos" + posIndex.ToString() + "uv" + uvIndex.ToString() + "normal"+normalIndex.ToString(); if (cache.ContainsKey(cacheString)) { int index = cache[cacheString]; indexs[i-1] = index; } else { Vertex newVertex = new Vertex(); newVertex.pos = posList[posIndex]; newVertex.uv = uvList[uvIndex]; newVertex.normal = normalList[normalIndex]; vertexList.Add(newVertex); indexs[i-1] = vertexList.Count - 1; cache[cacheString] = vertexList.Count - 1; } } } int index1 = indexs[0]; int index2 = indexs[1]; int index3 = indexs[2]; indexs[0] = index3; indexs[1] = index2; indexs[2] = index1; triangleIndexList.Add(indexs); } } if (data != null) { data.triangleIndexs = triangleIndexList; data.vertexs = vertexList.ToArray(); data.materail = m; datalist.Add(data); } return datalist; }
public void drawTriange(Vertex[] vertexList, int[] index, Buffer<Color4> outPutBuffer, Buffer<float> zBuffer, Texture t) { Vertex v1 = vertexList[index[0]]; Vertex v2 = vertexList[index[1]]; Vertex v3 = vertexList[index[2]]; float tMinX =v1.pos.X; float tMinY = v1.pos.Y; float tMaxX = v1.pos.X; float tMaxY = v1.pos.Y; for (int i = 0; i < 3; i++) { Vertex v = vertexList[index[i]]; if (v.pos.X < tMinX) tMinX = v.pos.X; if (v.pos.Y < tMinY) tMinY = v.pos.Y; if (v.pos.X > tMaxX) tMaxX = v.pos.X; if (v.pos.Y > tMaxY) tMaxY = v.pos.Y; } int minX = (int)Math.Floor(tMinX); int maxX = (int)Math.Ceiling(tMaxX); int minY = (int)Math.Floor(tMinY); int maxY = (int)Math.Ceiling(tMaxY); for (int posX = minX; posX <= maxX; posX++) { for (int posY = minY; posY <= maxY; posY++) { float posX0 = v1.pos.X; float posX1 = v2.pos.X; float posX2 = v3.pos.X; float posY0 = v1.pos.Y; float posY1 = v2.pos.Y; float posY2 = v3.pos.Y; float index0 = ((posY1 - posY2) * posX + (posX2 - posX1) * posY + posX1 * posY2 - posX2 * posY1) / ((posY1 - posY2) * posX0 + (posX2 - posX1) * posY0 + posX1 * posY2 - posX2 * posY1); float index1 = ((posY2 - posY0) * posX + (posX0 - posX2) * posY + posX2 * posY0 - posX0 * posY2) / ((posY2 - posY0) * posX1 + (posX0 - posX2) * posY1 + posX2 * posY0 - posX0 * posY2); float index2 = ((posY0 - posY1) * posX + (posX1 - posX0) * posY + posX0 * posY1 - posX1 * posY0) / ((posY0 - posY1) * posX2 + (posX1 - posX0) * posY2 + posX0 * posY1 - posX1 * posY0); if (index0 > 0 && index1 > 0 && index2 > 0) { Color4 c = new Color4(); c.Alpha = v1.color.Alpha * index0 + v2.color.Alpha * index1 + v3.color.Alpha * index2; c.Red = v1.color.Red * index0 + v2.color.Red * index1 + v3.color.Red * index2; c.Green = v1.color.Green * index0 + v2.color.Green * index1 + v3.color.Green * index2; c.Blue = v1.color.Blue * index0 + v2.color.Blue * index1 + v3.color.Blue * index2; float z = v1.pos.Z * index0 + v2.pos.Z * index1 + v3.pos.Z * index2; bool offScreen = posX < 0 || posX >= SRDevice.Device.GetWidth() || posY < 0 || posY >= SRDevice.Device.GetHeight(); if (!offScreen) { float curZ = zBuffer.readOneData(posX, posY); if (z < curZ) { zBuffer.writeOneData(posX, posY, z); if (t != null) { float u = v1.uv.X * index0 + v2.uv.X * index1 + v3.uv.X * index2; float v = v1.uv.Y * index0 + v2.uv.Y * index1 + v3.uv.Y * index2; Math.Min(Math.Max(u, 0.0f), 1.0f); Math.Min(Math.Max(v, 0.0f), 1.0f); outPutBuffer.writeOneData(posX, posY, t.getPixel(u, v)); } else { outPutBuffer.writeOneData(posX, posY, c); } } } } } } }
public void drawLine(Vertex[] vertexs, int[] indexs, Buffer<Color4> outPut) { Vertex[] line = new Vertex[2]; line[0] = vertexs[indexs[0]]; line[1] = vertexs[indexs[1]]; Array.Sort(line, (l1, l2) => l1.pos.X.CompareTo(l2.pos.X)); Color4 c = line[0].color; int posX1 = (int)line[0].pos.X; int posY1 = (int)line[0].pos.Y; int posX2 = (int)line[1].pos.X; int posY2 = (int)line[1].pos.Y; if (posX1 == posX2) { int start = 0; int end = 0; if (posY1> posY2) { start = posY2; end = posY1; } else { start = posY1; end = posY2; } for (int posY = start; posY<end; posY++) { outPut.writeOneData(posX1, posY, c); } } else { float k = ((float)(posY2 - posY1)) / ((float)(posX2 - posX1)); float d = posY1 - k * posX1; if (k == 0) { int start = 0; int end = 0; if (posX1 > posX2) { start = posX2; end = posX1; } else { start = posX1; end = posX2; } for (int posX = start; posX < end; posX++) { outPut.writeOneData(posX, posY1, c); } } else if (k >= 1) { int posX = posX1; for (int posY = posY1; posY <= posY2; posY++) { outPut.writeOneData(posX, posY, c); if (posY + 1 - k * (posX + 0.5) - d > 0) { posX = posX + 1; } } } else if (k > 0 && k < 1) { int posY = posY1; for (int posX = posX1; posX <= posX2; posX++) { outPut.writeOneData(posX, posY, c); if (posY + 0.5 - k * (posX + 1) - d < 0) { posY = posY + 1; } } } else if (k < 0 && k > -1) { int posY = posY1; for (int posX = posX1; posX <= posX2; posX++) { outPut.writeOneData(posX, posY, c); if (posY + 0.5 - k * (posX + 1) - d > 0) { posY = posY - 1; } } } else if (k <= -1) { int posX = posX1; for (int posY = posY1; posY >= posY2; posY--) { outPut.writeOneData(posX, posY, c); if (posY - 1 - k * (posX + 0.5) - d < 0) { posX = posX + 1; } } } } }
public CullResult CullTriangles(Vertex[] vertexs, List<int[]> trianglesIndex, CullPlane cullPlanes) { foreach (int[] indexs in trianglesIndex) { Vertex[] t = new Vertex[3]; int index1 = indexs[0]; t[0] = vertexs[index1]; int index2 = indexs[1]; t[1] = vertexs[index2]; int index3 = indexs[2]; t[2] = vertexs[index3]; cullTriangles.Add(t); } foreach (Plane p in cullPlanes.getCullPlanes()) { Vertex[][] triAry = cullTriangles.ToArray(); int length = triAry.Length; cullTriangles.Clear(); cullTrianglesCache.Clear(); for (int i = 0; i < triAry.Length; i++) { cullTriangle(triAry[i], p); } List<Vertex> newVertex1 = new List<Vertex>(); foreach (Vertex[] t in cullTriangles) { if (!newVertex1.Contains(t[0])) newVertex1.Add(t[0]); if (!newVertex1.Contains(t[1])) newVertex1.Add(t[1]); if (!newVertex1.Contains(t[2])) newVertex1.Add(t[2]); } int vertexCount = newVertex1.Count; } List<Vertex> newVertex = new List<Vertex>(); foreach (Vertex[] t in cullTriangles) { if (!newVertex.Contains(t[0])) newVertex.Add(t[0]); if (!newVertex.Contains(t[1])) newVertex.Add(t[1]); if (!newVertex.Contains(t[2])) newVertex.Add(t[2]); } vertexs = newVertex.ToArray(); trianglesIndex = new List<int[]>(); foreach(Vertex[] t in cullTriangles) { int[] indexs = new int[3]; indexs[0] = newVertex.IndexOf(t[0]); indexs[1] = newVertex.IndexOf(t[1]); indexs[2] = newVertex.IndexOf(t[2]); trianglesIndex.Add(indexs); } CullResult result = new CullResult(); result.vertexs = vertexs; result.trianglesIndex = trianglesIndex; return result; }
private void addNewCullTriangle(Vertex[] triangle) { //string temp = triangle[0].ToString() + triangle[1].ToString() + triangle[2].ToString(); //if (!cullTrianglesCache.ContainsKey(temp)) //{ // cullTriangles.Add(triangle); // cullTrianglesCache[temp] = triangle; //} Vertex[] temp = cullTriangles.Find(x => x.Contains(triangle[0]) && x.Contains(triangle[1]) && x.Contains(triangle[2])); if (temp == null) cullTriangles.Add(triangle); }
List<Vertex> getPreCullList(Vertex p1, Vertex p2, Plane p) { CullLine cullLine = null; string cacheString = p1.pos.ToString() + p2.pos.ToString() + p.normal.ToString()+p.point.ToString(); foreach (CullLine c in cullLineList.Values) { if (c.inputList.Contains(p1) && c.inputList.Contains(p2) && c.plane == p) cullLine = c; } //if (cullLineList.ContainsKey(cacheString)) // cullLine = cullLineList[cacheString]; if (cullLine != null) return cullLine.outPutList; else return null; }
private void cullTriangle(Vertex[] triangle, Plane p) { List<Vertex> vertexs = new List<Vertex>(); vertexs.AddRange(cullLine(triangle[0], triangle[1], p)); foreach (Vertex v in cullLine(triangle[1], triangle[2], p)) { if (!vertexs.Contains(v)) vertexs.Add(v); } foreach (Vertex v in cullLine(triangle[2], triangle[0], p)) { if (!vertexs.Contains(v)) vertexs.Add(v); } if (vertexs.Count == 3) { addNewCullTriangle(vertexs.ToArray()); } else if (vertexs.Count == 4) { Vertex[] newTriangle = new Vertex[3]; newTriangle[0] = vertexs[0]; newTriangle[1] = vertexs[1]; newTriangle[2] = vertexs[2]; addNewCullTriangle(newTriangle); newTriangle = new Vertex[3]; newTriangle[0] = vertexs[2]; newTriangle[1] = vertexs[3]; newTriangle[2] = vertexs[0]; addNewCullTriangle(newTriangle); } }
private List<Vertex> cullLine(Vertex p1, Vertex p2, Plane p) { //List<Vertex> list = getPreCullList(p1, p2, p); //if (list != null) // return list; List<Vertex> list = new List<Vertex>(); float value1 = p.getDotValue(p1.pos); float value2 = p.getDotValue(p2.pos); float temp = value1 * value2; if (temp >= 0) { if (value1>0 && value2 > 0) { list.Add(p1); list.Add(p2); } else if (value1>0 && value2==0 || value2>0 && value1==0) { list.Add(p1); list.Add(p2); } } else { Vertex v = p.getInsertValue(p1, p2); if (value1 > 0) { list.Add(p1); list.Add(v); } else { list.Add(v); list.Add(p2); } } CullLine cullLine = new CullLine(); cullLine.inputList.Add(p1); cullLine.inputList.Add(p2); cullLine.plane = p; cullLine.outPutList = list; string cacheString = p1.pos.ToString() + p2.pos.ToString() + p.normal.ToString()+p.point.ToString(); cullLineList[cacheString] = cullLine; return list; }
public Cube(Vector4 minPos, Vector4 maxPos) { this.minPos = minPos; this.maxPos = maxPos; Vertex v1 = new Vertex(); v1.pos = new Vector4(minPos.X, minPos.Y, minPos.Z, 1.0f); v1.color = new Color4(1.0f, 1.0f, 0.0f, 0.0f); v1.uv = new Vector2(0.0f, 0.0f); Vertex v2 = new Vertex(); v2.pos = new Vector4(maxPos.X, minPos.Y, minPos.Z, 1.0f); v2.color = new Color4(1.0f, 1.0f, 0.0f, 0.0f); v2.uv = new Vector2(1.0f, 0.0f); Vertex v3 = new Vertex(); v3.pos = new Vector4(maxPos.X, maxPos.Y, minPos.Z, 1.0f); v3.color = new Color4(1.0f, 1.0f, 0.0f, 0.0f); v3.uv = new Vector2(1.0f, 1.0f); Vertex v4 = new Vertex(); v4.pos = new Vector4(minPos.X, maxPos.Y, minPos.Z, 1.0f); v4.color = new Color4(1.0f, 1.0f, 0.0f, 0.0f); v4.uv = new Vector2(0.0f, 1.0f); Vertex v5 = new Vertex(); v5.pos = new Vector4(minPos.X, minPos.Y, maxPos.Z, 1.0f); v5.color = new Color4(1.0f, 0.0f, 0.0f, 1.0f); v5.uv = new Vector2(0.0f, 0.0f); Vertex v6 = new Vertex(); v6.pos = new Vector4(maxPos.X, minPos.Y, maxPos.Z, 1.0f); v6.color = new Color4(1.0f, 0.0f, 0.0f, 1.0f); v6.uv = new Vector2(1.0f, 0.0f); Vertex v7 = new Vertex(); v7.pos = new Vector4(maxPos.X, maxPos.Y, maxPos.Z, 1.0f); v7.color = new Color4(1.0f, 0.0f, 0.0f, 1.0f); v7.uv = new Vector2(1.0f, 1.0f); Vertex v8 = new Vertex(); v8.pos = new Vector4(minPos.X, maxPos.Y, maxPos.Z, 1.0f); v8.color = new Color4(1.0f, 0.0f, 0.0f, 1.0f); v8.uv = new Vector2(0.0f, 1.0f); vertexs[0] = v1; vertexs[1] = v2; vertexs[2] = v3; vertexs[3] = v4; vertexs[4] = v5; vertexs[5] = v6; vertexs[6] = v7; vertexs[7] = v8; triangleIndexs.Add(new int[3] { 2, 3, 0 }); triangleIndexs.Add(new int[3] { 0, 1, 2 }); triangleIndexs.Add(new int[3] { 6, 2, 1 }); triangleIndexs.Add(new int[3] { 1, 5, 6 }); triangleIndexs.Add(new int[3] { 4, 7, 6 }); triangleIndexs.Add(new int[3] { 6, 5, 4 }); triangleIndexs.Add(new int[3] { 3, 7, 4 }); triangleIndexs.Add(new int[3] { 4, 0, 3 }); triangleIndexs.Add(new int[3] { 6, 7, 3 }); triangleIndexs.Add(new int[3] { 3, 2, 6 }); triangleIndexs.Add(new int[3] { 0, 4, 5 }); triangleIndexs.Add(new int[3] { 5, 1, 0 }); lines.Add(new int[2] { 0, 1 }); lines.Add(new int[2] { 1, 2 }); lines.Add(new int[2] { 2, 3 }); lines.Add(new int[2] { 3, 0 }); lines.Add(new int[2] { 4, 5 }); lines.Add(new int[2] { 5, 6 }); lines.Add(new int[2] { 6, 7 }); lines.Add(new int[2] { 7, 4 }); lines.Add(new int[2] { 0, 4 }); lines.Add(new int[2] { 1, 5 }); lines.Add(new int[2] { 2, 6 }); lines.Add(new int[2] { 3, 7 }); }
static void Main(string[] args) { int width = 1024; int height = 1024; float near = 1f; float far = 100.0f; SRDevice.Device.Init(width, height); Camera c = new Camera(near, far, (float)Math.PI/2,width, height); Culler cull = new Culler(); SRDevice.Device.Camera = c; SRDevice.Device.Cull = cull; c.setLookAt(new Vector3(20, 20, 0), new Vector3(-0.1f, 0.5f, 1), new Vector3(0, 1, 0)); Vertex[] vertexs; List<int[]> trianglesIndex; ObjPaser p = new ObjPaser(); List<Pass.PassData> dataList = p.PaserObj("media/cube.obj"); Model m1 = new Model(dataList); Vertex v1 = new Vertex(); v1.pos = new Vector4(-0.5f, -0.5f, 11f, 0); v1.color = new Color4(1.0f, 0.5f, 0.5f, 0.5f); Vertex v2 = new Vertex(); v2.pos = new Vector4(-0.5f, 0.5f, 11f, 0); v2.color = new Color4(1.0f, 0.5f, 0.5f, 0.5f); Vertex v3 = new Vertex(); v3.pos = new Vector4(0.5f, -0.5f, 11f, 0); v3.color = new Color4(1.0f, 0.5f, 0.5f, 0.5f); Vertex v4 = new Vertex(); v4.pos = new Vector4(0.5f, 0.5f, 11f, 0); v4.color = new Color4(1.0f, 0.5f, 0.5f, 0.5f); Pass.PassData data = new Pass.PassData(); data.vertexs = new Vertex[4]; data.vertexs[0] = v1; data.vertexs[1] = v2; data.vertexs[2] = v3; data.vertexs[3] = v4; data.triangleIndexs = new List<int[]>(); int[] triangle1 = new int[3] { 0, 3, 2 }; int[] triangle2 = new int[3] { 3, 0, 1 }; data.triangleIndexs.Add(triangle1); data.triangleIndexs.Add(triangle2); data.materail = new Material(); Model m2 = new Model(new List<Pass.PassData>() { data }); m2.Render(Matrix.Invert(SRDevice.Device.Camera.getViewMatrix())); m1.transform.localPosition = new Vector4(0.0f, 0.0f, 10.0f, 0.0f); m1.transform.localScale = new Vector4(10.0f, 10.0f, 10.0f, 0.0f); //m1.transform.localRotation = new Vector4(0.0f, (float)Math.PI / 4, 0.0f, 0.0f); //m1.Render(); SRDevice.Device.Present(); }