using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
[assembly: AssemblyProduct("OpenTK/OpenGL Library")]
[assembly: AssemblyCopyright("Copyright © Jason Beighel")]
[assembly: AssemblyTrademark("Mindlence")]
[assembly: AssemblyVersion("0.1.0.1")]
[assembly: AssemblyFileVersion("0.1.0.1")]
namespace MDLN {
namespace GLTools {
class GLModel {
private Vector3[] cav3Vertexes, cav3Normals;
private Vector2[] cav2UVCoords;
private bool cbVertexChange, cbNormalChange, cbUVCoordsChange;
private Vector4 cv4BaseColor;
private int ciUniformBuffer, ciUniformID, ciVertexBuffer, ciVertexID;
private string cstrErrDesc;
public GLModel() {
int[] aiBuffList;
cbVertexChange = true;
cbNormalChange = true;
cbUVCoordsChange = true;
ciUniformBuffer = -1;
ciUniformID = -1;
ciVertexBuffer = -1;
ciVertexID = -1;
aiBuffList = new int[1];
GL.GenBuffers(aiBuffList.Length, aiBuffList);
ciVertexBuffer = aiBuffList[0];
}
public Vector4 BaseColor {
get {
return cv4BaseColor;
}
}
public int UniformBuffer {
get {
return ciUniformBuffer;
}
set {
ciUniformBuffer = value;
}
}
public int UniformID {
get {
return ciUniformID;
}
set {
ciUniformID = value;
}
}
public int VertexAttributeID {
get {
return ciVertexID;
}
set {
ciVertexID = value;
}
}
public string ErrorDescription {
get {
return cstrErrDesc;
}
}
public bool SetBaseColor(float fRed, float fGreen, float fBlue, float fAlpha) {
cv4BaseColor.X = fRed;
cv4BaseColor.Y = fGreen;
cv4BaseColor.Z = fBlue;
cv4BaseColor.W = fAlpha;
return true;
}
public bool LoadOBJFile(string strFile) {
string strChunk;
string[] astrLines, astrLineParts, astrFaceParts;
int iCtr, iCnt, iFaceCount, iCurrVert, iSrcIndex;
List lv3Vertexes, lv3Normals;
List lv2UVCoords;
Vector3 v3New;
Vector2 v2New;
StreamReader srModel;
cstrErrDesc = "";
iFaceCount = 0;
lv3Vertexes = new List();
lv3Normals = new List();
v3New = new Vector3();
lv2UVCoords = new List();
v2New = new Vector2();
srModel = new StreamReader(strFile);
strChunk = srModel.ReadToEnd();
srModel.Close();
astrLines = strChunk.Split('\n');
//First pass through the file: Load all vertex information
for (iCtr = 0; iCtr < astrLines.Length; iCtr++) {
astrLineParts = astrLines[iCtr].Split(' ');
switch (astrLineParts[0]) {
case "v" : //Vertex coordinates
v3New.X = float.Parse(astrLineParts[1], CultureInfo.InvariantCulture.NumberFormat);
v3New.Y = float.Parse(astrLineParts[2], CultureInfo.InvariantCulture.NumberFormat);
v3New.Z = float.Parse(astrLineParts[3], CultureInfo.InvariantCulture.NumberFormat);
lv3Vertexes.Add(v3New);
break;
case "vt" : //Vertex texture coordinates (UV Coordinates)
v2New.X = float.Parse(astrLineParts[1], CultureInfo.InvariantCulture.NumberFormat);
v2New.Y = float.Parse(astrLineParts[2], CultureInfo.InvariantCulture.NumberFormat);
lv2UVCoords.Add(v2New);
break;
case "vn" : //Vertex normal
v3New.X = float.Parse(astrLineParts[1], CultureInfo.InvariantCulture.NumberFormat);
v3New.Y = float.Parse(astrLineParts[2], CultureInfo.InvariantCulture.NumberFormat);
v3New.Z = float.Parse(astrLineParts[3], CultureInfo.InvariantCulture.NumberFormat);
lv3Normals.Add(v3New);
break;
case "f" : //Face information, just count them
iFaceCount++;
break;
default : //Unknown line information, skip it
break;
}
}
//Resize the class data arrays based on the number of faces
cav3Vertexes = new Vector3[iFaceCount * 3]; //1FaceCount has the number of faces
cav3Normals = new Vector3[iFaceCount * 3]; //Each face has 3 vertexes
cav2UVCoords = new Vector2[iFaceCount * 3];
//Second pass through the file: process all faces
iCurrVert = 0;
for (iCtr = 0; iCtr < astrLines.Length; iCtr++) {
astrLineParts = astrLines[iCtr].Split(' ');
switch (astrLineParts[0]) {
case "f" : //Face information
for (iCnt = 1; iCnt <= 3; iCnt++) {
astrFaceParts = astrLineParts[iCnt].Split('/');
//Copy vertex coordinates
iSrcIndex = Convert.ToInt32(astrFaceParts[0]) - 1; //Obj indexes start at 1, C# arrays start at 0
cav3Vertexes[iCurrVert].X = lv3Vertexes[iSrcIndex].X;
cav3Vertexes[iCurrVert].Y = lv3Vertexes[iSrcIndex].Y;
cav3Vertexes[iCurrVert].Z = lv3Vertexes[iSrcIndex].Z;
//Copy UV Coordinates
iSrcIndex = Convert.ToInt32(astrFaceParts[1]) - 1;
cav2UVCoords[iCurrVert].X = lv2UVCoords[iSrcIndex].X;
cav2UVCoords[iCurrVert].Y = lv2UVCoords[iSrcIndex].Y;
//Copy Normal values
iSrcIndex = Convert.ToInt32(astrFaceParts[2]) - 1;
cav3Normals[iCurrVert].X = lv3Normals[iSrcIndex].X;
cav3Normals[iCurrVert].Y = lv3Normals[iSrcIndex].Y;
cav3Normals[iCurrVert].Z = lv3Normals[iSrcIndex].Z;
iCurrVert++;
}
break;
default : //Ignore all other lines
break;
}
}
//Mark the arrays as needing updated
cbVertexChange = true;
cbNormalChange = true;
cbUVCoordsChange = true;
return true;
}
public bool RenderObject() {
cstrErrDesc = "";
float[] afUniformData;
//Be sure the buffer objects have been specified
if ((ciUniformID == -1)||(ciUniformBuffer == -1)) {
cstrErrDesc = "Unable to render with no Uniform Buffer or ID specified.";
return false;
}
if ((ciVertexBuffer == -1)||(ciVertexID == -1)) {
cstrErrDesc = "Unable to render with no Vertex Buffer or ID specified.";
return false;
}
//Check if buffer data needs refreshed
if (cbVertexChange == true) {
cstrErrDesc = cstrErrDesc + "Loading cube data, " + cav3Vertexes.Length + " vertices | size : " + (cav3Vertexes.Length * Vector3.SizeInBytes) + " \n";
GL.BindBuffer(BufferTarget.ArrayBuffer, ciVertexBuffer);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(cav3Vertexes.Length * Vector3.SizeInBytes), cav3Vertexes, BufferUsageHint.DynamicDraw);
cbVertexChange = false;
}
//Set Uniform buffer data
afUniformData = new float[4];
afUniformData[0] = cv4BaseColor.X;
afUniformData[1] = cv4BaseColor.Y;
afUniformData[2] = cv4BaseColor.Z;
afUniformData[3] = cv4BaseColor.W;
GL.BindBuffer(BufferTarget.UniformBuffer, ciUniformBuffer);
GL.BufferData(BufferTarget.UniformBuffer, (IntPtr)(afUniformData.Length * sizeof(float)), afUniformData, BufferUsageHint.DynamicDraw);
GL.BindBufferBase(BufferTarget.UniformBuffer, ciUniformID, ciUniformBuffer);
//Draw the model
GL.BindBuffer(BufferTarget.ArrayBuffer, ciVertexBuffer);
GL.EnableVertexAttribArray(ciVertexID);
GL.VertexAttribPointer(ciVertexID, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
GL.DrawArrays(BeginMode.Triangles, 0, cav3Vertexes.Length);
GL.DisableVertexAttribArray(ciVertexID);
return true;
}
}
}
}
GLModel Class v0.1.0.1 - 01-02-2014
Subscribe to:
Comments (Atom)
No comments:
Post a Comment