让我向您介绍Fishtank:
这是一个水族馆模拟器,我在进入Vulkan之前在OpenGL上学习。
我画了很多这样的鱼:
现在我添加了网格功能,如下所示:
但是当我让它转过一段时间时,这些线条出现了:
我已经看到某个地方清除了深度缓冲区,我做了,但这并没有解决问题。
这是函数的代码:
void Game::drawGrid()
{
std::vector<glm::vec2> gridVertices;
for (unsigned int x = 1; x < mGameMap.mColCount; x += 1) //Include the last one as the drawed line is the left of the column
{
gridVertices.push_back(glm::vec2(transformToNDC(mWindow, x*mGameMap.mCellSize, mGameMap.mCellSize)));
gridVertices.push_back(glm::vec2(transformToNDC(mWindow, x*mGameMap.mCellSize, (mGameMap.mRowCount-1)*mGameMap.mCellSize)));
}
for (unsigned int y = 1; y < mGameMap.mRowCount; y += 1) //Same here but special info needed:
// Normally, the origin is at the top-left corner and the y-axis points to the bottom. However, OpenGL's y-axis is reversed.
// That's why taking into account the mRowCount-1 actually draws the very first line.
{
gridVertices.push_back(glm::vec2(transformToNDC(mWindow, mGameMap.mCellSize, y*mGameMap.mCellSize)));
gridVertices.push_back(glm::vec2(transformToNDC(mWindow, (mGameMap.mColCount - 1)*mGameMap.mCellSize, y*mGameMap.mCellSize)));
}
mShader.setVec3("color", glm::vec3(1.0f));
glBufferData(GL_ARRAY_BUFFER, gridVertices.size()*sizeof(glm::vec2), gridVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT_VEC2, GL_FALSE, sizeof(glm::vec2), (void*)0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_LINES, 0, gridVertices.size()*sizeof(glm::vec2));
glClear(GL_DEPTH_BUFFER_BIT);
}
我想删除这些行并理解为什么OpenGL会这样做(或者也许是我,但我看不到哪里)。
答案 0 :(得分:4)
这是有问题的一行:
glDrawArrays(GL_LINES, 0, gridVertices.size()*sizeof(glm::vec2));
如果查看documentation for this function,您会找到
void glDrawArrays(GLenum模式,GLint优先,GLsizei计数);
count :指定要呈现的索引数
但是你传递的是字节大小。因此,您要求OpenGL绘制比顶点缓冲区中更多的顶点。您正在使用的特定OpenGL实现可能是读取网格顶点缓冲区的末尾,并从鱼顶点缓冲区中查找顶点以进行绘制(但此行为未定义)。
所以,只需将其更改为
即可glDrawArrays(GL_LINES, 0, gridVertices.size());
一般性评论:每次要绘制相同的东西时都不要创建顶点缓冲区。在应用程序的开头创建它们并重新使用它们。如果需要,您也可以更改其内容,但要小心,因为它带有性能价格。创建顶点缓冲区的成本更高。