private void DrawText(string text, int x, int y) { for (int i = 0; i < text.Length; ++i) { int n = text[i]; float sizeU = 1.0f / mapWidth; float sizeV = 1.0f / mapHeight; float u = (float)(n % mapWidth) / mapWidth; float v = (float)(n / mapHeight) / mapHeight; int width = CharWidth * Scale; int height = CharHeight * Scale; Vertex4[] vertices = new Vertex4[] { new Vertex4(x + i * width, y, u, v + sizeV), new Vertex4(x + i * width, y + height, u, v), new Vertex4(x + i * width + width, y, u + sizeU, v + sizeV), new Vertex4(x + i * width + width, y + height, u + sizeU, v) }; GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, Marshal.SizeOf(typeof(Vertex4)) * 4, vertices); GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4); } }
public void Move(double deltaX, double deltaY) { Vertex1.Move(deltaX, deltaY); Vertex2.Move(deltaX, deltaY); Vertex3.Move(deltaX, deltaY); Vertex4.Move(deltaX, deltaY); }
private static void DrawFlatLine(Vertex4 v1, Vertex4 v2) { if (v1.Point.Y >= Height || v1.Point.Y < 0) { return; } if (v1.Point.X > v2.Point.X) { Swap(ref v1, ref v2); } if (v1.Point.X >= Width || v2.Point.X < 0) { return; } float x0 = v1.Point.X; float x1 = v2.Point.X >= Width ? Width - 1 : v2.Point.X; float dx = v2.Point.X - x0 + 0.01f; for (int i = (int)(x0 < 0 ? 0 : x0); i <= x1; i++) { float t = (i - x0) / dx; Vertex4 v = Mathf.Lerp(v1, v2, t); v = MulOnePerZ(v); SetPixel(i, (int)(v1.Point.Y), Tex.Value(v.UV), v.Point.Z); } }
static void Swap(ref Vertex4 a, ref Vertex4 b) { Vertex4 c = a; a = b; b = c; }
public static void DrawTrangle(Vertex4 v1, Vertex4 v2, Vertex4 v3) { if (Clip(v1) == true && Clip(v2) == true && Clip(v3) == true) { return; } TriCount++; v1.Point = ToScreen(v1.Point); v2.Point = ToScreen(v2.Point); v3.Point = ToScreen(v3.Point); v1 = MulOnePerZ(v1); v2 = MulOnePerZ(v2); v3 = MulOnePerZ(v3); Sort(ref v1, ref v2, ref v3); if (v2.Point.Y == v3.Point.Y) { FillFlatTriangle(v1, v2, v3, false); } else if (v1.Point.Y == v2.Point.Y) { FillFlatTriangle(v3, v1, v2, true); } else { float t = (v2.Point.Y - v1.Point.Y) / (v3.Point.Y - v1.Point.Y); Vertex4 v4 = Mathf.Lerp(v1, v3, t); FillFlatTriangle(v1, v2, v4, false); FillFlatTriangle(v3, v2, v4, true); } }
private static Vertex4 MulOnePerZ(Vertex4 v) { v.Point.W = 1 / v.Point.W; v.Color *= v.Point.W; v.Normal *= v.Point.W; v.UV *= v.Point.W; return(v); }
public static Vertex4 Lerp(Vertex4 a, Vertex4 b, float t) { return(new Vertex4 { Color = Vector4.Lerp(a.Color, b.Color, t), Point = Vector4.Lerp(a.Point, b.Point, t), UV = Vector2.Lerp(a.UV, b.UV, t), Normal = Vector3.Lerp(a.Normal, b.Normal, t), }); }
private static bool Clip(Vertex4 v) { //cvv为 x-1,1 y-1,1 z0,1 if (v.Point.X >= -v.Point.W && v.Point.X <= v.Point.W && v.Point.Y >= -v.Point.W && v.Point.Y <= v.Point.W && v.Point.Z >= 0f && v.Point.Z <= v.Point.W) { return(true); } return(false); }
public void MoveEllipse(double deltaX, double deltaY) { Center.Move(deltaX, deltaY); Vertex1.Move(deltaX, deltaY); Vertex2.Move(deltaX, deltaY); Vertex3.Move(deltaX, deltaY); Vertex4.Move(deltaX, deltaY); Foci1.Move(deltaX, deltaY); Foci2.Move(deltaX, deltaY); Axis1.Move(deltaX, deltaY); Axis2.Move(deltaX, deltaY); BindingRectangle.Move(deltaX, deltaY); }
/// 小到大排序 private static void Sort(ref Vertex4 v1, ref Vertex4 v2, ref Vertex4 v3) { if (v1.Point.Y > v2.Point.Y) { Swap(ref v1, ref v2); } if (v2.Point.Y > v3.Point.Y) { Swap(ref v2, ref v3); } if (v1.Point.Y > v2.Point.Y) { Swap(ref v1, ref v2); } }
public Font(Frame frame) { CharWidth = 8; CharHeight = 8; this.frame = frame; mapWidth = 16; mapHeight = 16; texture = new FontTexture(Loader.LoadFontImage("0.png")); shader = new ShaderProgram( new Shader("font_vs.glsl", ShaderType.VertexShader), new Shader("font_fs.glsl", ShaderType.FragmentShader) ); vao = GL.GenVertexArray(); GL.BindVertexArray(vao); vbo = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.BufferData( BufferTarget.ArrayBuffer, Marshal.SizeOf(typeof(Vertex4)) * 4, IntPtr.Zero, BufferUsageHint.DynamicDraw ); Attribute attr = Vertex4.GetAttribute(shader, "vertex"); GL.EnableVertexAttribArray(attr.Index); GL.VertexAttribPointer( attr.Index, attr.SizeOfElements, VertexAttribPointerType.Float, false, attr.StrideOfElements * sizeof(float), attr.OffsetOfElements * sizeof(float) ); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(0); }
private static void FillFlatTriangle(Vertex4 v1, Vertex4 v2, Vertex4 v3, bool isFlatBottom) { if (isFlatBottom) { for (int scanlineY = (int)v2.Point.Y; scanlineY <= v1.Point.Y; scanlineY++) { float t = (scanlineY - v2.Point.Y) / (v1.Point.Y - v2.Point.Y); DrawFlatLine(Mathf.Lerp(v1, v2, t), Mathf.Lerp(v1, v3, t)); } } else { for (int scanlineY = (int)v1.Point.Y; scanlineY <= v2.Point.Y; scanlineY++) { float t = (scanlineY - v1.Point.Y) / (v2.Point.Y - v1.Point.Y); DrawFlatLine(Mathf.Lerp(v1, v2, t), Mathf.Lerp(v1, v3, t)); } } }
public Vertex4_6(BinaryStream s) { Vertex_4 = new Vertex4[4]; Vertex_6 = new Vertex6[2]; for (int i = 0; i < 4; i++) Vertex_4[i] = new Vertex4(s); for (int i = 0; i < 2; i++) Vertex_6[i] = new Vertex6(s); }