0
\$\begingroup\$

i am losing my mind. I am trying to create an obj parser has a way to learn opengl but i have ran into a brick wall. with DMGregory help i got the textures to work i think but know the mesh just looks like a blob

--Result--

Hmmm

--Obj parser code--

using OpenTK.Mathematics;
using System.Runtime.InteropServices;

using Core.Common.Objects;

namespace Core.Common
{
    public class LoadModel
    {
        public (vertex[] vertices, int[] indices) LoadObj(string path)
        {
            List<Vector3> Positions = new List<Vector3>();
            List<Vector2> texCoords = new List<Vector2>();


            List<int> position_Indices = new List<int>();
            List<int> texture_Indices = new List<int>();


            int[] indicesArray = null;
            vertex[] vertices = null;

            Console.ForegroundColor = ConsoleColor.DarkBlue;
            Console.WriteLine("loading " + path + " ... ");
            Console.ResetColor();

            string[] lines = File.ReadAllLines(path);

            foreach (string line in lines)
            {
                string[] parts = line.Split(' ');

                switch (parts[0])
                {
                    case "v":
                        Vector3 pos = new Vector3(Convert.ToSingle(parts[1]), Convert.ToSingle(parts[2]), Convert.ToSingle(parts[3]));
                        Positions.Add(pos);
                        break;

                    case "vt":
                        Vector2 texture = new Vector2(float.Parse(parts[1]), float.Parse(parts[2]));
                        texCoords.Add(texture);
                        break;

                    case "f":
                        string[] vertex1 = parts[1].Split('/');
                        string[] vertex2 = parts[2].Split('/');
                        string[] vertex3 = parts[3].Split('/');

                        int index1 = int.Parse(vertex1[0]) - 1;
                        int index2 = int.Parse(vertex2[0]) - 1;
                        int index3 = int.Parse(vertex3[0]) - 1;

                        int texIndex1 = Int32.Parse(vertex1[1]) - 1;
                        int texIndex2 = Int32.Parse(vertex2[1]) - 1;
                        int texIndex3 = Int32.Parse(vertex3[1]) - 1;

                        position_Indices.Add(index1);
                        position_Indices.Add(index2);
                        position_Indices.Add(index3);

                        texture_Indices.Add(texIndex1);
                        texture_Indices.Add(texIndex2);
                        texture_Indices.Add(texIndex3);



                        break;
                }
            }
            
            // bellow is modified\\

            indicesArray = new int[position_Indices.Count];
            vertices = new vertex[position_Indices.Count];

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i].pos = Positions[position_Indices[i]];
                vertices[i].tex = texCoords[texture_Indices[i]];
            }

            for (int i = 0; i < position_Indices.Count; i++)
            {
                indicesArray[i] = i;
            }

            foreach (var item in vertices)
            {
                Console.WriteLine(item.pos);
            }


            return (vertices, indicesArray); //return modeldata and faces
        }




    }
}

--Rendering code--

using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using System.Runtime.InteropServices;


using Core.Common.Objects;
using Core.Render;

namespace Core.Common
{
    public class Loader
    {
        private List<int> vbos = new List<int>();
        private List<int> vaos = new List<int>();
    

        public RawModel loadModel(vertex[] verts, int[] indices, string texPath)
        {
            int vao = createVAO();
            vbos.Add(vao);
            bindIndicesBuffer(indices);
            storeDataInPosAttribList(0, 3, verts, vertex.Stride);
            storeDataInTexAttribList(1, 2, verts, vertex.Stride);
            loadTexture(texPath);
            unbindVAO();
            return new RawModel(vao, indices.Length);
        }

        private int createVAO()
        {
            int vao = GL.GenVertexArray();
            GL.BindVertexArray(vao);
            return vao;
        }

        private void loadTexture(string path)
        {
            Texture texture;
            texture = Texture.LoadFromFile(path);
            texture.Use(TextureUnit.Texture0);
        }
        
        private void storeDataInPosAttribList(int attribNum, int size, vertex[]  verts, int stride)
        {
            int vbo = GL.GenBuffer();
            vbos.Add(vbo);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // bellow is modified\\
            GL.BufferData(BufferTarget.ArrayBuffer, stride * Vector3.SizeInBytes, ref verts[0].pos, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(attribNum, size, VertexAttribPointerType.Float, false, 0, 0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }

        private void storeDataInTexAttribList(int attribNum, int size, vertex[] tex, int stride)
        {
            int vbo = GL.GenBuffer();
            vbos.Add(vbo);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // bellow is modified\\
            GL.BufferData(BufferTarget.ArrayBuffer, stride * Vector2.SizeInBytes, ref tex[0].tex, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(attribNum, size, VertexAttribPointerType.Float, false, 0, 0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }

        private void unbindVAO()
        {
            GL.BindVertexArray(0);
        }

        private void bindIndicesBuffer(int[] indices)
        {
            int vbo = GL.GenBuffer();
            vbos.Add(vbo);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, vbo);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(int), indices, BufferUsageHint.StaticDraw);
        }



        public void cleanUP()
        {
            foreach (var item in vaos)
            {
                GL.DeleteVertexArray(item);
            }

            foreach (var item in vbos)
            {
                GL.DeleteBuffer(item);
            }

        }

    }
}
\$\endgroup\$
11
  • \$\begingroup\$ ok i was looking at the what sort of data was being added to the texture list. and fore some reason its a complete mess. this is what appears in the console (0.250043, 0.5) (0.5, 0.5) (0.250043, 0.250043) (0.5, 0.250043) (8.7E-05, 0.5) (0.250043, 0.749957) (0.749957, 0.5) (0.5, 0.749957) (8.7E-05, 0.250043) (0.250043, 8.7E-05) (0.250043, 0.999914) (0.5, 0.999914) (0.5, 8.7E-05) (0.749957, 0.250043) \$\endgroup\$ Mar 19 at 2:33
  • \$\begingroup\$ You construct a vertices array, but don't return it? Remember, there's no guarantee your positions and texture coordinates are in the same order or even have the same number of elements - that's why you build a vertices array that has them properly interleaved. \$\endgroup\$
    – DMGregory
    Mar 19 at 2:37
  • \$\begingroup\$ this is what happens when i try to use the vertex array imgur.com/a/K3NtvEw ``` \$\endgroup\$ Mar 19 at 2:52
  • \$\begingroup\$ Because your index array is written assuming you're not using the vertex array. With the way you're building your vertex array, your index array should just be the whole numbers [0, 1, 2, 3, 4, 5...] \$\endgroup\$
    – DMGregory
    Mar 19 at 3:03
  • \$\begingroup\$ sorry for not responding quickly. what would be the best way for me to have the index array use whole numbers? \$\endgroup\$ Mar 19 at 3:17

1 Answer 1

0
\$\begingroup\$

Special thanks to DMGregory for dealing with my doubts.

I solved my problem by creating a new list of Vectors:

List<Vector3> out_verts = new List<Vector3>();
List<Vector2> out_uv = new List<Vector2>();

Then, I iterate through a list of indices:

for (int i = 0; i < position_Indices.Count; i++)
{
    out_verts.Add(Positions[position_Indices[i]]);
    out_uv.Add(texCoords[texture_Indices[i]]);
}

I create the indices array with the whole number of the index list:

indicesArray = new int[position_Indices.Count];

for (int i = 0; i < position_Indices.Count; i++)
{
    indicesArray[i] = i;
}

Finally, the renderer multiplies the lists by the size of the specified vector:

GL.BufferData(BufferTarget.ArrayBuffer, Vector3.SizeInBytes * verts.Count, verts.ToArray(), BufferUsageHint.StaticDraw);
GL.BufferData(BufferTarget.ArrayBuffer, Vector2.SizeInBytes * tex.Count, tex.ToArray(), BufferUsageHint.StaticDraw);

Final result:

enter image description here

(I'm not very good at explaining things, so I hope all this makes sense.)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .