budnhead/org.niclasundharald.engine/graphics/Model3D.cs

171 lines
4.3 KiB
C#

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);
}
if (normals != null){
float[] fn = new float[ normals.Length * 3];
for (int n=0;n<normals.Length;n++){
fn[(n * 3) ] = normals[n].X;
fn[(n * 3) + 1] = normals[n].Y;
fn[(n * 3) + 2] = normals[n].Z;
}
GL.BindBuffer(BufferTarget.ArrayBuffer, nbo);
GL.BufferData(BufferTarget.ArrayBuffer, 3 * fn.Length, fn, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(2);
} else {
float[] fn = new float[fv.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();
fn[(n * 3) ] = normal.X;
fn[(n * 3) + 1] = normal.Y;
fn[(n * 3) + 2] = normal.Z;
fn[(n * 3) + 3] = normal.X;
fn[(n * 3) + 4] = normal.Y;
fn[(n * 3) + 5] = normal.Z;
fn[(n * 3) + 6] = normal.X;
fn[(n * 3) + 7] = normal.Y;
fn[(n * 3) + 8] = normal.Z;
}
GL.BindBuffer(BufferTarget.ArrayBuffer, nbo);
GL.BufferData(BufferTarget.ArrayBuffer, 3 * fn.Length, fn, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(2);
}
}
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;
}
}
}