我在學習OpenGL並遇到「障礙」。 我用索引緩衝區畫了一些房屋(塊和金字塔)。 當將所有頂點(從所有房屋)加載到頂點緩衝區並使用1個大的索引緩衝區時,這可以正常工作。現在我想動畫化對象並逐個將它們加載到頂點緩衝區中,以便我可以逐個對對象執行變換。代碼與一個大緩衝區沒有多大區別,但是當我這樣做時,我只是看到屏幕上出現一些隨機的形狀。我的代碼如下:OpenGL indexbuffer在逐個加載對象時不起作用
我有一個世界級的持有3D對象列表,有一個所有頂點的大列表(用於試用),一個大列表(也是試用版)以及一個添加方法一個Object3D對象的世界。
class World
{
public:
World();
~World();
vector<Object3D> objects;
vector<glm::vec3> Vertices;
vector<GLushort> Indices;
void AddObject(Object3D &object);
};
Object3D類:
class Object3D
{
public:
Object3D();
~Object3D();
glm::vec3 Position;
vector<glm::vec3> Vertices;
vector<unsigned int> Indices;
};
世界AddObject方法,簡單地將對象添加到了「對象」名單,並增加了頂點和索引的「頂點」和「指標」列出了創建一個大的緩衝區:
void World::AddObject(Object3D &object) {
int oldVerticesSize = Vertices.size();
objects.push_back(object);
Vertices.insert(Vertices.end(), object.Vertices.begin(), object.Vertices.end());
for each (GLushort index in object.Indices)
{
Indices.push_back(index + oldVerticesSize);
}
}
當我渲染所有頂點和索引(如下所示)的大緩衝區時,它工作正常。
void WorldRenderer::Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(Vao); //use vao
glDrawElements(GL_TRIANGLES, World.Indices.size(), GL_UNSIGNED_SHORT, 0);
//glDrawArrays(GL_TRIANGLES, 0, World.Vertices.size());
glBindVertexArray(0); //release vao
//Model = glm::rotate(Model, 0.01f, glm::vec3(0.0f, 1.0f, 0.0f));
Mvp = Projection * View * Model;
glUniformMatrix4fv(UniformMvp, 1, GL_FALSE, glm::value_ptr(Mvp));
glutSwapBuffers();
//glutPostRedisplay();
}
當我通過對象迴路和負載的對象的頂點在緩衝一對象在-A-時間(如下所示)它顯示了一些隨機「的形狀」,它保持「拍攝」或快速變化。我在這裏做錯了什麼? 在此先感謝您的任何建議。
void WorldRenderer::Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int index = 0;
for each (Object3D mesh in World.objects)
{
Mvp = Projection * View * Model;
UpdateBuffer(mesh.Vertices, mesh.Indices);
glBindVertexArray(Vao); //use vao
glDrawElements(GL_TRIANGLES, mesh.Indices.size() , GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0); //release vao
glUniformMatrix4fv(UniformMvp, 1, GL_FALSE, glm::value_ptr(Mvp));
index++;
}
glutSwapBuffers();
}
UpdateBuffers方法:
void WorldRenderer::UpdateBuffer(vector<glm::vec3> vertices, vector<unsigned int> indices) {
//fill Vbo
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//fill ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(Vao);
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
}
對於第一渲染方法(不循環)的緩衝器中,看起來像這樣init方法創建一次:
void WorldRenderer::Init(int argc, char ** argv) {
InitGlutGlew(argc, argv);
InitMatrices();
glDisable(GL_CULL_FACE);
//-------------- init buffers --------------
// vbo vertices
glGenBuffers(1, &Vbo);
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBufferData(GL_ARRAY_BUFFER, World.Vertices.size() * sizeof(glm::vec3),
&World.Vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//ibo
glGenBuffers(1, &Ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, World.Indices.size() * sizeof(unsigned int),
&World.Indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// VAO setup
glGenVertexArrays(1, &Vao);
glBindVertexArray(Vao);
// Bind vertices to vao
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
//Bind elements
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
//------ init shaders -----------
InitShader();
}
謝謝! :D這讓我更進了一步(我應該更加整潔)。但是現在我只能看到大約一半的三角形。 indexbuffer和vertexbuffer看起來很好,我試着移動一些索引並禁用Cull的面部,但我一直看到每個網格的相同三角形。任何想法爲什麼這樣?圖片不錯:https://puu.sh/vwZAc/e108f7fb9c.png。圖片不好:https://puu.sh/vx0j6/a8eddd1d7d.png –
嘗試在循環外釋放「glBindVertexArray(0); //釋放vao」....我的意思是在每個循環之後......在函數「Render()」 – Naidu
這似乎並不工作:\。也嘗試glBindVertexArray(Vao)外循環(這似乎邏輯),但不幸的是沒有改變。 –