コード例 #1
0
 public Mesh(ObjLoader.Loader.Loaders.LoadResult result, Vector3 position, Vector3 rotation, float rotationAngle, Vector3 scale, float[] color)
 {
     // TODO: Complete member initialization
     this.result        = result;
     this.position      = position;
     this.rotation      = rotation;
     this.rotationAngle = rotationAngle;
     this.scale         = scale;
     this.color         = color;
 }
コード例 #2
0
        public void LoadObject(string filename)
        {
            try
            {
                // This OBJ parser library is developed by chrisjansson and available at https://github.com/chrisjansson/ObjLoader
                ObjLoader.Loader.Loaders.LoadResult obj = LoadOBJObject(filename);

                // This code assumes that all faces in all groups are defined as triangles or quads
                foreach (var group in obj.Groups)
                {
                    Group newGroup = new Group();
                    if (group.Material.DiffuseTextureMap != null)
                    {
                        newGroup.texture = ResourceManager.LoadTexture(group.Material.DiffuseTextureMap);
                        if (group.Material.BumpMap != null)
                        {
                            newGroup.bumpTexture = ResourceManager.LoadTexture(group.Material.BumpMap);
                        }
                        if (group.Material.DisplacementMap != null)
                        {
                            newGroup.displacementTexture = ResourceManager.LoadTexture(group.Material.DisplacementMap);
                        }
                    }
                    else
                    {
                        newGroup.texture = 0;
                    }
                    bool   error        = false;
                    string errorMessage = "";
                    bool   primitiveSet = false;
                    foreach (var face in group.Faces)
                    {
                        ++newGroup.numberOfFaces;

                        if (face.Count == 3)
                        {
                            if (primitiveSet && newGroup.primitiveScale != 3)
                            {
                                error        = true;
                                errorMessage = "The " + filename + " file has both triangular and quad faces and so will not be rendered correctly";
                            }
                            newGroup.primitiveType  = PrimitiveType.Triangles;
                            newGroup.primitiveScale = 3;
                            primitiveSet            = true;
                        }
                        else if (face.Count == 4)
                        {
                            if (primitiveSet && newGroup.primitiveScale != 4)
                            {
                                error        = true;
                                errorMessage = "The " + filename + " file has both triangular and quad faces and so will not be rendered correctly";
                            }
                            newGroup.primitiveType  = PrimitiveType.Quads;
                            newGroup.primitiveScale = 4;
                            primitiveSet            = true;
                        }
                        else
                        {
                            error        = true;
                            errorMessage = "The " + filename + " file does not have triangular or quad faces and so will not be rendered correctly";
                        }

                        for (int i = 0; i < face.Count; ++i)
                        {
                            // obj indexing starts at 1, so we need to subtract 1
                            int v = face[i].VertexIndex - 1;
                            newGroup.vertices.Add(obj.Vertices[v].X);
                            newGroup.vertices.Add(obj.Vertices[v].Y);
                            newGroup.vertices.Add(obj.Vertices[v].Z);

                            if (obj.Textures.Count > 0)
                            {
                                // obj indexing starts at 1, so we need to subtract 1
                                int t = face[i].TextureIndex - 1;
                                newGroup.textureCoords.Add(obj.Textures[t].X);
                                // OpenGL tex coords start at top-left
                                newGroup.textureCoords.Add(1.0f - obj.Textures[t].Y);
                            }

                            if (obj.Normals.Count > 0)
                            {
                                // obj indexing starts at 1, so we need to subtract 1
                                int n = face[i].NormalIndex - 1;
                                newGroup.normals.Add(obj.Normals[n].X);
                                newGroup.normals.Add(obj.Normals[n].Y);
                                newGroup.normals.Add(obj.Normals[n].Z);
                            }

                            //for creating tangent/binormal
                            if (newGroup.textureCoords.Count > 0)
                            {
                                int vIndex1 = face[0].VertexIndex - 1;
                                int vIndex2 = face[1].VertexIndex - 1;
                                int vIndex3 = face[2].VertexIndex - 1;

                                Vector3 face1 = new Vector3(obj.Vertices[vIndex1].X, obj.Vertices[vIndex1].Y, obj.Vertices[vIndex1].Z);
                                Vector3 face2 = new Vector3(obj.Vertices[vIndex2].X, obj.Vertices[vIndex2].Y, obj.Vertices[vIndex2].Z);
                                Vector3 face3 = new Vector3(obj.Vertices[vIndex3].X, obj.Vertices[vIndex3].Y, obj.Vertices[vIndex3].Z);

                                Vector3 p21 = Vector3.Subtract(face2, face1);
                                Vector3 p31 = Vector3.Subtract(face3, face1);


                                int tIndex1 = face[0].TextureIndex - 1;
                                int tIndex2 = face[1].TextureIndex - 1;
                                int tIndex3 = face[2].TextureIndex - 1;

                                Vector2 tex1 = new Vector2(obj.Textures[tIndex1].X, obj.Textures[tIndex1].Y);
                                Vector2 tex2 = new Vector2(obj.Textures[tIndex2].X, obj.Textures[tIndex2].Y);
                                Vector2 tex3 = new Vector2(obj.Textures[tIndex3].X, obj.Textures[tIndex3].Y);


                                Vector2 uv21 = Vector2.Subtract(tex2, tex1);
                                Vector2 uv31 = Vector2.Subtract(tex3, tex1);

                                Vector3 calculatedTangent = Vector3.Subtract(Vector3.Multiply(p21, uv31.Y), Vector3.Multiply(p31, uv21.Y));
                                calculatedTangent.Normalize();

                                newGroup.tangents.Add(calculatedTangent.X);
                                newGroup.tangents.Add(calculatedTangent.Y);
                                newGroup.tangents.Add(calculatedTangent.Z);

                                Vector3 calculatedBinormal = Vector3.Subtract(Vector3.Multiply(p31, uv21.X), Vector3.Multiply(p21, uv31.X));
                                calculatedBinormal.Normalize();

                                newGroup.binormals.Add(calculatedBinormal.X);
                                newGroup.binormals.Add(calculatedBinormal.Y);
                                newGroup.binormals.Add(calculatedBinormal.Z);

                                //GL.BindAttribLocation(newGroup.vao_Handle, 12, "tangent");
                                //GL.BindAttribLocation(newGroup.vao_Handle, 13, "binormal");
                            }
                        }
                    }

                    if (error)
                    {
                        MessageBox.Show(errorMessage, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }



                    // Create the single VAO that will hold all information for this group
                    GL.GenVertexArrays(1, out newGroup.vao_Handle);
                    GL.BindVertexArray(newGroup.vao_Handle);

                    // Create the buffer for the vertices
                    GL.GenBuffers(1, out newGroup.vbo_verts);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, newGroup.vbo_verts);
                    GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(newGroup.vertices.Count * 4), newGroup.vertices.ToArray <float>(), BufferUsageHint.StaticDraw);
                    GL.EnableVertexAttribArray(0);
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * 4, 0);

                    // Tex Coords
                    if (obj.Textures.Count > 0)
                    {
                        // Create the buffer for the texture coords
                        GL.GenBuffers(1, out newGroup.vbo_texs);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, newGroup.vbo_texs);
                        GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(newGroup.textureCoords.Count * 4), newGroup.textureCoords.ToArray <float>(), BufferUsageHint.StaticDraw);
                        GL.EnableVertexAttribArray(1);
                        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 2 * 4, 0);
                    }

                    // Normals
                    if (obj.Normals.Count > 0)
                    {
                        // Create the buffer for the normals
                        GL.GenBuffers(1, out newGroup.vbo_normals);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, newGroup.vbo_normals);
                        GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(newGroup.normals.Count * 4), newGroup.normals.ToArray <float>(), BufferUsageHint.StaticDraw);
                        GL.EnableVertexAttribArray(2);
                        GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 3 * 4, 0);
                    }

                    //tangents
                    if (newGroup.tangents.Count > 0)
                    {
                        // Create the buffer for the tangents
                        GL.GenBuffers(1, out newGroup.vbo_tangents);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, newGroup.vbo_tangents);
                        GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(newGroup.normals.Count * 4), newGroup.tangents.ToArray <float>(), BufferUsageHint.StaticDraw);
                        GL.EnableVertexAttribArray(3);
                        GL.VertexAttribPointer(3, 3, VertexAttribPointerType.Float, false, 3 * 4, 0);
                    }

                    //binormals
                    if (newGroup.binormals.Count > 0)
                    {
                        // Create the buffer for the tangents
                        GL.GenBuffers(1, out newGroup.vbo_binormals);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, newGroup.vbo_binormals);
                        GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(newGroup.normals.Count * 4), newGroup.binormals.ToArray <float>(), BufferUsageHint.StaticDraw);
                        GL.EnableVertexAttribArray(4);
                        GL.VertexAttribPointer(4, 3, VertexAttribPointerType.Float, false, 3 * 4, 0);
                    }

                    groups.Add(newGroup);
                    GL.BindVertexArray(0);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }