如何告诉 IBO 处理给定的数据? (布料模拟)
How to tell a VBO to handle the given data? (cloth simulation)
我正在 openGL 中创建布料模拟,我一直在尝试使用 VAO 和 VBO 进行渲染,而不是使用旧的即时模式(glBegin、glEnd)。
我认为最好只提供代码的相关部分而不是全部。所以我目前有一个 class,Cloth,它将质量(节点)存储在一个向量中。
class Cloth {
private:
std::vector<Mass>masses;
public:
std::vector<Mass> getMasses() { return masses; };
// functions below
还有一个 class,马萨诸塞州
class Mass {
glm::vec3 currentPos;
glm::vec3 oldPos;
glm::vec3 acceleration;
// functions below
我已经创建了一个像这样的 VBO
glGenBuffers(1, &VBO_ID);
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
glBufferData(GL_ARRAY_BUFFER, cloth.getMasses().size() * sizeof(Mass), &cloth.getMasses().front(), GL_DYNAMIC_DRAW);
和一个 VAO
glGenVertexArrays(1, &VAO_ID);
glBindVertexArray(VAO_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GL_FLOAT), 3*sizeof(GL_FLOAT)); // unsure about this part
根据我收集到的信息,通过调用 glVertexAttribPointer,您可以告诉 VBO 如何处理提供给它的数据。我给了它一个 Mass 类型的向量。
告诉它如何处理数据以便它使用 currentPos 作为顶点的正确方法是什么?
和
是否有更好的(性能方面的)方法来做到这一点,如果有,如何以及为什么?
例如,最好使用结构来保存 currentPos 吗?
我没有发现代码有任何问题。但是有了 vertexBuffer 属性,你不需要告诉 openGL 状态机使用 currentPos 作为顶点,这将在顶点着色器中完成。
EDIT 我发现代码有问题。我以为你只发送原始类型。您不能将 class 发送到您的 GLSL 代码并希望它能正常工作。你可以发送数据,glVertexAttribPointer 告诉你的着色器数据的布局。你在做什么是行不通的。
我建议你看一下https://learnopengl.com/它对我帮助很大而且非常完整。
你将拥有:
layout (location = 0) in vec3 currentPos;
layout (location = 1) in vec3 oldPos;
layout (location = 2) in vec2 acceleration;
然后你用这个输出顶点的位置:
gl_Position = mvp*vec4(currentPos, 1.0);
mvp beeing 您可能会作为制服发送的模型视图投影矩阵。
接下来的内容有点超出您的回答范围,但可能很有趣:
虽然我不知道你到底想做什么,但你应该知道在顶点着色器中你不能编辑顶点属性,这意味着考虑你的代码现在的样子,你将拥有在模拟的每一步更新您的 VBO。您可以自己更新它 CPU(这可能很慢),但在计算着色器中进行更新可能要快得多。
我正在 openGL 中创建布料模拟,我一直在尝试使用 VAO 和 VBO 进行渲染,而不是使用旧的即时模式(glBegin、glEnd)。
我认为最好只提供代码的相关部分而不是全部。所以我目前有一个 class,Cloth,它将质量(节点)存储在一个向量中。
class Cloth {
private:
std::vector<Mass>masses;
public:
std::vector<Mass> getMasses() { return masses; };
// functions below
还有一个 class,马萨诸塞州
class Mass {
glm::vec3 currentPos;
glm::vec3 oldPos;
glm::vec3 acceleration;
// functions below
我已经创建了一个像这样的 VBO
glGenBuffers(1, &VBO_ID);
glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
glBufferData(GL_ARRAY_BUFFER, cloth.getMasses().size() * sizeof(Mass), &cloth.getMasses().front(), GL_DYNAMIC_DRAW);
和一个 VAO
glGenVertexArrays(1, &VAO_ID);
glBindVertexArray(VAO_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GL_FLOAT), 3*sizeof(GL_FLOAT)); // unsure about this part
根据我收集到的信息,通过调用 glVertexAttribPointer,您可以告诉 VBO 如何处理提供给它的数据。我给了它一个 Mass 类型的向量。
告诉它如何处理数据以便它使用 currentPos 作为顶点的正确方法是什么?
和
是否有更好的(性能方面的)方法来做到这一点,如果有,如何以及为什么?
例如,最好使用结构来保存 currentPos 吗?
我没有发现代码有任何问题。但是有了 vertexBuffer 属性,你不需要告诉 openGL 状态机使用 currentPos 作为顶点,这将在顶点着色器中完成。
EDIT 我发现代码有问题。我以为你只发送原始类型。您不能将 class 发送到您的 GLSL 代码并希望它能正常工作。你可以发送数据,glVertexAttribPointer 告诉你的着色器数据的布局。你在做什么是行不通的。
我建议你看一下https://learnopengl.com/它对我帮助很大而且非常完整。
你将拥有:
layout (location = 0) in vec3 currentPos;
layout (location = 1) in vec3 oldPos;
layout (location = 2) in vec2 acceleration;
然后你用这个输出顶点的位置:
gl_Position = mvp*vec4(currentPos, 1.0);
mvp beeing 您可能会作为制服发送的模型视图投影矩阵。
接下来的内容有点超出您的回答范围,但可能很有趣:
虽然我不知道你到底想做什么,但你应该知道在顶点着色器中你不能编辑顶点属性,这意味着考虑你的代码现在的样子,你将拥有在模拟的每一步更新您的 VBO。您可以自己更新它 CPU(这可能很慢),但在计算着色器中进行更新可能要快得多。