数据未正确发送到缓冲区中?

时间:2019-02-16 08:11:22

标签: c++ opengl glsl

我正在尝试创建一个系统,该系统使用属性将数据从缓冲区传递到顶点着色器,我已经有了一些,但是这个新系统无法正常工作。我试图将单数传递给我的顶点着色器。我知道我所有其他系统都能正常工作,并且进入缓冲区的数据是正确的。当我放置一个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的位置。

1 个答案:

答案 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());