我在Google / Stackflow上进行了很多搜索,无法找到我特定问题的答案。我尝试使用修补的球体网格和以下参考文献实现实例化:
http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html
https://learnopengl.com/Advanced-OpenGL/Instancing
我试图调试我自己的代码,但似乎没有任何工作...我一直得到一个看起来像modelmatrix值已损坏或设置不正确的输出。这是在传递模型的Identity矩阵时在不同的相机旋转时的样子:
如果我将顶点着色器中的模型矩阵硬编码为Identity Matrix,那么它就可以了:
所以在我看来,模型矩阵没有被正确传递,因为我花了好几天检查我的代码并尝试不同的东西。我希望有人可以对此进行评论并发现问题..谢谢!
for (unsigned int Level = 0; Level < Levels; Level++)
{
FrameTicks[Level] = 0;
VBO_SeedVector[Level] = 0;
VBO_ModelMatrix[Level] = 0;
//. Bind VAO for Object's Level of Detail
glBindVertexArray(Meshes->GetMesh(Level)->GetVAO());
//. Generate Buffers for Object's SeedVector
glGenBuffers(1, &VBO_SeedVector[Level]);
//. Generate Instance Array for Object's SeedVector
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4f), (void*)0);
glVertexAttribDivisor(2, 1);
//. Generate Buffers for Object's ModelMatrix
glGenBuffers(1, &VBO_ModelMatrix[Level]);
//. Generate Instance Array for Object's ModelMatrix
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(0 * sizeof(Vector4f)));
glVertexAttribDivisor(3, 1);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(1 * sizeof(Vector4f)));
glVertexAttribDivisor(4, 1);
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(2 * sizeof(Vector4f)));
glVertexAttribDivisor(5, 1);
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(3 * sizeof(Vector4f)));
glVertexAttribDivisor(6, 1);
ObjectSeeds.push_back(std::vector<Vector4f>());
ObjectModels.push_back(std::vector<Matrix4f>());
}
//. Load Instance Arrays into VAOs
for (unsigned int Level = 0; Level < Levels; Level++)
{
glBindVertexArray(Meshes->GetMesh(Level)->GetVAO());
glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
glBufferData(GL_ARRAY_BUFFER, ObjectSeeds[Level].size() * sizeof(Vector4f), &ObjectSeeds[Level], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
glBufferData(GL_ARRAY_BUFFER, ObjectModels[Level].size() * sizeof(Matrix4f), &ObjectModels[Level], GL_STATIC_DRAW);
}
//. Empty Detailed Mesh
if (Meshes == nullptr)
return;
//. Enable VAA for Px, Py, Pz, U
glEnableVertexAttribArray(0);
glVertexAttribDivisor(0, 0);
//. Enable VAA for Nx, Ny, Nz, V
glEnableVertexAttribArray(1);
glVertexAttribDivisor(1, 0);
//. Enable VAA for Seed Vector
glEnableVertexAttribArray(2);
glVertexAttribDivisor(2, 0);
//. Enable VAA for Model Matrix
glEnableVertexAttribArray(3);
glVertexAttribDivisor(3, 1);
glEnableVertexAttribArray(4);
glVertexAttribDivisor(4, 1);
glEnableVertexAttribArray(5);
glVertexAttribDivisor(5, 1);
glEnableVertexAttribArray(6);
glVertexAttribDivisor(6, 1);
//. Render Instances For Each Ring
for (unsigned int Level = Levels - 1; Level > 0; Level--)
{
unsigned int RingSize = ObjectModels[Level].size();
//. Empty Ring
if (RingSize == 0)
continue;
BaseMesh* Mesh = Meshes->GetMesh(Level);
//. Empty Mesh
if (Mesh == nullptr)
continue;
unsigned int VAO = Mesh->GetVAO();
if (VAO == 0)
continue;
//. Render Instances
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES, Mesh->Elements.size(), GL_UNSIGNED_INT, 0, RingSize);
}
glDisableVertexAttribArray(6);
glDisableVertexAttribArray(5);
glDisableVertexAttribArray(4);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
#version 440
layout (location = 0) in vec4 Position;
layout (location = 1) in vec4 Normal;
layout (location = 2) in vec4 Seed;
layout (location = 3) in vec4 ModelCol0;
layout (location = 4) in vec4 ModelCol1;
layout (location = 5) in vec4 ModelCol2;
layout (location = 6) in vec4 ModelCol3;
//uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;
out vec3 mPosition;
out vec3 vPosition;
out vec3 vNormal;
out vec2 vSample;
void main()
{
mPosition = Position.xyz;
mat4 vModel = mat4(1.0);
vModel[0] = ModelCol0;
vModel[1] = ModelCol1;
vModel[2] = ModelCol2;
vModel[3] = ModelCol3;
vPosition = (vModel * vec4(mPosition.xyz, 1.0)).xyz;
vNormal = (vModel * vec4(Normal.xyz, 0.0)).xyz;
vSample = vec2(Position.w, Normal.w);
gl_Position = Projection * View * vModel * vec4(mPosition.xyz, 1.0);
}
我更新了InstanceObject :: Init()以在VAA调用之前绑定VBO,如下所示:
for (unsigned int Level = 0; Level < Levels; Level++)
{
FrameTicks[Level] = 0;
VBO_SeedVector[Level] = 0;
VBO_ModelMatrix[Level] = 0;
//. Bind VAO for Object's Level of Detail
glBindVertexArray(Meshes->GetMesh(Level)->GetVAO());
if (!LogErrorGL(std::cout, "glGenBuffers"))
return false;
//. Generate Buffers for Object's SeedVector
glGenBuffers(1, &VBO_SeedVector[Level]);
if (!LogErrorGL(std::cout, "glGenBuffers"))
return false;
//. Enable Vertex Attribute Arrays
glEnableVertexAttribArray(2);
if (!LogErrorGL(std::cout, "glEnableVertexAttribArray"))
return false;
//. Bind Buffer to Setup Instance Array
glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
if (!LogErrorGL(std::cout, "glBindBuffer"))
return false;
//. Generate Instance Array for Object's SeedVector
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vector4f), (void*)0);
if (!LogErrorGL(std::cout, "glVertexAttribPointer"))
return false;
//. Apply Attribute Divisors
glVertexAttribDivisor(2, 1);
if (!LogErrorGL(std::cout, "glVertexAttribDivisor"))
return false;
//. Unbind Buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
//.
//.
//.
//. Generate Buffers for Object's ModelMatrix
glGenBuffers(1, &VBO_ModelMatrix[Level]);
if (!LogErrorGL(std::cout, "glGenBuffers"))
return false;
//. Enable Vertex Attribute Arrays
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6);
if (!LogErrorGL(std::cout, "glEnableVertexAttribArray"))
return false;
//. Bind Buffer to Setup Instance Arrays
glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
if (!LogErrorGL(std::cout, "glBindBuffer"))
return false;
//. Generate Instance Array for Object's ModelMatrix
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(0 * sizeof(Vector4f)));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(1 * sizeof(Vector4f)));
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(2 * sizeof(Vector4f)));
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix4f), (void*)(3 * sizeof(Vector4f)));
if (!LogErrorGL(std::cout, "glVertexAttribPointer"))
return false;
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
glVertexAttribDivisor(5, 1);
glVertexAttribDivisor(6, 1);
if (!LogErrorGL(std::cout, "glVertexAttribDivisor"))
return false;
//. Unbind Buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
//. Bind Default VAO ~ move to outside For Loop
glBindVertexArray(0);
if (!LogErrorGL(std::cout, "glBindVertexArray"))
return false;
ObjectSeeds.push_back(std::vector<Vector4f>());
ObjectModels.push_back(std::vector<Matrix4f>());
}
当我尝试绑定VAO以加载更新数据时,所有工作都没有抛出任何GL错误,但我在InstanceObject :: Update()部分得到GL_INVALID_OPERATION:
//. Load Instance Arrays into VAOs
for (unsigned int Level = 0; Level < Levels; Level++)
{
glBindVertexArray(Meshes->GetMesh(Level)->GetVAO()); //. GL_INVALID OPERATION
if (!LogErrorGL(std::cout, "glBindVertexArray"))
return;
//glGenBuffers(1, &VBO_SeedVector[Level]);
glBindBuffer(GL_ARRAY_BUFFER, VBO_SeedVector[Level]);
if (!LogErrorGL(std::cout, "glBindBuffer"))
return;
glBufferData(GL_ARRAY_BUFFER, ObjectSeeds[Level].size() * sizeof(Vector4f), &ObjectSeeds[Level], GL_STATIC_DRAW);
if (!LogErrorGL(std::cout, "glBufferData"))
return;
//glGenBuffers(1, &VBO_ModelMatrix[Level]);
glBindBuffer(GL_ARRAY_BUFFER, VBO_ModelMatrix[Level]);
if (!LogErrorGL(std::cout, "glBindBuffer"))
return;
glBufferData(GL_ARRAY_BUFFER, ObjectModels[Level].size() * sizeof(Matrix4f), &ObjectModels[Level], GL_STATIC_DRAW);
if (!LogErrorGL(std::cout, "glBufferData"))
return;
答案 0 :(得分:0)
在<html>
<head>
<title>HHH</title>
</head>
<body>
<h1 id="text" onmousedown="MouseDown()" onmouseup="Mouseup()">BBB </h1>
<script>
function MouseDown() {
document.getElementById("text").innerHTML="CCC" ;
}
function Mouseup() {
document.getElementById("text").innerHTML="AAA" ;
}
</script>
</body>
</html>
中,您实际上绑定您正在创建的任何VBO。
GL'a属性数组指针始终包含对缓冲区对象名称的引用,以及到此缓冲区的字节偏移量(以及其他内容,如数据格式和步幅等)。 InstanceObject::Init()
会将当前绑定的 glVertexAttribPointer
的名称存储在属性指针中。