Opengl - 实例化属性

时间:2015-05-30 17:45:50

标签: c++ opengl geometry-instancing

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

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

我将跳过一些实现细节,以免使这个问题更复杂。假设我在描述的操作之前绑定了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,右边的粒子组等于1.第二组粒子具有适当的位置但是不正确地指向FluidColors阵列。

我所知道的:

  • 我设置FluidColors制服的方式不是问题。如果我在着色器中对颜色选择进行硬编码,如下所示:

    sphereColor = FluidID == 0? FluidColors [0]:FluidColors 1;

我明白了:

enter image description here

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

1 个答案:

答案 0 :(得分:2)

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

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