我正在尝试在opentk中实现索引缓冲区对象,但不知道在绘制内容时如何实际使用它 [英] i'm trying to implement index buffer object in opentk but don't know how to actually use it when drawing things

查看:61
本文介绍了我正在尝试在opentk中实现索引缓冲区对象,但不知道在绘制内容时如何实际使用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用索引缓冲区,但不知道如何使用

关于我本该尝试的方法,我确实陷入了困境.这些教程都没有真正显示出与我的代码相似的东西,这就是为什么我遇到问题的主要原因.我可能不得不重写多维数据集顶点数组创建器.(换句话说,也许我不应该只是将opengl塞进一些现成的代码中),现在我只启用顶面以查看发生了什么.

 ///< summary>///绘制指定的Cube Onsccreen.///</summary>公共无效Draw(){GL.UseProgram(VSID);Vector3 ObjectPosition = new Vector3((new Vector(1,1)*(Position-Offset))){Z =层* 0.1f};Matrix4 Scale = Matrix4.CreateScale(Width +高亮,Height +高亮,Height +高亮);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组合=比例*旋转*平移*视点* CameraRotZ * CameraRotX;GL.ProgramUniformMatrix4(VSID,GL.GetUniformLocation(VSID,"QuadMatrix"),false,ref Combined);GL.ProgramUniform4(VSID,GL.GetUniformLocation(VSID,"ColorIn"),颜色);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,index.Length);}公共静态无效CreateVisuals(){int VS = Shaders.Load("Shaders.vs",ShaderType.VertexShader);int FS = Shaders.Load("Shaders.fs",ShaderType.FragmentShader);VSID = Visuals.Create(VS,FS);}公共静态无效CreateCube(){QID = GL.GenVertexArray();GL.BindVertexArray(QID);int VID = GL.GenBuffer();float []顶点={-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、11、10、0,0、0,1、11、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);索引=新的uint []{0、1、22,1,3/*,0、1、50、1、41 3 53 5 52 3 72 6 70、2、60、4、64 5 65、6、7//*/};IBO = GL.GenBuffer();GL.BindBuffer(BufferTarget.ElementArrayBuffer,IBO);GL.BufferData(BufferTarget.ElementArrayBuffer,(IntPtr)(sizeof(uint)* index.Length),索引,BufferUsageHint.StaticDraw);GL.VertexAttribPointer(IBO,1,VertexAttribPointerType.UnsignedInt,false,0,0);GL.EnableVertexAttribArray(2);} 

不是以简单的四边形绘制而是以错误的顺序绘制了两个三角形.它实际上只是在空间中使用坐标,而不是这些坐标的索引当前看起来像这样:

解决方案

 <代码> x y v0:-0.5 0.5 0.5 0 01:0.5 0.5 0.5 1 02:-0.5 -0.5 0.5 0 13:0.5 -0.5 0.5 1 14:-0.5 -0.5 -0.5 0 05:0.5 -0.5 -0.5 1 06:-0.5 0.5 -0.5 0 17:0.5 0.5 -0.5 1 18:-0.5 0.5 0.5 1 19:-0.5 0.5 -0.5 1 010:0.5 0.5 0.5 0 111:0.5 0.5 -0.5 0 0 

请注意,索引属性为0、2、4和6的顶点属性集具有相同的u坐标0.索引属性为1、3、5和7的顶点属性集具有相同的u坐标.1.
如果要将纹理包装到四边形,则必须更改u和v坐标.因此,您必须添加单独的顶点属性集8、9、10和11.

通过设置顶点坐标和纹理坐标,您可以定义立方体的12个三角形面:

 <代码> 0-2-1 2-3-18-9-2 9-4-22-4-3-4-5-33-5-10 5-11-104-6-5 6-7-56-0-7 0-1-7 

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

I really am stuck in a wall 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:

解决方案

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

这篇关于我正在尝试在opentk中实现索引缓冲区对象,但不知道在绘制内容时如何实际使用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆