budnhead/NHEngine/SquaredMap.cs

211 lines
4.0 KiB
C#

using System;
using System.IO;
using ImageSharp;
using ImageSharp.PixelFormats;
using OpenTK.Graphics.OpenGL4;
using OpenTK;
using org.niclasundharald.engine;
using org.niclasundharald.engine.graphics;
namespace nhengine
{
public class SquaredMap : WorldObject
{
private static float edge = 64;
private int width,
height;
private float[] heightMap;
private MapModel3D model;
public SquaredMap(int width,int height)
{
this.width = width;
this.height = height;
this.heightMap = new float[ (width + 1) * (height + 1) ];
generateHeightMap();
computeModel();
}
public override Model3D getModel3D()
{
return this.model;
}
public SquaredMap(Image heightMap)
{
this.width = heightMap.Width-1;
this.height = heightMap.Height-1;
this.heightMap = new float[ (width + 1) * (height + 1) ];
loadHeightMap(heightMap);
computeModel();
}
public void generateHeightMap(){
Random rand = new Random();
for (int y = 0; y <= height; y++)
{
for (int x = 0; x <= width; x++)
{
float h = (float)rand.NextDouble();
heightMap[x + (y * width)] = (float)(256 * (h * h));
}
}
}
public void loadHeightMap(Image _heightMap){
Rgba32[] pixels = _heightMap.Pixels;
for (int y = 0; y <= height; y++)
{
for (int x = 0; x <= width; x++)
{
Rgba32 pixel = pixels[ x + (y * (width + 1))];
float h = (pixel.R + pixel.G + pixel.B) / 3;
heightMap[x + (y * (width + 1))] = (float)(h);
}
}
}
public void computeModel(){
float left,
right,
bottom,
top,
vcenter,
hcenter;
Vector3[] vertexes = new Vector3[ 18 * width * height ];
Console.WriteLine("Creating geometry");
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int i = x + ((width + 1) * y);
int j = x + ((width + 1) * (y + 1));
float[] h = new float[4];
h[0] = heightMap[i];
h[1] = heightMap[i+1];
h[2] = heightMap[j];
h[3] = heightMap[j+1];
float ah = (h[0] + h[1] + h[2] + h[3]) / 4.0f;
left = edge * x;
right = edge * (x + 1);
bottom = edge * y;
top = edge * (y + 1);
vcenter = (top + bottom) / 2.0f;
hcenter = (left + right) / 2.0f;
int b = 4 * (x + (width * y));
Model3D.setTriangle(
vertexes,
b,
new Vector3(left, top, h[2]),
new Vector3(right, top, h[3]),
new Vector3(hcenter,vcenter,ah)
);
Model3D.setTriangle(
vertexes,
b + 1,
new Vector3(right, top, h[3]),
new Vector3(right, bottom, h[1]),
new Vector3(hcenter, vcenter, ah)
);
Model3D.setTriangle(
vertexes,
b + 2,
new Vector3(right, bottom, h[1]),
new Vector3(left, bottom, h[0]),
new Vector3(hcenter, vcenter, ah)
);
Model3D.setTriangle(
vertexes,
b + 3,
new Vector3(left, bottom, h[0]),
new Vector3(left, top, h[2]),
new Vector3(hcenter, vcenter, ah)
);
}
}
/*
Console.WriteLine("Coloring...");
for (int n = 0; n < vertices.Length / 3;n++){
float _h = vertices[(3 * n) + 2] / 512.0f;
setColor(
n,
)
}
*/
this.model = new MapModel3D( vertexes );
this.Position = new Vector3(-(width)*edge,-(height)*edge,0);
}
}
class MapModel3D : Model3D {
int nDraw;
public MapModel3D(Vector3[] vertexes){
Vector4[] colors = new Vector4[ vertexes.Length ];
for (int n=0; n< vertexes.Length; n++){
if (vertexes[n].Z >= 256 ){
Console.WriteLine("Max. Height : {0}",vertexes[n].Z / 256);
}
colors[n] = new Vector4(
0.50f + (0.2f * vertexes[n].Z / 256),
0.25f + (0.50f * vertexes[n].Z / 256),
0.10f + (0.80f * vertexes[n].Z / 256),
1.0f
);
}
bind(vertexes, colors);
}
public override void draw()
{
nDraw+= nTriangles >> 8;
if (nDraw > nTriangles){
nDraw = 0;
}
nDraw = nTriangles;
GL.BindVertexArray(this.vao);
GL.DrawArrays(PrimitiveType.Triangles, 0, nDraw * 3);
GL.BindVertexArray(0);
}
}
}