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\$ Commented Mar 19, 2023 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\$ Commented Mar 19, 2023 at 2:37
  • \$\begingroup\$ this is what happens when i try to use the vertex array imgur.com/a/K3NtvEw ``` \$\endgroup\$ Commented Mar 19, 2023 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\$ Commented Mar 19, 2023 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\$ Commented Mar 19, 2023 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.