public VAO(Mesh mesh) { var triangles = mesh.triangles; var vertices = mesh.vertices; var normals = mesh.normals; var uvs = mesh.uv; vbo = new VertexIn[triangles.Length]; Color color = Color.white; for (int i = 0; i < triangles.Length / 3; ++i) { for (int j = 0; j < 3; ++j) { var v = new VertexIn(); var idx = triangles[i * 3 + j]; v.pos = vertices[idx]; v.normal = normals[idx]; v.uv = uvs[idx]; v.color = color; vbo[i * 3 + j] = v; } } }
FragmentIn VS(VertexIn input) { FragmentIn output; Vector2 scaledInput = (input.Position * SizePos.Size) + SizePos.Position; output.Position = Mul(Projection, new Vector4(scaledInput, 0, 1)); output.TexCoord = input.TexCoord; return(output); }
public VAO(ref Vector3[] vertices, ref Color[] colors) { vbo = new VertexIn[vertices.Length]; for (int i = 0; i < vertices.Length; ++i) { var v = new VertexIn(); v.pos = vertices[i]; v.color = colors[i]; vbo[i] = v; } }
public void Execute(int i) { VertexIn inVal = input[triangles[i]]; VertexOut outVal; outVal.position = math.mul(model, inVal.position); outVal.position = math.mul(view, outVal.position); outVal.position = math.mul(proj, outVal.position); outVal.texcoord0 = inVal.texcoord0; outVal.normal = math.mul(model, inVal.normal); output[i] = outVal; }
public FragmentIn Vert(VertexIn v) { var vert = new FragmentIn(); vert.worldPos = ShaderGlobal.l2wMat.MultiplyPoint3x4(v.pos); vert.normal = ShaderGlobal.l2wInvTMat.MultiplyVector(v.normal).normalized; vert.uv = v.uv; vert.color = v.color; Vector4 pos = v.pos; pos.w = 1; vert.vertex = ShaderGlobal.MVPMat * pos; return(vert); }
public void DrawTriangle2D(VertexIn v1, VertexIn v2, VertexIn v3, Color color) { var p1 = v1.pos; var p2 = v2.pos; var p3 = v3.pos; // 保证v1,v2,v3 y轴依次变小 if (p1.y < p2.y) { Swap(ref v1, ref v2); } if (p1.y < p3.y) { Swap(ref v1, ref v3); } if (p2.y < p3.y) { Swap(ref v2, ref v3); } p1 = v1.pos; p2 = v2.pos; p3 = v3.pos; if (p2.y == p3.y) { fillBottomFlatTriangle(v2, v3, v1, color); } else if (p1.y == p2.y) { fillBottomFlatTriangle(v1, v2, v3, color); } else { // y = y0 + k(x-x0) // x = x0 + 1/k*(y-y0) float k = (p1.y - p3.y) / (p1.x - p3.x); float splitx = p3.x + (p2.y - p3.y) / k; float splity = p3.y + (splitx - p3.x) * k; var splitv = new VertexIn(splitx, splity); fillBottomFlatTriangle(v2, splitv, v1, color); fillBottomFlatTriangle(v2, splitv, v3, color); } }
// /\3 // 1----2 void fillBottomFlatTriangle(VertexIn v1, VertexIn v2, VertexIn v3, Color color) { var p1 = v1.pos; var p2 = v2.pos; var p3 = v3.pos; float slop1 = (p3.y - p1.y) / (p3.x - p1.x); float slop2 = (p3.y - p2.y) / (p3.x - p2.x); float curx1 = p1.x; float curx2 = p2.x; int inc = p1.y > p3.y ? -1 : 1; int scanline = (int)p1.y; int scanto = (int)p3.y; if (scanline == scanto) { //三角形退化 var start = new VertexIn(curx1, scanline); var end = new VertexIn(curx2, scanline); DrawLine(start, end, ref color); } else { for (; scanline != scanto; scanline += inc) { var start = new VertexIn(curx1, scanline); var end = new VertexIn(curx2, scanline); DrawLine(start, end, ref color); curx1 += inc / slop1; curx2 += inc / slop2; } } }
public void DrawLine(VertexIn start, VertexIn end, ref Color color) { //裁剪不可见的线 if (!CohenSutherlandLineClip(ref start.pos, ref end.pos, ClipLowLeft, ClipUpRight)) { return; } int x0 = (int)start.pos.x; int x1 = (int)end.pos.x; int y0 = (int)start.pos.y; int y1 = (int)end.pos.y; if (x0 == x1 && y0 == y1) { //点 DrawPixel(x0, y0, ref color); } else if (x0 == x1) { // 竖线 int inc = y0 > y1 ? -1 : 1; for (var y = y0; y != y1; y += inc) { DrawPixel(x0, y, ref color); } DrawPixel(x1, y1, ref color); } else if (y0 == y1) { // 横线 int inc = x0 > x1 ? -1 : 1; for (var x = x0; x != x1; x += inc) { DrawPixel(x, y0, ref color); } DrawPixel(x1, y1, ref color); } else { int dx = (x0 < x1) ? x1 - x0 : x0 - x1; int dy = (y0 < y1) ? y1 - y0 : y0 - y1; // k < 0 if (dx > dy) { if (x1 < x0) { Swap(ref x0, ref x1); Swap(ref y0, ref y1); } int rem = 0, x, y; for (x = x0, y = y0; x <= x1; x++) { DrawPixel(x, y, ref color); rem += dy; if (rem >= dx) { rem -= dx; y += (y1 > y0) ? 1 : -1; } } } else { if (y1 < y0) { Swap(ref x0, ref x1); Swap(ref y0, ref y1); } int rem = 0, x, y; for (x = x0, y = y0; y <= y1; y++) { DrawPixel(x, y, ref color); rem += dx; if (rem >= dy) { rem -= dy; x += (x1 > x0) ? 1 : -1; } } } } }
public static Primitive CreateSphere(GraphicsDevice device) { Primitive p = new Primitive(); float diameter = 1.0f; int tessellation = 16; int verticalSegments = tessellation; int horizontalSegments = tessellation * 2; var vertices = new VertexIn[(verticalSegments + 1) * (horizontalSegments + 1)]; var indices = new int[(verticalSegments) * (horizontalSegments + 1) * 6]; float radius = diameter / 2; int vertexCount = 0; // Create rings of vertices at progressively higher latitudes. for (int i = 0; i <= verticalSegments; i++) { float v = 1.0f - (float)i / verticalSegments; var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0); var dy = (float)Math.Sin(latitude); var dxz = (float)Math.Cos(latitude); // Create a single ring of vertices at this latitude. for (int j = 0; j <= horizontalSegments; j++) { float u = (float)j / horizontalSegments; var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments); var dx = (float)Math.Sin(longitude); var dz = (float)Math.Cos(longitude); dx *= dxz; dz *= dxz; var normal = new Vector3(dx, dy, dz); var textureCoordinate = new Vector2(u, v); vertices[vertexCount++] = new VertexIn() { Position = normal * radius, Normal = normal }; } } // Fill the index buffer with triangles joining each pair of latitude rings. int stride = horizontalSegments + 1; int indexCount = 0; for (int i = 0; i < verticalSegments; i++) { for (int j = 0; j <= horizontalSegments; j++) { int nextI = i + 1; int nextJ = (j + 1) % stride; indices[indexCount++] = (i * stride + j); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (nextI * stride + nextJ); } } for (int i = 0; i < indices.Length; i += 3) { Utilities.Swap(ref indices[i], ref indices[i + 2]); } p.IndexBuffer = SharpDX.Toolkit.Graphics.Buffer.Index.New(device, indices); p.VertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(device, vertices); return(p); }
public static Primitive CreateCube(GraphicsDevice device) { Primitive p = new Primitive(); float size = 1.0f; var vertices = new VertexIn[CubeFaceCount * 4]; var indices = new int[CubeFaceCount * 6]; size /= 2.0f; int vertexCount = 0; int indexCount = 0; // Create each face in turn. for (int i = 0; i < CubeFaceCount; i++) { Vector3 normal = faceNormals[i]; // Get two vectors perpendicular both to the face normal and to each other. Vector3 basis = (i >= 4) ? Vector3.UnitZ : Vector3.UnitY; Vector3 side1; Vector3.Cross(ref normal, ref basis, out side1); Vector3 side2; Vector3.Cross(ref normal, ref side1, out side2); // Six indices (two triangles) per face. int vbase = i * 4; indices[indexCount++] = (vbase + 0); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 2); indices[indexCount++] = (vbase + 0); indices[indexCount++] = (vbase + 2); indices[indexCount++] = (vbase + 3); // Four vertices per face. vertices[vertexCount++] = new VertexIn() { Position = (normal - side1 - side2) * size, Normal = normal }; vertices[vertexCount++] = new VertexIn() { Position = (normal - side1 + side2) * size, Normal = normal }; vertices[vertexCount++] = new VertexIn() { Position = (normal + side1 + side2) * size, Normal = normal }; vertices[vertexCount++] = new VertexIn() { Position = (normal + side1 - side2) * size, Normal = normal }; } for (int i = 0; i < indices.Length; i += 3) { Utilities.Swap(ref indices[i], ref indices[i + 2]); } p.IndexBuffer = SharpDX.Toolkit.Graphics.Buffer.Index.New(device, indices); p.VertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(device, vertices); return(p); }