241 lines
4.7 KiB
C#
241 lines
4.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
|
|
|
|
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
|
|
);
|
|
}
|
|
|
|
Vector3[] normals = Model3D.computeNormals(vertexes);
|
|
|
|
Dictionary<Vector3,List<Vector3>> dNormals = new Dictionary<Vector3, List<Vector3>>();
|
|
|
|
foreach (Vector3 v in vertexes){
|
|
if (!dNormals.ContainsKey(v)){
|
|
dNormals.Add(v,new List<Vector3>());
|
|
}
|
|
}
|
|
|
|
for (int n=0;n<vertexes.Length;n++){
|
|
dNormals[ vertexes[n] ].Add(normals[n]);
|
|
}
|
|
|
|
foreach (Vector3 v in dNormals.Keys){
|
|
Vector3 s = new Vector3();
|
|
foreach (Vector3 n in dNormals[v]){
|
|
s += n;
|
|
}
|
|
s /= dNormals[v].Count;
|
|
dNormals[v].Clear();
|
|
dNormals[v].Add(s);
|
|
}
|
|
|
|
for (int n=0;n<vertexes.Length;n++){
|
|
normals[n] = dNormals[ vertexes[n] ][0];
|
|
}
|
|
|
|
bind(vertexes, colors, normals);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|