OpenGL未找到纹理坐标VertexAttribPoint

w6mmgewl  于 2022-10-18  发布在  其他
关注(0)|答案(1)|浏览(160)

我在OpenGL中可能有一个非常简单的问题。我想画不同的形状,上面有纹理。因此,我定义了一个顶点结构,它包含结的位置和附加信息(法线向量、纹理坐标、纹理引用):

public struct Vertex
{
    public Vector3 position;
    public Vector3 normal;
    public Vector2 texCoord;
    public int texid;

    public static int SizeInBytes
    {
        get { return Vector3.SizeInBytes * 2 + Vector2.SizeInBytes + sizeof(int); }
    }
    public Vertex(Vector3 position, Vector3 normal, Vector2 texCoord, int texid)
    {
        this.position = position;
        this.normal = normal;
        this.texCoord = texCoord;
        this.texid = texid;
    }
}

然后创建两个顶点数组(VA_TopBottom_WP和VA_Side_WP)及其顶点缓冲区(VB_TopBottom_WP和VB_Side_WP)。此外,我还创建了所有纹理。

internal void init()
    {

        // Create Buffer for top and bottom part
        GL.GenVertexArrays(1, out VA_TopBottom_WP);
        GL.BindVertexArray(VA_TopBottom_WP);
        VB_TopBottom_WP = GL.GenBuffer();

        // Create Buffer for side part
        GL.GenVertexArrays(1, out VA_Side_WP);
        GL.BindVertexArray(VA_Side_WP);
        VB_Side_WP = GL.GenBuffer();

        // Create textures 
        texes = new List<STL_Tools.Texture2D>();
        texes.Add(new STL_Tools.Texture2D());//Default texture
        for (int n = 0; n < session.pgm.Count(); n++)
        {
            texes.Add(new STL_Tools.Texture2D());
        }
        updateFrame();

    }

然后我更新缓冲区内容:

public void updateFrame()
    {
        // Top and bottom buffer
        GL.BindVertexArray(VA_TopBottom_WP);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VB_TopBottom_WP);

        //Fill vertex structure
        vertBuffer_TopBottom = poly.GetTopBottomMeshesVertex();
        GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertex.SizeInBytes * vertBuffer_TopBottom.Length), vertBuffer_TopBottom, BufferUsageHint.StaticDraw);
        GL.EnableVertexAttribArray(0);
        GL.VertexAttribPointer(0,3, VertexAttribPointerType.Float,false, Vertex.SizeInBytes, (IntPtr)0);//Position
        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes*2));//Texture
        GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes));//Normal

        // Side buffer
        GL.BindVertexArray(VA_Side_WP);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VB_Side_WP);
        vertBuffer_Side = poly.GetSideVertex();//Fill vertices
        GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertex.SizeInBytes * vertBuffer_Side.Length), vertBuffer_Side, BufferUsageHint.StaticDraw);
        GL.EnableVertexAttribArray(0);
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)0);//Position
        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes * 2));//Texture
        GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes));//Normal

        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
    }

顶点变量包含之后合理的纹理坐标(下文中的Vector2对象)。例如:

vertBuffer_Side = new Vertex[4]
{new Vertex(new Vector3(0,0,0),new Vector3(1,0,0),new Vector2(0,0),0),
 new Vertex(new Vector3(0,-80,0),new Vector3(1,0,0),new Vector2(1,0),0),
 new Vertex(new Vector3(0,-80,-10),new Vector3(1,0,0),new Vector2(1,1),0),
 new Vertex(new Vector3(0,0,-10),new Vector3(1,0,0),new Vector2(0,0),0)};

然后,我使用以下函数绘制所有内容:

public void renderFrame()
    {
        GL.PushMatrix();

        GL.EnableClientState(ArrayCap.VertexArray);
        GL.EnableClientState(ArrayCap.NormalArray);
        GL.EnableClientState(ArrayCap.TextureCoordArray);

        // Draw Side
        GL.BindVertexArray(VA_Side_WP);
        GL.Color3(Color.White);
        GL.Enable(EnableCap.Texture2D);
        for (int n = 0; n < (vertBuffer_Side.Length / 4); n++)
        {
            //GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.BindTexture(TextureTarget.Texture2D, texes[vertBuffer_Side[n*4].texid].ID);
            GL.DrawArrays(PrimitiveType.Quads, n*4,4);
        }
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        GL.Disable(EnableCap.Texture2D);
        //Draw top and bottom
        GL.BindVertexArray(VA_TopBottom_WP);
        ...
        GL.PopMatrix();
    }

几何图形绘制正确。但纹理绘制不正确。它只用一种颜色绘制。它是纹理的最右侧像素的颜色。可能是以下功能不能正常工作:

GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes * 2));//Texture

我的错误在哪里?

rqqzpn5f

rqqzpn5f1#

客户端功能是顶点数组对象的状态。因此,您需要在设置客户端能力之前绑定VAO。此外,您使用的不是着色器,而是着色器程序。因此,必须定义VertexPointerNormalVectorTexCoordPointer,而不是指定顶点属性的泛型数组。请注意,可以指定顶点属性0而不是VertexPointer,但法线和纹理坐标不能指定顶点属性(另请参见What are the Attribute locations for fixed function pipeline in OpenGL 4.0++ core profile?):

GL.VertexPointer(3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)0);//Position
GL.TexCoordPointer(2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes*2));//Texture
GL.NormalPointer(VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(Vector3.SizeInBytes));//Normal
GL.BindVertexArray(VA_Side_WP);
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);

相关问题