gpt4 book ai didi

c++ - 将自定义顶点结构传递给 GLSL 着色器

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:05 24 4
gpt4 key购买 nike

我正在尝试将结构传递给简单的 GLSL vetrex 着色器。下面是 C++ 端的结构:

struct Vertex
{
float position[3];
char boneIndex[4];
float weights[4];
float normals[3];
float textureCords[2];
};

是否可以将这个顶点的数组传递给顶点着色器而不为每个组件创建一个单独的数组?

我可以做这样的事情吗:

#version 330 core

uniform mat4 MVP;

layout(location = 0) in struct Vertex
{
vec3 position;
uint boneIndex;
vec4 weights;
vec3 normals;
vec2 textureCords;
} vertex;

out vec2 UV;

void main()
{
gl_Position = MVP * vec4(vertex.position, 1.0f);
UV = vertex.textureCords;
}

(不要介意并非所有组件都在使用,这只是为了示例。)

如果可以的话,我如何使用 glVertexAttribPointer() 函数从 C++ 端将数据传递给它? (根据我的理解,您只能将 1、2、3、4 传递给 size 参数)。

这是做事的正确方法吗?我是 OpenGL 编程的初学者,所以如果您有答案,请不要犹豫,包括明显的细节。

编辑:

我最终做了这样的事情:

    glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); //float position[3]
glVertexAttribPointer(1, 1, GL_INT, GL_FALSE, 12, (void*)0); //char boneIndex[4]
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 16, (void*)0); //float weights[4]
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 32, (void*)0); //float normals[3]
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, 44, (void*)0); //float textureCords[2]


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indiceBuffer);

glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void*)0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);

关于 C++ 大小和 GLSL 顶点着色器:

    #version 330 core

uniform mat4 MVP;

layout(location = 0) in vec3 position;
layout(location = 1) in int boneIndex;
layout(location = 2) in vec4 weight;
layout(location = 3) in vec3 normal;
layout(location = 4) in vec2 UVCords;

out vec2 UV;

void main()
{
gl_Position = MVP * vec4(position, 1.0f);
UV = UVCords;
}

但还是不行,模型无法正确渲染

最佳答案

您用来传输交错数据的方法是正确的(即使用glVertexAttribPointer,但是,您的最后两个参数不正确)。

倒数第二个是stride(对于struct中的每一项都是一样的,应该是struct的大小),最后一个是offset ,每个元素应该不同(因为它们在结构本身中的偏移量不同)。

此外,最好不要在此处使用常量,而是使用 sizeof() 运算符,以使您的代码尽可能独立于平台。

它应该是这样的:

glVertexAttribPointer(
0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr
); //float position[3]

glVertexAttribIPointer(
1, 1, GL_INT, GL_FALSE, sizeof(Vertex),
std::reinterpret_cast<void *>(offsetof(Vertex, boneIndex))
); //char boneIndex[4]

glVertexAttribPointer(
2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
std::reinterpret_cast<void *>(offsetof(Vertex, weights))
); //float weights[4]

glVertexAttribPointer(
3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
std::reinterpret_cast<void *>(offsetof(Vertex, normals))
); //float normals[3]

glVertexAttribPointer(
4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
std::reinterpret_cast<void *>(offsetof(Vertex, textureCoords))
); //float textureCoords[2]

另外,您可能应该确保您的 Vertex 结构没有被打包以适应一个漂亮的单词边界。这是通过使用 #pragma pack(0) 完成的,如果您的编译器支持的话。 (记住在你的结构之后重置它,否则编译器将在整个编译过程的其余部分使用这个指令,并且你所有的聚合数据结构将以一种不会屈服于最适合的方式构造到世界对齐。),这是它的样子:

#pragma pack(push, 0)

struct Vertex {
float position[3];
char boneIndex[4];
float weights[4],
normals[4],
textureCoords[2];
};

#pragma pack(pop)

关于c++ - 将自定义顶点结构传递给 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19081734/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com