gpt4 book ai didi

c++ - 修改 OpenGL 中的单个顶点位置

转载 作者:行者123 更新时间:2023-11-30 01:45:45 25 4
gpt4 key购买 nike

我现在正在将我的代码从我使用 glBegin()glVertex3f() 的 OpenGL 2 转换为 OpenGL 3.3 并使用 VBO、EBO .我阅读了许多教程,但我找不到一件非常重要的事情,我希望有人能够在这里帮助我。

在以前的版本中,感谢 glBegin(GL_POLYGON) 和 4 glVertex3f(floa, float, float) 我能够创建我想要的形状。或者更准确地说是用户想要的——他可以只抓取一个顶点并修改基本矩形。所以可以创建这样的东西:

previous

现在我绘制基本矩形的代码如下所示:

box_vertices[] = {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};

box_indices[] = {
0, 1, 3,
1, 2, 3
};

GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(box_vertices), box_vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(box_indices), box_indices, GL_STATIC_DRAW);

// Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(0);

while(true) {
GLint modelLoc = glGetUniformLocation(box_shader.Program, "model");
GLint viewLoc = glGetUniformLocation(box_shader.Program, "view");
GLint projLoc = glGetUniformLocation(box_shader.Program, "projection");

glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

glBindVertexArray(VAO);

model = glm::mat4();
model = glm::scale(model, glm::vec3(0.25, 0.75, 1.0));
// Position box at it's location
model = glm::translate(model, glm::vec3(x, y, z));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

结果看起来像这样:

now

也许这可能会有所帮助,这是我的顶点着色器代码:

#version 330 core
layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
}

我只是不知道如何修改一个顶点,因为首先它是嵌入在 VBO 中的).我怀疑每次都需要生成新的 box_vertices 数组,那么如何才能做到呢?

有人可以告诉我如何实现我的目标吗?

编辑:

根据vesan的回答修改代码

while(true) {
GLint modelLoc = glGetUniformLocation(box_shader.Program, "model");
GLint viewLoc = glGetUniformLocation(box_shader.Program, "view");
GLint projLoc = glGetUniformLocation(box_shader.Program, "projection");

glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

glBindVertexArray(VAO);

MakeSomeChangesToVerticesArray();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(box_vertices), box_vertices, GL_DYNAMIC_DRAW);

model = glm::mat4();
model = glm::scale(model, glm::vec3(0.25, 0.75, 1.0));
// Position box at it's location
model = glm::translate(model, glm::vec3(x, y, z));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

最佳答案

您可以简单地修改缓冲区中的数据。数据仍然存在,VAO 只是指向它。

因此,在渲染周期开始时,只需根据需要修改 box_vertices 数组,然后调用与第一次放入数据时相同的方法:

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(box_vertices), box_vertices, GL_STATIC_DRAW);

你的数组很小,所以性能不应该是一个问题。如果是,请确保仅在形状实际发生变化时才修改缓冲区,考虑使用 GL_DYNAMIC_DRAW 而不是 GL_STATIC_DRAW 或使用 glBufferSubData仅替换缓冲区的一部分(不幸的是,我没有一个方便的例子)。

编辑:当然,修改缓冲区的代码不必在绘图循环内。它可以在任何地方(例如在鼠标或键盘处理程序中)。我建议将它放在循环中,因为代码的结构方式,没有其他地方可以放置它。

关于c++ - 修改 OpenGL 中的单个顶点位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34125298/

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