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; Listlv3Vertexes, 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:
Posts (Atom)
No comments:
Post a Comment