C++ 在OpenGL中修改单顶点位置 我现在正在把我的代码从OpenGL 2转换成我使用的代码> > GLUX()/代码>, GLVTEX3F.)/代码>到OpenGL 3.3,以及使用VBOS,EBOS。我读了很多教程,但我找不到一件非常重要的事情,我希望有人能在这里帮助我

C++ 在OpenGL中修改单顶点位置 我现在正在把我的代码从OpenGL 2转换成我使用的代码> > GLUX()/代码>, GLVTEX3F.)/代码>到OpenGL 3.3,以及使用VBOS,EBOS。我读了很多教程,但我找不到一件非常重要的事情,我希望有人能在这里帮助我,c++,opengl,C++,Opengl,在以前的版本中,由于glBegin(GL_POLYGON)和4glVertex3f(floa,float,float)我能够创建我想要的形状。或者更准确地说,用户需要-他可以抓住一个顶点并修改基本矩形。所以有可能创造出这样的东西: box_vertices[] = { 0.5f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f, -0.5f, 0.5

在以前的版本中,由于
glBegin(GL_POLYGON)
和4
glVertex3f(floa,float,float)
我能够创建我想要的形状。或者更准确地说,用户需要-他可以抓住一个顶点并修改基本矩形。所以有可能创造出这样的东西:

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);
}

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

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);
}
结果如下所示:

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);
}

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

#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中的,其次它必须规范化为我所理解的一个(如果不是OpenGL,我会这样做)。我怀疑我每次都需要生成新的
box\u顶点
数组,那么如何才能做到呢

有人能告诉我怎样才能实现我的目标吗

编辑:

根据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\u顶点
数组,然后调用与第一次放入数据时相同的操作:

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(box_vertices), box_vertices, GL_STATIC_DRAW);
您的阵列非常小,因此性能不应受到关注。如果是,只需修改缓冲区,仅当形状实际改变时,考虑使用<代码> GLyDycIcIdPult<代码>,而不是<代码> GLYSTATICHOLD < /COD> >或仅用于替换部分缓冲区(不幸的是,我没有一个很好的例子)。


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

如果不能使用转换,可以使用
glBufferData
glBufferSubData
@vesan不,我不能使用转换,不幸的是,在这种情况下它无法工作。你能举个简单的例子说明我如何使用这些方法吗?@sebap123:是什么让你认为你必须“规范化”这些值,使其达到如此大的范围。顶点属性被传递到着色器。我已经根据你的答案修改了代码。我猜这正是你所说的-我说得对吗?我还担心一件事-如果这个值应该被规范化(正如我从教程中了解的),我会将其中一个顶点坐标更改为5.0,其余的将保持不变,这样可以吗?是的,应该可以(你测试过了吗?)。我可能会在调用
glBindVertexArray
之前添加更改缓冲区的代码,但我认为这没有任何区别。不确定您读到了什么关于标准化的内容,这通常是针对法线的。当然,如果您将顶点修改为一些大不相同的值,您的形状可能最终会脱离屏幕。非常感谢您的所有解释。我现在已经测试过了,效果很好。