i'm trying to implement index buffer object in opentk but don't know how to actually use it when drawing things

╄→гoц情女王★ 提交于 2021-02-11 05:59:46

问题


i'm trying to use an index buffer but have no idea how

i really am stuck in a waall as to what i'm supposed to even try so. none of the tutorials really show anything similar to my code which is mostly why i'm having problems. i might have to rewrite cube vertex array creator. (on a different note maybe i shouldn't have just shoved opengl into some ready code)right now i've only enabled the top face as to see what's going on.

/// <summary>
        /// Draws the specified Cube Onsccreen.
        /// </summary>
        public void Draw()
        {

            GL.UseProgram(VSID);
            Vector3 ObjectPosition = new Vector3((new Vector(1, 1) * (Position - Offset)))
            {
                Z = Layer * 0.1f
            };
            Matrix4 Scale = Matrix4.CreateScale(Width+highlight, Height+highlight, Height+highlight);
            Matrix4 Translation = Matrix4.CreateTranslation(ObjectPosition);

            Matrix4 ViewPoint = Matrix4.CreateOrthographic(Game.window.Width , Game.window.Height, -1,1000);
            ViewPoint = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI-Zoom,Game.window.Width/Game.window.Height,0.0001f,1000);
            Matrix4 Rotation = Matrix4.CreateRotationZ((float)Angle);
            Matrix4 CameraRotX = Matrix4.CreateRotationX((float)Math.PI/180*40f );
            Matrix4 CameraRotZ = Matrix4.CreateRotationZ(Game.CameraAngle);

            Matrix4 Combined = Scale * Rotation  * Translation * ViewPoint * CameraRotZ * CameraRotX;

            GL.ProgramUniformMatrix4(VSID, GL.GetUniformLocation(VSID, "QuadMatrix"), false, ref Combined);
            GL.ProgramUniform4(VSID, GL.GetUniformLocation(VSID, "ColorIn"), Color);
            GL.ProgramUniform1(VSID, GL.GetUniformLocation(VSID, "SS"), 0);

            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.IndexArray);

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, Texture);
            GL.BindVertexArray(QID);
            GL.DrawArrays(PrimitiveType.Triangles, 0, indices.Length);


        }


        public static void CreateVisuals()
        {
            int VS = Shaders.Load("Shaders.vs", ShaderType.VertexShader);
            int FS = Shaders.Load("Shaders.fs", ShaderType.FragmentShader);

            VSID = Visuals.Create(VS, FS);
        }

        public static void CreateCube()
        {
            QID = GL.GenVertexArray();
            GL.BindVertexArray(QID);

            int VID =GL.GenBuffer();
            float[] Verticles = 
            {
                -0.5f,  0.5f,  0.5f,
                 0.5f,  0.5f,  0.5f,
                -0.5f, -0.5f,  0.5f,
                 0.5f, -0.5f,  0.5f,
                -0.5f,  0.5f, -0.5f,
                 0.5f,  0.5f, -0.5f,
                -0.5f, -0.5f, -0.5f,
                 0.5f, -0.5f, -0.5f


            };
            GL.BindBuffer(BufferTarget.ArrayBuffer, VID);
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float)*Verticles.Length, Verticles,BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(0);

            int UVID = GL.GenBuffer();
            float[] UVs =
            {
                0, 1,
                1, 1,
                0, 0,
                0, 0,
                1, 1,
                1, 0
            };
            GL.BindBuffer(BufferTarget.ArrayBuffer, UVID);
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * UVs.Length, UVs, BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(1);

            indices = new uint[]
            {
                0,1,2,
                2,1,3/*,
                0,1,5,
                0,1,4,
                1,3,5,
                3,5,7,
                2,3,7,
                2,6,7,
                0,2,6,
                0,4,6,
                4,5,6,
                5,6,7//*/
            };

            IBO = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, IBO);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(sizeof(uint) * indices.Length), indices, BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(IBO,1,VertexAttribPointerType.UnsignedInt,false,0,0);
            GL.EnableVertexAttribArray(2);

        }

    }

instead of drawing a simple quad it the 2 triangles get drawn in the wrong order. it's actually just using the coordinates in space instead of the indexes for those coordinates currently looks like this:

image


回答1:


The Index buffer name (value) is stated in the state vector of the Vertex Array Object.
To "use" it you've binbd the vertex array object and to call glDrawElements instead of glDrawArrays:

GL.BindVertexArray(QID);
GL.DrawElements(PrimitiveType.Triangles, 0, DrawElementsType.UnsignedInt, NULL);

You have to "duplicate" vertex positions. See Rendering meshes with multiple indices. The vertex coordinate and its attributes (like texture coordinate) form a tuple. You can imagine a 3D vertex coordinate and a 2D texture coordinate as a single 5D coordinate.

At least you have to use separate vertices and attributes, for 2 edges of the cube. This means you need at least 8+2*2=12 different sets of vertex attributes.

         x    y    z      u  v
0  :    -0.5  0.5  0.5    0  0
1  :     0.5  0.5  0.5    1  0
2  :    -0.5 -0.5  0.5    0  1
3  :     0.5 -0.5  0.5    1  1
4  :    -0.5 -0.5 -0.5    0  0
5  :     0.5 -0.5 -0.5    1  0
6  :    -0.5  0.5 -0.5    0  1 
7  :     0.5  0.5 -0.5    1  1
8  :    -0.5  0.5  0.5    1  1
9  :    -0.5  0.5 -0.5    1  0
10 :     0.5  0.5  0.5    0  1
11 :     0.5  0.5 -0.5    0  0

Note, the vertex attribute sets with the indices 0, 2, 4 and 6 have an identically u-coordinate of 0. And the vertex attribute sets with the indices 1, 3, 5 and 7 have an identically u-coordinate of 1.
If you want to wrap a texture to a quad you have to vary the u and the v coordinates. Because of that you have to add the separated vertex attribute sets 8, 9, 10 and 11.

With this setup of vertex coordinates and texture coordinates you can define the 12 triangular faces of the cube:

0 - 2 -  1    2 -  3 -  1
8 - 9 -  2    9 -  4 -  2
2 - 4 -  3    4 -  5 -  3
3 - 5 - 10    5 - 11 - 10
4 - 6 -  5    6 -  7 -  5
6 - 0 -  7    0 -  1 -  7



回答2:


so my problem was that i was going from 2d to 3d and from just simple quads to index buffered objects and when you're drawing straigth from vertexes you use

GL.DrawArrays();

but when you're using index buffer object's you're supposed to use

GL.DrawElements();

since you're saving the indexes into the element buffer here:

GL.BindBuffer(BufferTarget.ElementArrayBuffer, IBO);



来源:https://stackoverflow.com/questions/57818706/im-trying-to-implement-index-buffer-object-in-opentk-but-dont-know-how-to-actu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!