gpt4 book ai didi

c++ - 在 OpenGL 中存储模型矩阵的最佳位置?

转载 作者:搜寻专家 更新时间:2023-10-31 01:02:49 24 4
gpt4 key购买 nike

我目前正在重构我的 OpenGL 程序(曾经是一个巨大的文件)以使用 C++ 类。基本框架如下所示:

我有一个接口(interface) Drawable 和函数 virtual void Render(GLenum type) const = 0; 和一堆实现这个接口(interface)的类 (SphereCubeGridPlanePLYMeshOBJMesh)。

在我的 main.cpp 中,我正在设置一个包含多个此类对象的场景,每个对象都有自己的着色器程序。在设置统一缓冲区对象和每个程序的单独统一后,我调用 glutMainLoop()

在调用每一帧的 Display 函数中,我要做的第一件事是设置所有变换矩阵,最后为每个对象调用上述 Render 函数在场景中:

void Display()
{
// Clear framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


modelViewMatrix = glm::mat4(1.0);
projectionMatrix = glm::mat4(1.0);
normalMatrix = glm::mat4(1.0);

modelViewMatrix = glm::lookAt(glm::vec3(0.0, 0.0, mouse_translate_z), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
modelViewMatrix = glm::rotate(modelViewMatrix, -mouse_rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
modelViewMatrix = glm::rotate(modelViewMatrix, -mouse_rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));

projectionMatrix = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 1.0f, 10000.f);

// No non-uniform scaling (only use mat3(normalMatrix in shader))
normalMatrix = modelViewMatrix;

glBindBuffer(GL_UNIFORM_BUFFER, ubo_global_matrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(modelViewMatrix));
glBufferSubData(GL_UNIFORM_BUFFER, 1 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(projectionMatrix));
glBufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(normalMatrix));
glBindBuffer(GL_UNIFORM_BUFFER, 0);

// ************************************************** //
// **************** DRAWING COMMANDS **************** //
// ************************************************** //

// Grid
if (grid->GetIsRendered())
{
program_GRID_NxN->Use();
grid->Render(GL_LINES);
program_GRID_NxN->UnUse();
}

// Plane
...

// Sphere
...

// Swap front and back buffer and redraw scene
glutSwapBuffers();
glutPostRedisplay();
}

我现在的问题如下:使用当前代码,我为每个对象使用相同的 ModelView 矩阵。如果我只想平移球体,或者只旋转平面而不改变顶点位置怎么办?在大型 OpenGL 程序中存储模型矩阵的最佳位置在哪里?将 protected 成员变量 glam::mat4 modelMatrix 放入 Drawable 接口(interface)怎么样?此外,是否应该拆分模型和 View 矩阵(例如,使用仅包含 View 矩阵的 Camera 类)?

最佳答案

我的回答主要基于 Tom Dalling's excellent tutorial , 但有一些小的变化。

首先,您所有的 View 和投影矩阵操作都应该放在 Camera 类中。 Camera 将通过调用 matrix() 方法提供一种获取 View 和投影矩阵的便捷方式。

glm::mat4 Camera::matrix() const {
return projection() * view();
}

Camera.cpp

然后对于此示例,您将拥有一个模型资源,其中包含渲染几何体所需的一切。此 Assets 应该是唯一的,并存储在 ResourceManager 或类似的东西中。

struct ModelAsset {
Shader* shader;
Texture* texture;
GLuint vbo;
GLuint vao;
GLenum drawType;
GLint drawStart;
GLint drawCount;
};

然后您有一个模型实例,它有一个指向 Assets 的指针和一个唯一的变换矩阵。通过这种方式,您可以为特定 Assets 创建尽可能多的实例,每个实例都有自己独特的转换。

struct ModelInstance {
ModelAsset* asset;
glm::mat4 transform;
};

ModelInstance cube;
cube.asset = &asset; // An asset that you created somewhere else (e.g. ResourceManager)
cube.transform = glm::mat4(); // Your unique transformation for this instance

要渲染实例,您将 View 和模型矩阵作为制服传递给着色器,着色器会完成其余工作。

shaders->setUniform("camera", camera.matrix());
shaders->setUniform("model", cube.transform);

最后,最好将所有实例很好地分组在某个可调整大小的容器中。

std::vector<ModelInstance> instances;
instances.push_back(cube);
instances.push_back(sphere);
instances.push_back(pyramid);

for (ModelInstance i : instances) {
i.transform = glm::rotate(i.transform, getTime(), glm::vec3(0.0f, 1.0f, 0.0f));
}

关于c++ - 在 OpenGL 中存储模型矩阵的最佳位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26445174/

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