我正在尝试创建一个系统,该系统使用属性将数据从缓冲区传递到顶点着色器,我已经有了一些,但是这个新系统无法正常工作。我试图将单数传递给我的顶点着色器。我知道我所有其他系统都能正常工作,并且进入缓冲区的数据是正确的。当我放置一个int而不是属性时,矩阵可以正常工作,所以我知道这与缓冲区有关。
我已经测试了所有系统。实际上,这是因为我将整数属性插入到顶点着色器中数组的运算符中,即使它不直接位于整数中并且我将另一个int设置为整数,它也无法工作。并且我最终得到一个全白的屏幕,由于某种原因,当我将属性设置为3而不是4时,屏幕变为红色。如果我做1,它仍然会变成白色。进入glbufferdata的数据值为1,我确保它的长度正确,并且每个EACH顶点都有一对。
if (reload == 1)
{
char scenepath[32] = "Gamedata\\Scenes\\Scene01.map";
LoadScene(scenepath);
for (size_t i = 0; i < ObjNames.size(); i++)
{
loadobj(modelloc[i]);
}
reorder_index();
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size() * sizeof(int), &index[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, objbuffer);
glBufferData(GL_ARRAY_BUFFER, model_index.size() * sizeof(int), &model_index[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, objbuffer); //not workinngggg
glVertexAttribPointer(3, 1, GL_INT, GL_FALSE, 0, (void*)0);
}
}
#version 430
layout(location = 0) in vec3 v_pos;
//layout (location = 1) in vec3 uv;
layout (location = 2) in vec3 v_Normal;
layout (location = 3) in int object;
out vec3 FragPos;
out vec3 Normalout;
uniform mat4 outmatrix[];
uniform mat4 model;
void main() {
gl_Position = outmatrix[object] * vec4(v_pos, 10.0f);
FragPos = vec3(model * vec4(v_pos , 0.0));
Normalout = v_Normal;
}
我期望属性3中的整数进入outmatrix [interger_here],以产生在我的游戏中具有多个矩阵的预期结果。
我很高兴您的支持,因为我真的很笨拙,并且屏幕的颜色取决于attrib的位置。
答案 0 :(得分:1)
如果要定义通用整数顶点属性数据的数组,则必须使用glVertexAttribIPointer
(专注于 I
)而不是{{1} }:
glVertexAttribPointer
请注意,glBindBuffer(GL_ARRAY_BUFFER, objbuffer);
glVertexAttribIPointer(3, 1, GL_INT, 0, (void*)0);
与整数数据类型(例如glVertexAttribPointer
)结合使用会将整数属性转换为浮点值。
统一变量数组由属性索引是无效的!
请参见OpenGL Shading Language 4.30 Specification - 4.3.9 Interface Blocks; page 53
统一或着色器存储块数组只能使用动态统一整数表达式进行索引,否则结果不确定。
(在最新的GLSL版本4.60中,保持不变)
请注意,统一变量存储在默认的统一块中,并且属性不是“动态统一”的,因为它对于每次顶点着色器的运行都可能不同。
这意味着,根据规范,您的代码结果是不确定的。
GL_INT
一种解决方法是使用内部格式GL_RGBA32F
将矩阵编码为二维(4 * N)纹理:
#version 430
// [...]
layout (location = 3) in int object;
uniform mat4 outmatrix[];
void main()
{
// [...]
gl_Position = outmatrix[object] * vec4(v_pos, 10.0f);
}
使用texelFetch
从纹理中获取矩阵值:
const int N = ...;
std::vector<glm::mat4> outmatrix(N);
GLuint tbo;
glGenTextures(1, tbo);
glBindTexture(GL_TEXTURE_2D, tbo);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, N, 0, GL_RGBA, GL_FLOAT, outmatrix.data());