索引缓冲区对象和 UV 坐标不好用 [英] Index Buffer Object and UV Coordinates don't play nice

查看:51
本文介绍了索引缓冲区对象和 UV 坐标不好用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这将生成 25 个主要顶点.

This generates the 25 main vertices.

    For x As Single = -1 To 1 Step 0.5F
        For y As Single = 1 To -1 Step -0.5F
            Dim pt1 As New Vector3(x, y, 0)
            tFloats.Add(pt1)
        Next
    Next

这是索引,由 32 个三角形组成的 16 个图块组成,我实际上生成了它们,但这是第一行:

This is the indices, which makes up 16 tiles made of 32 triangles, I actually generate them but this is the first row:

        Dim inasd() As Integer = {
        0, 2, 10,
        2, 10, 12,
        10, 12, 20,
        12, 20, 22,
        20, 22, 30,
        22, 30, 32
        }

现在我尝试将纹理应用于每个三角形,每个图块 1 个纹理.16 种不同的纹理.

Now I'm trying to apply a texture to every single triangle, 1 texture per tile. 16 different textures.

现在我的问题在于当我使用

Now my problem lies within the fact that when I use

GL.DrawRangeElements(PrimitiveType.Triangles, 0, indices.Length - 1, 6, DrawElementsType.UnsignedShort, New IntPtr(0))

不是沿着 UV 数据并像 (0,1,2) (3,4,5) (6,7,8) 那样使用它,而是跟随索引数据,并像 (0,2,10) (2,10,12) (10,12,20) 所以反驳我这样做了:

Rather than going along the UV data and using it like (0,1,2) (3,4,5) (6,7,8) it instead follows the index data, and grabs UV cords like (0,2,10) (2,10,12) (10,12,20) so to counter that I did this:

        Dim UV_Data(12) As Vector2
        UV_Data(0) = New Vector2(0.0F, 1.0F)
        UV_Data(2) = New Vector2(0.0F, 0.0F)
        UV_Data(10) = New Vector2(1.0F, 1.0F)
        UV_Data(12) = New Vector2(1.0F, 0.0F)

这在第一块瓷砖上效果很好.在第二个图块上,因为它是 (10,12,20),它使用 UV_Data(10) 作为三角形的左上角,这是纹理的右上角,所以它不起作用.无论如何我可以摆脱UV上的索引而不是顶点上的索引吗?因为它只是让我头疼,否则我该怎么办?

This works great, on the first tile. On the second tile because it goes (10,12,20) it uses UV_Data(10) as the top left corner of the triangle which is the top right corner on the texture so it doesn't work. Is there anyway I can get rid of the indexing on the UV but not on the vertex? Because its just causing such a headache for me, otherwise what can I do?

顶点数据和 UV 数据存储在两个独立的缓冲区中,如下所示:

The vertex data and UV Data ares stored in two separate buffers like this:

    GL.GenBuffers(1, FloatBuffer)
    GL.BindBuffer(BufferTarget.ArrayBuffer, FloatBuffer)
    GL.BufferData(BufferTarget.ArrayBuffer, New IntPtr(floats.Length * Vector3.SizeInBytes), floats, BufferUsageHint.StaticDraw)

    GL.GenBuffers(1, UVBuffer)
    GL.BindBuffer(BufferTarget.ArrayBuffer, UVBuffer)
    GL.BufferData(BufferTarget.ArrayBuffer, New IntPtr(UV_Data.Length * Vector2.SizeInBytes), UV_Data, BufferUsageHint.StaticDraw)

他们像这样进入显卡:

    GL.EnableVertexAttribArray(0)
    GL.BindBuffer(BufferTarget.ArrayBuffer, FloatBuffer)
    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, False, 0, 0)

    GL.EnableVertexAttribArray(1)
    GL.BindBuffer(BufferTarget.ArrayBuffer, UVBuffer)
    GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, False, 0, 0)

我也有索引缓冲区:

    GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndicesBuffer)

然后用上面的 Gl.DrawRangeElements 代码绘制.

Then drawn with the Gl.DrawRangeElements code above.

我的顶点着色器:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

// Values that stay constant for the whole mesh.

void main(){

// Output position of the vertex, in clip space : MVP * position
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1;

// UV of the vertex. No special space for this one.
UV = vertexUV;
}

我的片段着色器:

#version 330 core

// Interpolated values from the vertex shaders
in vec2 UV;

// Ouput data
out vec3 color;

// Values that stay constant for the whole mesh.
uniform sampler2D myTextureSampler;

void main(){

// Output color = color of the texture at the specified UV
color = texture2D( myTextureSampler, UV ).rgb;
}

EDIT 2:是否可以在渲染时编辑 UV 数据,例如:

EDIT 2: Is it possible to edit the UV data whilst rendering for example:

    Dim UV_Data(indices.Length) As Vector2
    For i As Integer = 0 To 1
        UV_Data(indices(i)) = New Vector2(0.0F, 1.0F)
        UV_Data(indices(i + 1)) = New Vector2(0.0F, 0.0F)
        UV_Data(indices(i + 2)) = New Vector2(1.0F, 1.0F)
        UV_Data(indices(i + 3)) = New Vector2(1.0F, 0.0F)
        'GL.BindBuffer(BufferTarget.ArrayBuffer, UVBuffer)
        GL.BufferData(BufferTarget.ArrayBuffer, New IntPtr(UV_Data.Length * Vector2.SizeInBytes), UV_Data, BufferUsageHint.DynamicDraw)
        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, False, 0, 0)

        'GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndicesBuffer)
        GL.BindTexture(TextureTarget.Texture2D, mapTextures.Item(i))
        GL.DrawRangeElements(PrimitiveType.Triangles, 0, indices.Length - 1, 6, DrawElementsType.UnsignedShort, New IntPtr(i * 12))
    Next

推荐答案

索引适用于顶点数据和纹理数据和属性.没有办法解决这个问题.例如在一个简单的 4 个四边形阵列中,它可以像下面那样工作.

The index applies to vertex data and texture data and attributes. There is no way around this. For example in a simple 4 quad array, it can work like below.

var backgroundObj = [-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1];

var backgroundObj = [ -1,-1, -1, 1,-1,-1, 1,1,-1, -1,1,-1 ];

var backgroundObjTexCoords = [0.000000, 0.000000, 1.000000, 0.000000,
1.000000, 1.000000, 0.000000, 1.000000];

var backgroundObjTexCoords = [ 0.000000, 0.000000, 1.000000, 0.000000,
1.000000, 1.000000, 0.000000, 1.000000 ];

var backgroundObjIndices = [0,1,2,0,2,3];

var backgroundObjIndices = [ 0,1,2, 0,2,3 ];

编辑 1:

,

如果采用与上图相反的流程,三角形将遵循 012、213、234 等顺序.即使手动生成,也需要以这种方式生成顶点.

If you take the opposite flow as in above image, the triangles will follow the order 012, 213, 234, etc. You need to generate vertices this way even if doing manually.

这篇关于索引缓冲区对象和 UV 坐标不好用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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