budnhead/SquaredMap.cs

206 lines
4.3 KiB
C#

using System;
using System.IO;
using OpenTK.Graphics.OpenGL4;
using OpenTK;
namespace nhengine
{
public class SquaredMap
{
private int width,
height;
private double[] heightMap;
private int[] tileTypes;
/* GL shared resources */
private int vao, cao, nao, ebo;
private int bufVertices;
private float[]
vertices;
private float[]
colors,
normals;
private int[] elements;
private ShaderProgram
shaderProgram;
public SquaredMap(int width,int height)
{
this.width = width;
this.height = height;
this.heightMap = new double[getVertexIndex(width,height) + 1];
this.tileTypes = new int[getTileIndex(width,height) + 1];
shaderProgram = new ShaderProgram(
new FileStream("shader/simple_vertex.shader",FileMode.Open),
new FileStream("shader/simple_fragment.shader",FileMode.Open)
);
prepareGL();
computeGL();
dumpGL();
}
private void prepareGL(){
vao = GL.GenVertexArray();
cao = GL.GenBuffer();
nao = GL.GenBuffer();
ebo = GL.GenBuffer();
bufVertices = GL.GenBuffer();
}
public void computeGL(){
int b;
if (vertices == null){
vertices = new float[heightMap.Length * 3];
}
if (elements == null){
elements = new int[width * height * 6];
}
if (colors == null){
colors = new float[heightMap.Length * 3];
normals = new float[colors.Length];
}
Random rand = new Random();
for (int x = 0; x <= width;x++)
{
for (int y = 0; y <= height;y++){
b = 3 * getVertexIndex(x, y);
vertices[b + 0] = 128 * x;
vertices[b + 1] = 128 * y;
float h = (float)rand.NextDouble();
vertices[b + 2] = (float)(256 * (h * h));
colors[b + 0] = 0.3f + 0.7f * (float)vertices[b + 2] / 256.0f;
colors[b + 1] = 0.2f + 0.8f * (float)vertices[b + 2] / 256.0f;
colors[b + 2] = 0.4f + 0.6f * (float)vertices[b + 2] / 256.0f;
}
}
for (int x = 0; x < width;x++)
{
for (int y = 0; y < height;y++){
b = 6 * getTileIndex(x, y);
elements[b + 0] = x + (y * (width + 1));
elements[b + 1] = x + (y * (width + 1)) + 1;
elements[b + 2] = x + ((y + 1) * (width + 1));
elements[b + 3] = x + ((y + 1) * (width + 1));
elements[b + 4] = x + (y * (width + 1)) + 1;
elements[b + 5] = x + ((y + 1) * (width + 1)) + 1;
}
}
GL.BindVertexArray(vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, bufVertices);
GL.BufferData(BufferTarget.ArrayBuffer, 4 * vertices.Length, vertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(0,
3,
VertexAttribPointerType.Float,
false,
0,
0);
GL.BindBuffer(BufferTarget.ArrayBuffer, cao);
GL.BufferData(BufferTarget.ArrayBuffer, 4 * colors.Length, colors, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(1,
3,
VertexAttribPointerType.Float,
false,
0,
0);
GL.EnableVertexAttribArray(0);
GL.EnableVertexAttribArray(1);
GL.BindBuffer(BufferTarget.ElementArrayBuffer,ebo);
GL.BufferData(BufferTarget.ElementArrayBuffer, 4 * elements.Length, elements, BufferUsageHint.StaticDraw);
GL.BindVertexArray(0);
}
void dumpGL(){
Console.WriteLine("Vertices:");
for (int x = 0; x < 8;x++){
Console.WriteLine("{0}", vertices[x]);
}
}
private int getTileIndex(int x, int y)
{
return x + (y * this.width);
}
private int getVertexIndex(int x,int y){
return x + (y * (this.width + 1));
}
private int getTileType(int x, int y)
{
int ind = getTileIndex(x, y);
if ((ind < 0) || (ind > tileTypes.Length))
{
return 0;
}
return this.tileTypes[ind];
}
private int getTileType(int ind)
{
if ((ind < 0) || (ind > tileTypes.Length))
{
return 0;
}
return this.tileTypes[ind];
}
private double getHeight(int ind)
{
if ((ind < 0) || (ind > heightMap.Length))
{
return 0;
}
return this.heightMap[ind];
}
public void paint(GLCamera camera){
Matrix4 pmat = camera.Matrix;
GL.UseProgram(shaderProgram.ID);
int pm = GL.GetUniformLocation(shaderProgram.ID, "proj_matrix");
GL.UniformMatrix4(pm, false, ref pmat);
GL.BindVertexArray(vao);
GL.DrawElements(BeginMode.Triangles, elements.Length, DrawElementsType.UnsignedInt, 0);
GL.BindVertexArray(0);
}
}
}