2017-05-01 01:33:33 +02:00
|
|
|
using System;
|
|
|
|
|
|
|
|
using OpenTK.Graphics.OpenGL;
|
|
|
|
using OpenTK;
|
|
|
|
|
|
|
|
namespace org.niclasundharald.engine.graphics {
|
|
|
|
|
|
|
|
public class Model3D {
|
|
|
|
|
|
|
|
protected int vao,
|
|
|
|
vbo, // Vertex Buffer
|
|
|
|
cbo, // Color Buffer
|
|
|
|
nbo; // Normals Buffer
|
|
|
|
|
|
|
|
protected int nTriangles;
|
|
|
|
|
|
|
|
protected Model3D(){
|
|
|
|
vao = GL.GenVertexArray();
|
|
|
|
nTriangles = 0;
|
|
|
|
|
|
|
|
prepare();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void prepare(){
|
|
|
|
vbo = GL.GenBuffer();
|
|
|
|
cbo = GL.GenBuffer();
|
|
|
|
nbo = GL.GenBuffer();
|
|
|
|
|
|
|
|
GL.BindVertexArray(vao);
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
|
|
|
|
GL.VertexAttribPointer(0,
|
|
|
|
3,
|
|
|
|
VertexAttribPointerType.Float,
|
|
|
|
false,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, cbo);
|
|
|
|
GL.VertexAttribPointer(1,
|
|
|
|
4,
|
|
|
|
VertexAttribPointerType.Float,
|
|
|
|
false,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, nbo);
|
|
|
|
GL.VertexAttribPointer(2,
|
|
|
|
3,
|
|
|
|
VertexAttribPointerType.Float,
|
|
|
|
false,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
|
|
|
|
GL.BindVertexArray(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void bind(Vector3[] vertexes){
|
|
|
|
bind( vertexes, null, null, null );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void bind(Vector3[] vertexes,Vector4[] colors){
|
|
|
|
bind( vertexes, colors, null, null );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void bind(Vector3[] vertexes,Vector4[] colors,Vector3[] normals){
|
|
|
|
bind( vertexes, colors, normals, null );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void bind(Vector3[] vertexes,Vector4[] colors,Vector3[] normals,Vector2[] uvs){
|
|
|
|
float[] fv = new float[vertexes.Length * 3];
|
|
|
|
|
|
|
|
for (int n=0;n<vertexes.Length;n++){
|
|
|
|
fv[(n * 3) ] = vertexes[n].X;
|
|
|
|
fv[(n * 3) + 1] = vertexes[n].Y;
|
|
|
|
fv[(n * 3) + 2] = vertexes[n].Z;
|
|
|
|
}
|
|
|
|
|
|
|
|
GL.BindVertexArray(vao);
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
|
|
|
|
GL.BufferData(BufferTarget.ArrayBuffer, 4 * fv.Length, fv, BufferUsageHint.StaticDraw);
|
|
|
|
|
|
|
|
GL.EnableVertexAttribArray(0);
|
|
|
|
|
|
|
|
nTriangles = vertexes.Length / 3;
|
|
|
|
|
|
|
|
if (colors != null){
|
|
|
|
float[] fc = new float[ colors.Length * 4 ];
|
|
|
|
|
|
|
|
for (int n=0;n < colors.Length; n++){
|
|
|
|
fc[ (4*n) ] = colors[n].X;
|
|
|
|
fc[ (4*n) + 1 ] = colors[n].Y;
|
|
|
|
fc[ (4*n) + 2 ] = colors[n].Z;
|
|
|
|
fc[ (4*n) + 3 ] = colors[n].W;
|
|
|
|
}
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, cbo);
|
|
|
|
GL.BufferData(BufferTarget.ArrayBuffer, 4 * fc.Length, fc, BufferUsageHint.StaticDraw);
|
|
|
|
|
|
|
|
GL.EnableVertexAttribArray(1);
|
|
|
|
} else {
|
|
|
|
float[] fc = new float[ vertexes.Length * 4 ];
|
|
|
|
|
|
|
|
for (int n=0;n<fc.Length;n++){
|
|
|
|
fc[n] = n % 4 == 3 ? 1.0f : 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, cbo);
|
|
|
|
GL.BufferData(BufferTarget.ArrayBuffer, 4 * fc.Length, fc, BufferUsageHint.StaticDraw);
|
|
|
|
|
|
|
|
GL.EnableVertexAttribArray(1);
|
|
|
|
}
|
|
|
|
|
2017-05-01 11:26:54 +02:00
|
|
|
if (normals == null){
|
|
|
|
normals = computeNormals(vertexes);
|
2017-05-01 01:33:33 +02:00
|
|
|
}
|
|
|
|
|
2017-05-01 11:26:54 +02:00
|
|
|
float[] fn = v3aToArray(normals);
|
2017-05-01 01:33:33 +02:00
|
|
|
|
2017-05-01 11:26:54 +02:00
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, nbo);
|
|
|
|
GL.BufferData(BufferTarget.ArrayBuffer, 3 * fn.Length, fn, BufferUsageHint.StaticDraw);
|
2017-05-01 01:33:33 +02:00
|
|
|
|
2017-05-01 11:26:54 +02:00
|
|
|
GL.EnableVertexAttribArray(2);
|
2017-05-01 01:33:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void draw(){
|
|
|
|
GL.BindVertexArray(this.vao);
|
|
|
|
GL.DrawArrays(PrimitiveType.Triangles, 0, nTriangles * 3);
|
|
|
|
GL.BindVertexArray(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void setTriangle(Vector3[] vertexes,int n, Vector3 a, Vector3 b, Vector3 c)
|
|
|
|
{
|
|
|
|
vertexes[(3 * n)] = a;
|
|
|
|
vertexes[(3 * n)+1] = b;
|
|
|
|
vertexes[(3 * n)+2] = c;
|
|
|
|
}
|
|
|
|
|
2017-05-01 11:26:54 +02:00
|
|
|
public static Vector3[] computeNormals(Vector3[] vertexes){
|
|
|
|
Vector3[] normals = new Vector3[ vertexes.Length ];
|
|
|
|
|
|
|
|
for (int n=0;n<vertexes.Length;n+=3){
|
|
|
|
Vector3 normal = Vector3.Cross( vertexes[n+1] - vertexes[n], vertexes[n+2] - vertexes[n] );
|
|
|
|
normal.Normalize();
|
|
|
|
normals[(n) ] = normal;
|
|
|
|
normals[(n) + 1] = normal;
|
|
|
|
normals[(n) + 2] = normal;
|
|
|
|
}
|
|
|
|
|
|
|
|
return normals;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float[] v3aToArray(Vector3[] v3a){
|
|
|
|
float[] a = new float[ v3a.Length * 3];
|
|
|
|
|
|
|
|
for (int n=0;n<v3a.Length;n++){
|
|
|
|
a[ (3 * n) ] = v3a[n].X;
|
|
|
|
a[ (3 * n) + 1] = v3a[n].Y;
|
|
|
|
a[ (3 * n) + 2] = v3a[n].Z;
|
|
|
|
}
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
2017-05-01 01:33:33 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|