예제 #1
0
        /// <summary>Create an OpenGL/OpenTK VAO for a mesh</summary>
        /// <param name="isDynamic"></param>
        public static void CreateVAO(ref Mesh mesh, bool isDynamic)
        {
            var hint = isDynamic ? BufferUsageHint.DynamicDraw : BufferUsageHint.StaticDraw;

            var vertexData = new List <LibRenderVertex>();
            var indexData  = new List <ushort>();

            var normalsVertexData = new List <LibRenderVertex>();
            var normalsIndexData  = new List <ushort>();

            for (int i = 0; i < mesh.Faces.Length; i++)
            {
                mesh.Faces[i].IboStartIndex        = indexData.Count;
                mesh.Faces[i].NormalsIboStartIndex = normalsIndexData.Count;

                foreach (var vertex in mesh.Faces[i].Vertices)
                {
                    var data = new LibRenderVertex
                    {
                        Position = mesh.Vertices[vertex.Index].Coordinates,
                        Normal   = vertex.Normal,
                        UV       = new Vector2f(mesh.Vertices[vertex.Index].TextureCoordinates)
                    };

                    var coloredVertex = mesh.Vertices[vertex.Index] as ColoredVertex;

                    if (coloredVertex != null)
                    {
                        data.Color = coloredVertex.Color;
                    }
                    else
                    {
                        data.Color = Color128.White;
                    }

                    vertexData.Add(data);

                    var normalsData = new LibRenderVertex[2];
                    normalsData[0].Position = data.Position;
                    normalsData[1].Position = data.Position + data.Normal;

                    for (int j = 0; j < normalsData.Length; j++)
                    {
                        normalsData[j].Color = Color128.White;
                    }

                    normalsVertexData.AddRange(normalsData);
                }

                indexData.AddRange(Enumerable.Range(mesh.Faces[i].IboStartIndex, mesh.Faces[i].Vertices.Length).Select(x => (ushort)x));
                normalsIndexData.AddRange(Enumerable.Range(mesh.Faces[i].NormalsIboStartIndex, mesh.Faces[i].Vertices.Length * 2).Select(x => (ushort)x));
            }

            VertexArrayObject VAO = (VertexArrayObject)mesh.VAO;

            VAO?.UnBind();
            VAO?.Dispose();

            VAO = new VertexArrayObject();
            VAO.Bind();
            VAO.SetVBO(new VertexBufferObject(vertexData.ToArray(), hint));
            VAO.SetIBO(new IndexBufferObject(indexData.ToArray(), hint));
            VAO.UnBind();
            mesh.VAO = VAO;
            VertexArrayObject NormalsVAO = (VertexArrayObject)mesh.NormalsVAO;

            NormalsVAO?.UnBind();
            NormalsVAO?.Dispose();

            NormalsVAO = new VertexArrayObject();
            NormalsVAO.Bind();
            NormalsVAO.SetVBO(new VertexBufferObject(normalsVertexData.ToArray(), hint));
            NormalsVAO.SetIBO(new IndexBufferObject(normalsIndexData.ToArray(), hint));
            NormalsVAO.UnBind();
            mesh.NormalsVAO = NormalsVAO;
        }
예제 #2
0
        /// <summary>Create an OpenGL/OpenTK VAO for a mesh</summary>
        /// <param name="isDynamic"></param>
        public static void CreateVAO(ref Mesh mesh, bool isDynamic, VertexLayout vertexLayout, BaseRenderer renderer)
        {
            try
            {
                var hint = isDynamic ? BufferUsageHint.DynamicDraw : BufferUsageHint.StaticDraw;

                var vertexData = new List <LibRenderVertex>();
                var indexData  = new List <uint>();

                var normalsVertexData = new List <LibRenderVertex>();
                var normalsIndexData  = new List <uint>();

                for (int i = 0; i < mesh.Faces.Length; i++)
                {
                    mesh.Faces[i].IboStartIndex        = indexData.Count;
                    mesh.Faces[i].NormalsIboStartIndex = normalsIndexData.Count;

                    foreach (var vertex in mesh.Faces[i].Vertices)
                    {
                        var data = new LibRenderVertex
                        {
                            Position = mesh.Vertices[vertex.Index].Coordinates,
                            Normal   = vertex.Normal,
                            UV       = new Vector2f(mesh.Vertices[vertex.Index].TextureCoordinates)
                        };

                        var coloredVertex = mesh.Vertices[vertex.Index] as ColoredVertex;

                        if (coloredVertex != null)
                        {
                            data.Color = coloredVertex.Color;
                        }
                        else
                        {
                            data.Color = Color128.Transparent;
                        }

                        vertexData.Add(data);

                        var normalsData = new LibRenderVertex[2];
                        normalsData[0].Position = data.Position;
                        normalsData[1].Position = data.Position + data.Normal;

                        for (int j = 0; j < normalsData.Length; j++)
                        {
                            normalsData[j].Color = Color128.White;
                        }

                        normalsVertexData.AddRange(normalsData);
                    }

                    indexData.AddRange(Enumerable.Range(mesh.Faces[i].IboStartIndex, mesh.Faces[i].Vertices.Length).Select(x => (uint)x));
                    normalsIndexData.AddRange(Enumerable.Range(mesh.Faces[i].NormalsIboStartIndex, mesh.Faces[i].Vertices.Length * 2).Select(x => (uint)x));
                }

                VertexArrayObject VAO = (VertexArrayObject)mesh.VAO;
                VAO?.UnBind();
                VAO?.Dispose();

                VAO = new VertexArrayObject();
                VAO.Bind();
                VAO.SetVBO(new VertexBufferObject(vertexData.ToArray(), hint));
                if (indexData.Count > 65530)
                {
                    //Marginal headroom, although it probably doesn't matter
                    VAO.SetIBO(new IndexBufferObjectI(indexData.ToArray(), hint));
                }
                else
                {
                    VAO.SetIBO(new IndexBufferObjectU(indexData.Select(x => (ushort)x).ToArray(), hint));
                }

                VAO.SetAttributes(vertexLayout);
                VAO.UnBind();
                mesh.VAO = VAO;
                VertexArrayObject NormalsVAO = (VertexArrayObject)mesh.NormalsVAO;
                NormalsVAO?.UnBind();
                NormalsVAO?.Dispose();

                NormalsVAO = new VertexArrayObject();
                NormalsVAO.Bind();
                NormalsVAO.SetVBO(new VertexBufferObject(normalsVertexData.ToArray(), hint));
                if (normalsIndexData.Count > 65530)
                {
                    //Marginal headroom, although it probably doesn't matter
                    NormalsVAO.SetIBO(new IndexBufferObjectI(normalsIndexData.ToArray(), hint));
                }
                else
                {
                    NormalsVAO.SetIBO(new IndexBufferObjectU(normalsIndexData.Select(x => (ushort)x).ToArray(), hint));
                }

                NormalsVAO.SetAttributes(vertexLayout);
                NormalsVAO.UnBind();
                mesh.NormalsVAO = NormalsVAO;
            }
            catch (Exception e)
            {
                renderer.ForceLegacyOpenGL = true;
                renderer.currentHost.AddMessage(MessageType.Error, false, "Creating VAO failed with the following error: " + e);
            }
        }