c++ - Opengl - 实例化属性

标签 c++ opengl geometry-instancing

我使用 oglplus - 它是 OpenGL 的 C++ 包装器。

我在为我的粒子渲染器定义实例化数据时遇到问题 - 位置工作正常,但当我想从同一个 VBO 实例化一堆整数时出现问题。

我将跳过一些实现细节,以免使这个问题变得更复杂。假设我在描述的操作之前绑定(bind)了 VAO 和 VBO。

我有一个结构数组(称为“粒子”),我是这样上传的:

glBufferData(GL_ARRAY_BUFFER, sizeof(Particle) * numInstances, newData, GL_DYNAMIC_DRAW);

结构的定义:

struct Particle
{
    float3 position;        
    //some more attributes, 9 floats in total
    //(...)
    int fluidID;        
};

我使用辅助函数来定义 OpenGL 属性,如下所示:

void addInstancedAttrib(const InstancedAttribDescriptor& attribDesc, GLSLProgram& program, int offset=0)
        {
            //binding and some implementation details
            //(...)

            oglplus::VertexArrayAttrib attrib(program, attribDesc.getName().c_str());
            attrib.Pointer(attribDesc.getPerVertVals(), attribDesc.getType(), false, sizeof(Particle), (void*)offset);

            attrib.Divisor(1);
            attrib.Enable();
        }

我像这样为位置和流体添加属性:

            InstancedAttribDescriptor posDesc(3, "InstanceTranslation", oglplus::DataType::Float);
            this->instancedData.addInstancedAttrib(posDesc, this->program);

            InstancedAttribDescriptor fluidDesc(1, "FluidID", oglplus::DataType::Int);
            this->instancedData.addInstancedAttrib(fluidDesc, this->program, (int)offsetof(Particle,fluidID));

顶点着色器代码:

uniform vec3 FluidColors[2];

in vec3 InstanceTranslation;
in vec3 VertexPosition;
in vec3 n;

in int FluidID;

out float lightIntensity;
out vec3 sphereColor;

void main()
{   

    //some typical MVP transformations
    //(...)
    sphereColor = FluidColors[FluidID];
    gl_Position = projection * vertexPosEye;

}

这段代码作为一个整体产生了这样的输出:

opengl-problem

如您所见,粒子按照我希望的方式排列,这意味着“InstanceTranslation”属性设置正确。左侧粒子组的 FluidID 值为 0,右侧粒子组的 FluidID 值为 1。第二组粒子具有正确的位置,但在 FluidColors 数组中的索引不正确。

我所知道的:

  • 我设置 FluidColors uniform 的方式没有问题。如果我像这样在着色器中硬编码颜色选择:

    sphereColor = FluidID == 0?流体颜色[0]:流体颜色1 ;

我得到:

enter image description here

  • OpenGL 从 glGetError 返回 GL_NO_ERROR,所以我提供的枚举/值没有问题
  • offsetof 宏不是问题。我尝试使用硬编码值,但它们也不起作用。
  • 这不是 GLint 的兼容性问题,我使用简单的 32 位整数(用 sizeof(int) 检查过)
  • 我需要使用 FluidID 作为索引到颜色数组的实例化属性,否则,如果我要将粒子组的颜色设置为简单的 vec3 制服,我必须对相同的粒子类型进行批处理(使用相同的 FluidID)放在一起,这意味着要对它们进行排序,而且操作成本太高。

最佳答案

对我来说,这似乎是您如何设置 fluidID 的问题属性指针。由于您使用类型 int在着色器中,您必须使用glVertexAttribIPointer()设置属性指针。您使用普通 glVertexAttribPointer() 设置的属性函数仅适用于基于 float 的属性类型。它们接受整数输入,但当着色器访问它们时,数据将被转换为 float 。

在 oglplus 中,您显然必须使用 VertexArrayAttrib::IPointer()而不是 VertexArrayAttrib::Pointer()如果您想使用整数属性。

关于c++ - Opengl - 实例化属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30549390/

相关文章:

opengl - 测试着色器的兼容性

c++ - OpenGL 实例化 : how to debug missing per instance data

c++ - 如何创建指向另一个列表中对象的指针列表?

c++ - 将 QListView 与 QStringListModel 一起使用时无法使用 setData 设置工具提示

C++ - 如何实现 Mask R-CNN?

C++ OpenGL 网格渲染

c++ - 通过操纵 gl_FragDepth 将选定的线对象优先于其他对象

javascript - 通过实例化,我无法更改各个子几何图形的透明度/不透明度

c++ - 在发布版本中使用 assert() 时避免未使用的变量警告