我有多个对象但不知道如何单独移动或旋转它们。这将是我到目前为止的代码的缩短版本:
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*/}
如果我运行此代码,一切都会完美显示,但我无法找到一种在运行时更改一个特定对象顶点位置的简洁方法。
此外,这与初始问题没有任何关系,但我注意到每当我在笔记本电脑上运行完全相同的代码时,程序在调用glBindFragDataLocation()
时会崩溃(它无论我是在Linux还是Windows上运行它都无关紧要。
答案 0 :(得分:1)
在许多渲染应用程序中,使用了几种不同的坐标系:
在您的情况下,我会在存储位置的Object
结构中添加一个额外的vec3成员。
struct Object {
//Things you already have
glm::vec3 loc;
}
然后,您可以在调用glDrawElements
之前直接更新模型矩阵。由于已经发出了绘制调用,因此更改此位置的模型矩阵将始终影响正确的对象:
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);
}
}
另一种选择是将矩阵直接存储在Object
类中,这会增加数据大小(并且可能不太直观),但可能会降低运行时成本。
答案 1 :(得分:-1)
Draw函数的当前状态如下所示:
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);
}
}