C++ OpenGL在运行时转换顶点数组对象

C++ OpenGL在运行时转换顶点数组对象,c++,opengl,rotation,glsl,transform,C++,Opengl,Rotation,Glsl,Transform,我有多个对象,但不知道如何单独移动或旋转它们。这将是我迄今为止的代码的缩短版本: const GLchar* vertexSource = "#version 150 core\n" "in vec3 position;" "uniform mat4 model;" "uniform mat4 view;" "uniform mat4 proj;" "void main() {" " gl_Position = proj * view * mo

我有多个对象,但不知道如何单独移动或旋转它们。这将是我迄今为止的代码的缩短版本:

const GLchar* vertexSource = "#version 150 core\n"
    "in vec3 position;"
    "uniform mat4 model;"
    "uniform mat4 view;"
    "uniform mat4 proj;"
    "void main() {"
    "   gl_Position = proj * view * model * vec4(position, 1.0);"
    "}";

struct Object {
    // here are the constructors

    vector<Triangle> polys; // Triangle is a struct containing vertex data
    GLuint vao, vbo, ebo;

    // somne other variables and functions
    // ...
};  

void ShaderProgram::AddObject(const vector<Triangle>& polys) {
    objects.push_back(Object(polys));
    Object& obj = objects[objects.size()-1];

    glGenVertexArrays(1, &obj.vao);
    glBindVertexArray(obj.vao);

    // set up vertices and a vertex buffer object for them
    // ...
    glGenBuffers(1, &obj.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, obj.vbo);
    glBufferData(GL_ARRAY_BUFFER, obj.polys.size()*polySize*sizeof(float), vertices, GL_STATIC_DRAW);
    // 'polySize' is just a constant variable to healp me out and 'vertices' is a float array

    // set up element buffer object
    // ...
    glGenBuffers(1, &obj.ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, obj.ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
    // elements is a float array

    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, vertSize*sizeof(float), 0);
    // 'vertSize' is also a constant variable
}

void ShaderProgram::Draw(float dSec) {
    for (Object& it : objects) {
        glBindVertexArray(it.vao);
        // here's some texturing related stuff
        glDrawElements(GL_TRIANGLES, it.vertexCount(), GL_UNSIGNED_INT, 0);
    }
}

void ShaderProgram::Move(Object& obj, glm::vec3 vec) {/*move it somehw*/}
void ShaderProgram::Rotate(Object& obj, glm::vec3 rotPoint, glm::vec3 rot) {/*rotate obj around rotPoint*/}
const GLchar*vertexSource=“#版本150核心\n”
“处于vec3位置;”
“统一mat4模型;”
“统一mat4视图;”
“统一mat4项目;”
“void main(){”
“gl_位置=项目*视图*模型*vec4(位置,1.0);”
"}";
结构对象{
//这里是构造器
向量多边形;//三角形是包含顶点数据的结构
GLuint vao、vbo、ebo;
//其他变量和函数
// ...
};  
void ShaderProgram::AddObject(常量向量和多边形){
对象。推回(对象(多边形));
Object&obj=objects[objects.size()-1];
glGenVertexArrays(1和obj.vao);
glBindVertexArray(对象vao);
//设置顶点及其顶点缓冲区对象
// ...
glGenBuffers(1,&obj.vbo);
glBindBuffer(GL_数组_BUFFER,obj.vbo);
glBufferData(GL_数组_缓冲区,obj.polys.size()*polySize*sizeof(float),顶点,GL_静态_绘制);
//“polySize”只是一个常量变量,用于叠加,而“顶点”是一个浮点数组
//设置元素缓冲区对象
// ...
glGenBuffers(1和obj.ebo);
glBindBuffer(GL_元素数组缓冲区,obj.ebo);
glBufferData(GL_元素\数组\缓冲区、sizeof(元素)、元素、GL_静态\绘图);
//元素是一个浮点数组
GLint posAttrib=glGetAttribLocation(着色器程序,“位置”);
glEnableVertexAttribArray(posAttrib);
GLVERtexAttribute指针(POSATRIB,3,GL U FLOAT,GL U FALSE,vertSize*sizeof(浮点),0);
//“vertSize”也是一个常量变量
}
void ShaderProgram::Draw(float dSec){
用于(对象和it:对象){
glBindVertexArray(it.vao);
//这里有一些纹理相关的东西
glpaurements(GL_三角形,it.vertexCount(),GL_UNSIGNED_INT,0);
}
}
void ShaderProgram::Move(Object&obj,glm::vec3-vec){/*将其移动到某个hw*/}
void ShaderProgram::Rotate(对象&obj,glm::vec3 rotPoint,glm::vec3 rot){/*围绕rotPoint旋转obj*/}
如果我运行这段代码,所有内容都会完美地显示出来,但我无法找到一种在运行时更改特定对象顶点位置的干净方法


此外,这与最初的问题没有任何关系,但我注意到,每当我在笔记本电脑上运行完全相同的代码时,当调用
glBindFragDataLocation()
时,程序就会崩溃(无论我是在Linux还是Windows上运行它都无关紧要)。

在许多渲染应用程序中,使用了几种不同的坐标系:

  • 对象空间:这是定义顶点的空间。每个模型都有自己的对象坐标和自己的模型原点
  • 世界空间:这是场景中所有模型相对放置的空间。这通常是通过基于场景中的所需位置指定模型矩阵来完成的
在您的情况下,我将向存储位置的
对象
结构添加一个额外的vec3成员

struct Object {
    //Things you already have

    glm::vec3 loc;
}
然后,您可以在调用
gldrawerelements
之前直接更新模型矩阵。由于已发出绘制调用,因此在此处更改模型矩阵将始终影响正确的对象:

void ShaderProgram::Draw(float dSec) {
    for (Object& it : objects) {
        glBindVertexArray(it.vao);
        // here's some texturing related stuff

        glm::mat4 model_matrix(1.0f);
        glm::translate(model_matrix, it.loc);

        glUniformMatrix4fv(model_uniform_location, 1, GL_FALSE, model_matrix);

        glDrawElements(GL_TRIANGLES, it.vertexCount(), GL_UNSIGNED_INT, 0);
    }
}

另一种选择是将矩阵直接存储在
对象
类中,这将增加数据大小(使用起来可能不那么直观),但可能会降低运行时成本。

绘图函数的当前状态如下所示:

void ShaderProgram::Draw(float dSec) {
    objects[0].location.x += dSec;
    GLint uniModel = glGetUniformLocation(shaderProgram, "model");
    for (Object& it : objects) {
        glBindVertexArray(it.vao);
        glm::mat4 model;
        model = glm::translate(model, it.location);
        glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
        glDrawElements(GL_TRIANGLES, it.vertexCount(), GL_UNSIGNED_INT, 0);
    }
}

此代码中没有对
glBindFragDataLocation
的调用。这就是为什么说它是我当前代码的缩短版本。我如何获得模型的矩阵?我有一些类似的东西,但它会变换所有顶点。如何存储模型的变换?我刚刚将所有顶点的位置存储在每个三角形、每个对象的三个glm::vec3中。好吧,我现在可能很傻,但这段代码似乎可以转换我所有的对象。我已经使用了glGetUniformLocation(ShaderProgramm,“model”)来获取可能是问题所在的model\u uniform\u位置。是否有其他方法获取它?是否为不同的对象设置了不同的loc值
glGetUniformLocation
是正确的命令。