public void GenerateNormals() { Vector3[] norms = new Vector3[vb.Count]; int[] count = new int[vb.Count]; foreach (var p in parts) { for (int i = 0; i < p.IndexBuffer.Count; i += 3) { int i1 = (int)p.IndexBuffer[i]; int i2 = (int)p.IndexBuffer[i + 1]; int i3 = (int)p.IndexBuffer[i + 2]; var v1 = vb[i1].Position; var v2 = vb[i2].Position; var v3 = vb[i3].Position; var c1 = v2 - v1; var c2 = v3 - v1; var cross = Vector3.Cross(c1, c2).Normalize(); norms[i1] += cross; norms[i2] += cross; norms[i3] += cross; ++count[i1]; ++count[i2]; ++count[i3]; } } for (int i = 0; i < norms.Length; i++) { VertexPositionTexCoordNormal n = vb[i]; n.Normal = norms[i] / count[i]; vb[i] = n; } }
public virtual void InitializeGraphics() { if (heightmap == null && string.IsNullOrEmpty(Heightmap)) return; if (heightmap == null) owner.Resources.Load(Heightmap, out heightmap); //if (heightmap.Width != heightmap.Height) //throw new NotSupportedException("Must be rectangular heightmap"); int num_vertices = (heightmap.Width) * (heightmap.Height); if (vb != null) DoDispose(); vb = new VertexBuffer<VertexPositionTexCoordNormal>(VertexPositionTexCoordNormal.Descriptor); vb.Allocate(num_vertices); if (mat_name != null) owner.Resources.Load(mat_name, out mat); size = CellSize * heightmap.Width; float s2 = size / 2; int vi = 0; float xx = 0; float yy = -s2; Vector3[,] norms = new Vector3[heightmap.Height, heightmap.Width]; for (int i = 0; i < heightmap.Height; i++) { for (int j = 0; j < heightmap.Width; j++) { Vector3 n = new Vector3(); n.x = (heightmap[i - 1, j] - heightmap[i + 1, j]) * Height; n.y = (heightmap[i, j - 1] - heightmap[i, j + 1]) * Height; n.z = 2.0f / (heightmap.Width + 1) / CellSize + 2.0f / (heightmap.Height + 1) / CellSize; norms[i, j] = n.Normalize(); } } for (int i = 0; i < heightmap.Height; i++) { xx = -s2; for (int j = 0; j < heightmap.Width; j++, vi++) { vb[vi] = new VertexPositionTexCoordNormal() { Position = new Vector3(xx, heightmap[i, j] * Height, yy), Normal = norms[i, j] }; xx += CellSize; } yy += CellSize; } float offset = s2 / 2; int x_count = heightmap.Width / 2; int y_count = heightmap.Height / 2; var new_size = new Vector3(s2, size / 8, s2); blocks = new TerrainBlock[4]; blocks[0] = new TerrainBlock(0, 0, x_count, y_count, new BoundingBox() { Size = new_size, Position = new Vector3(-offset, 0, offset) }, 0, this); blocks[1] = new TerrainBlock(x_count-1, 0, x_count, y_count, new BoundingBox() { Size = new_size, Position = new Vector3(offset, 0, offset) }, 0, this); blocks[2] = new TerrainBlock(x_count-1, y_count-1, x_count, y_count, new BoundingBox() { Size = new_size, Position = new Vector3(offset, 0, -offset) }, 0, this); blocks[3] = new TerrainBlock(0, y_count-1, x_count, y_count, new BoundingBox() { Size = new_size, Position = new Vector3(-offset, 0, -offset) }, 0, this); vb.BufferData(VboUsage.GL_STATIC_DRAW); vb.FreeClientData(); init_finished = true; }
public override Model Build() { Model ret = new Model(); VertexBuffer<VertexPositionTexCoordNormal> vb = new VertexBuffer<VertexPositionTexCoordNormal>(VertexPositionTexCoordNormal.Descriptor); //IndexBuffer<uint> ib = new IndexBuffer<uint>(); float ang_inc = (float)(2 * Math.PI) / sides; int vsides = sides / 2 - 2; float ang = 0; vb.Allocate(sides * (sides / 2 - 2) + 2); int index = 0; for (int i = 0; i < sides; i++, ang += ang_inc) { float cs = (float)Math.Cos(ang); float ss = (float)Math.Sin(ang); float sang_inc = (float)Math.PI / vsides; float sang = -((float)Math.PI / 2) + sang_inc; for (int j = 0; j < vsides; j++, sang += sang_inc, ++index) { float vcs = (float)Math.Cos(sang); float vss = (float)Math.Sin(sang); Vector3 pos = new Vector3( cs * radius * vcs, vss * radius, ss * radius * vss); vb[index] = new VertexPositionTexCoordNormal() { Position = pos, TexCoord = new Vector2(), Normal = new Vector3(cs * vcs, vss, ss * vss) }; } vb[index] = new VertexPositionTexCoordNormal() { Position = new Vector3(0, -radius, 0), Normal = new Vector3(0, -1, 0) }; vb[index + 1] = new VertexPositionTexCoordNormal() { Position = new Vector3(0, radius, 0), Normal = new Vector3(0, radius, 0) }; } ret.VertexBuffer = vb; vb.BufferData(Glorg2.Graphics.OpenGL.VboUsage.GL_STATIC_DRAW); return ret; }
public override Model Build() { Model ret = new Model(); var w2 = width / 2; var h2 = height / 2; var d2 = depth / 2; ret.VertexBuffer = new VertexBuffer<VertexPositionTexCoordNormal>(VertexPositionTexCoordNormal.Descriptor); ret.VertexBuffer.Allocate(24); var vb = ret.VertexBuffer; var ib = new IndexBuffer<uint>(); //ib.Allocate(36); Vector3[] pos = new Vector3[8]; pos[0] = new Vector3(-w2, h2, d2); pos[1] = new Vector3(w2, h2, d2); pos[2] = new Vector3(w2, h2, -d2); pos[3] = new Vector3(-w2, h2, -d2); pos[4] = new Vector3(-w2, -h2, d2); pos[5] = new Vector3(w2, -h2, d2); pos[6] = new Vector3(w2, -h2, -d2); pos[7] = new Vector3(-w2, -h2, -d2); ret.Parts.Add( new ModelPart() { IndexBuffer = ib } ); vb[0] = new VertexPositionTexCoordNormal() { Position = pos[0], Normal = Vector3.Up, TexCoord = new Vector2(0, 0) }; vb[1] = new VertexPositionTexCoordNormal() { Position = pos[1], Normal = Vector3.Up, TexCoord = new Vector2(1, 0) }; vb[2] = new VertexPositionTexCoordNormal() { Position = pos[2], Normal = Vector3.Up, TexCoord = new Vector2(1, 1) }; vb[3] = new VertexPositionTexCoordNormal() { Position = pos[3], Normal = Vector3.Up, TexCoord = new Vector2(0, 1) }; vb[4] = new VertexPositionTexCoordNormal() { Position = pos[7], Normal = Vector3.Down, TexCoord = new Vector2(0, 0) }; vb[5] = new VertexPositionTexCoordNormal() { Position = pos[6], Normal = Vector3.Down, TexCoord = new Vector2(1, 0) }; vb[6] = new VertexPositionTexCoordNormal() { Position = pos[5], Normal = Vector3.Down, TexCoord = new Vector2(1, 1) }; vb[7] = new VertexPositionTexCoordNormal() { Position = pos[4], Normal = Vector3.Down, TexCoord = new Vector2(0, 1) }; vb[8] = new VertexPositionTexCoordNormal() { Position = pos[4], Normal = Vector3.North, TexCoord = new Vector2(0, 0) }; vb[9] = new VertexPositionTexCoordNormal() { Position = pos[5], Normal = Vector3.North, TexCoord = new Vector2(0, 0) }; vb[10] = new VertexPositionTexCoordNormal() { Position = pos[1], Normal = Vector3.North, TexCoord = new Vector2(0, 0) }; vb[11] = new VertexPositionTexCoordNormal() { Position = pos[0], Normal = Vector3.North, TexCoord = new Vector2(0, 0) }; vb[12] = new VertexPositionTexCoordNormal() { Position = pos[0], Normal = Vector3.West, TexCoord = new Vector2() }; vb[13] = new VertexPositionTexCoordNormal() { Position = pos[3], Normal = Vector3.West, TexCoord = new Vector2() }; vb[14] = new VertexPositionTexCoordNormal() { Position = pos[7], Normal = Vector3.West, TexCoord = new Vector2() }; vb[15] = new VertexPositionTexCoordNormal() { Position = pos[4], Normal = Vector3.West, TexCoord = new Vector2() }; vb[16] = new VertexPositionTexCoordNormal() { Position = pos[3], Normal = Vector3.South, TexCoord = new Vector2() }; vb[17] = new VertexPositionTexCoordNormal() { Position = pos[2], Normal = Vector3.South, TexCoord = new Vector2() }; vb[18] = new VertexPositionTexCoordNormal() { Position = pos[6], Normal = Vector3.South, TexCoord = new Vector2() }; vb[19] = new VertexPositionTexCoordNormal() { Position = pos[7], Normal = Vector3.South, TexCoord = new Vector2() }; vb[23] = new VertexPositionTexCoordNormal() { Position = pos[1], Normal = Vector3.East, TexCoord = new Vector2() }; vb[22] = new VertexPositionTexCoordNormal() { Position = pos[2], Normal = Vector3.East, TexCoord = new Vector2() }; vb[21] = new VertexPositionTexCoordNormal() { Position = pos[6], Normal = Vector3.East, TexCoord = new Vector2() }; vb[20] = new VertexPositionTexCoordNormal() { Position = pos[5], Normal = Vector3.East, TexCoord = new Vector2() }; int offset = 0; ib.Allocate(36); for (int i = 0; i < 6; i++) { offset = AddFaces(i * 4, offset, ib); } vb.BufferData(Glorg2.Graphics.OpenGL.VboUsage.GL_STATIC_DRAW); ib.BufferData(Glorg2.Graphics.OpenGL.VboUsage.GL_STATIC_DRAW); return ret; }