我在glBufferSubData
尝试更新GL_UNIFORM_BUFFER
时发现了一种奇怪的行为。
在我的场景中有3个物体。
我使用以下结构作为我的材质定义
#pragma pack(push, 0)
struct Material
{
GLfloat diffuse[4];
GLfloat ambient[4];
GLfloat specular[4];
GLint useTex;
GLfloat shininess;
} material;
#pragma pack(pop)
在向其写入值后,我更新了统一缓冲区:
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(material), (void*)&material);
std::cout << "out usetex: " << material.useTex << "\n";
/*The terminal shows:
out usetex: 0
out usetex: 7
out usetex: 7*/
这是我的片段着色器(为调试而简化):
#version 330
layout (location = 0) out vec4 outputF;
layout (std140) uniform Material {
vec4 diffuse;
vec4 ambient;
vec4 specular;
int useTex;
float shininess;
};
void main()
{
if(useTex == 1)
{
outputF = vec4(1.0);
} else
outputF = vec4(vec3(float(useTex), 0.0, 0.0), 1.0);
}
从之前的测试中我知道diffuse
,ambient
,specular
和shininess
已正确更新,并且会呈现正确的信息。
着色器绘制三个完全白色的对象(因此useTex
显然为1)。但正如您可能从上面注意到的那样,值应为0,7和7。
由于这没有成功,我尝试手动更新useTex
。
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(material.diffuse)*3, sizeof(material.useTex), (void*)&material.useTex);
哪个没有改变任何东西。
然后是奇怪的事情。我尝试了以下方法:
GLint gi = *new GLint(0);
std::cout << "out gi: " << gi << "\n";
std::cout << "out usetex: " << material.useTex << "\n";
/* gives:
out gi: 0
out usetex: 0
out gi: 0
out usetex: 7
out gi: 0
out usetex: 7*/
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(material.diffuse)*3, sizeof(material.useTex), (void*)&gi);
其中呈现三个黑色对象(当您查看着色器时如预期的那样)。
GLint gi = *new GLint(material.useTex);
这个再次呈现三个白色物体......
那么*new GLint(material.useTex)
和*new GLint(0)
之间的区别是什么?两者都应该与1
不同,不应该是吗?
我已经使用glGetError()
检查了OpenGL错误。没有错误。
您可能需要更多代码。以下几行描述了如何为material
指定值。如果您需要更多,我可以添加此信息。但我无法想到任何可能与这个问题有关的事情。
std::map<std::string, Material> materials;
std::vector<Mesh> meshes;
std::vector<Buffer> buffers;
/*... Mesh file loading code ...*/
/*a new material was found (name: matKey):*/
if(...)
{
materials[matKey].useTex |= DIFFUSE;
}
if(...)
{
materials[matKey].useTex |= SPECULAR;
}
if(...)
{
materials[matKey].useTex |= NORMAL;
}
/* for each mesh the following is called (The key exists! I checked that.)*/
meshes[meshIndex].material = materials[/*some key string*/];
/* After all mesh objects are filled with values the following loop copies the data to a Buffer object*/
for(size_t i = 0; i < meshes.size(); i++)
{
buffers[i].assign(&meshes[i]);
}
/* somewhere in Buffer::assign(Mesh* m) the uniform buffer is generated and the material struct is copied to a internal variable*/
glGenBuffers(1, &materialBuffer);
glBindBuffer(GL_UNIFORM_BUFFER, materialBuffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(m->material), (void*)&m->material, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, Shader::MATERIAL_BLOCK_BINDING_POINT, materialBuffer);
material = m->material; //material is an internal variable
/* the class Buffer has also a render() function which starts with the uniform loading code that was described earlier (glBufferSubData() ...).*/
/* The `1` that is outputted in the shader comes from the constructor Mesh::Mesh()*/
Mesh::Mesh()
{
/* .. some initializing .. */
material.useTex = 1;
}
如何解决此问题的任何提示?