OpenGL 形状仅在初始位置为 (0, 0, 0) 时绘制
OpenGL shape only draws when initial position is (0, 0, 0)
我有一个从 OBJ 文件加载的多维数据集。当我设置它的位置(0,0,0)时,一切正常。多维数据集呈现,我的函数为其提供速度,在屏幕上移动多维数据集。但是,如果我在进入渲染和计算速度变化的 while 循环之前将立方体的位置更改为 (0, 0, 0) 以外的位置,则立方体永远不会渲染。这是我第一次尝试在每次渲染帧时重新加载我的顶点,我假设我在那里搞砸了一些东西 - 但我查看了其他代码并且无法弄清楚是什么。
这是我的主要功能:
int main()
{
#ifdef TESTING
testing();
exit(0);
#endif
setupAndInitializeWindow(768, 480, "Final Project");
TriangleTriangleCollision collisionDetector;
Asset cube1("cube.obj", "vertexShader.txt", "fragmentShader.txt");
cube1.position = glm::vec3(0.0, 2.0, 0.0);
cube1.velocity = glm::vec3(0.0, -0.004, 0.0);
MVP = projection * view * model;
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
moveAsset(cube1);
renderAsset(cube1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
glfwTerminate();
return 0;
}
我的移动资产函数:
void moveAsset(Asset &asset)
{
double currentTime = glfwGetTime();
asset.position.x += (asset.velocity.x * (currentTime - asset.lastTime));
asset.position.y += (asset.velocity.y * (currentTime - asset.lastTime));
asset.position.z += (asset.velocity.z * (currentTime - asset.lastTime));
for (glm::vec3 &vertex : asset.vertices)
{
glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) * glm::vec4(vertex.x, vertex.y, vertex.z, 1);
vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
}
asset.lastTime = glfwGetTime();
}
void renderAsset(Asset asset)
{
glUseProgram(asset.programID);
GLuint MatrixID = glGetUniformLocation(asset.programID, "MVP");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, asset.vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, asset.vertices.size() * sizeof(glm::vec3), &asset.vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, asset.vertices.size());
glDisableVertexAttribArray(0);
}
我的模型、视图和投影矩阵定义为:
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(5, 5, 10),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0));
glm::mat4 projection = glm::perspective(45.0f, (float) _windowWidth / _windowHeight, 0.1f, 100.0f);
最后,我的资产结构:
struct Asset
{
Asset() { }
Asset(std::string assetOBJFile, std::string vertexShader, std::string fragmentShader)
{
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
programID = LoadShaders(vertexShader.c_str(), fragmentShader.c_str());
// Read our .obj file
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
loadOBJ(assetOBJFile.c_str(), vertices, uvs, normals);
// Load it into a VBO
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
//velocity = glm::vec3(0.0, 1.0, 1.0);
velocity = glm::vec3(0.0, 0.0, 0.0);
position = glm::vec3(0.0, 0.0, 0.0);
lastTime = glfwGetTime();
}
GLuint vertexArrayID;
GLuint programID;
GLuint vertexbuffer;
std::vector<glm::vec3> faces;
std::vector<glm::vec3> vertices;
glm::vec3 velocity;
double lastTime;
glm::vec3 position;
};
看起来您在每次迭代中都将当前asset.position
添加到顶点位置,替换之前的位置。从moveAsset()
函数:
for (glm::vec3 &vertex : asset.vertices)
{
glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) *
glm::vec4(vertex.x, vertex.y, vertex.z, 1);
vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
}
暂时忽略速度,并假设您在 (0, 0, 0) 处有一个原始顶点,您将在第一次迭代时将其移动到asset.position
。然后在第二次迭代中再次添加asset.position
,将其置于 2 * asset.position
.然后在第三次迭代中,再次将asset.position
添加到此当前位置,从而产生3 * asset.position
。因此,经过n
步,顶点将在n * asset.position
左右。即使您的对象最初可能是可见的,它也会在您眨眼之前移出可见范围。
为了使原始策略正常工作,最直接的方法是有两个顶点列表。一个列表包含原始对象坐标,您永远不会更改该坐标。然后在绘制之前,构建第二个顶点列表,计算为原始顶点加上当前asset.position
之和,并使用第二个列表进行渲染。
整个事情是...不是很开放。实际上没有必要修改 CPU 上的顶点坐标。可以将平移作为顶点着色器中应用的变换的一部分。您已经有一个模型矩阵。您可以简单地将平移asset.position
放入模型矩阵中,然后重新计算 MVP 矩阵。您已经具有将新矩阵传递给 renderAsset()
函数中的着色器程序的glUniformMatix4fv()
调用。
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 在不同位置绘制多次glbatch
- QGraphicsScene项目在两次(x2)位置绘制
- SFML 将形状绘制到屏幕上的多个位置
- SFML参考窗口在绝对位置绘制
- 如何在 MFC 中围绕当前光标的位置绘制一个矩形
- (C++)在圆内夹紧 2D 位置(使用中点圆算法绘制)
- C++绘制矩形位置
- C++ SDL 根据鼠标位置绘制动态矩形
- 在3D世界中的显示器上固定位置绘制2D文本-OpenGL
- 如何将顶点位置传递给顶点着色器.我写了一个着色器,它不会在屏幕上绘制任何内容
- TMX问题,在正确位置绘制瓷砖(c++)
- 未在指定位置绘制的精灵
- OpenGL 形状仅在初始位置为 (0, 0, 0) 时绘制
- C++:如何在命令提示符的特定位置绘制ASCII字符
- 如何让OpenGL在我想要的位置绘制角色
- 绘制多个网格到不同的位置(DirectX 12)
- 如何使用opencv获取位置并绘制矩形
- OpenGL如何知道它应该基于GL_ARRAY_BUFFER绘制顶点到什么位置
- 无法在屏幕上的所需位置绘制矩形