微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何为GLSL中的数组结构表示glVertexAttribPointer的步幅和指针参数

如何解决如何为GLSL中的数组结构表示glVertexAttribPointer的步幅和指针参数

我很难从数据结构之类的数组结构中绘制顶点。我认为这可能是我在glVertexAttribPointer调用中使用跨步和指针参数的方式。我有这样的结构:

struct RadarReturn_t
{
    float32_t x;
    float32_t y;
    float32_t z;
    float32_t prob;
}

我正在像这样的另一种结构中使用RadarReturn_t

struct Detections_t
{
    uint32_t currentScanNum;
    std::array<RadarReturn_t,64> detections;
}

让我们假设我要画100张Detections_t。我创建了一个VBO来打包所有这些信息,如下所示:

        glGenBuffers(1,&mRadarVbo);
        for (uint32_t iScan = 0; iScan < mMaxnumScans; ++iScan)
        {
            // Set the timestamp to 0U
            mPersistentDetections.at(iScan).currentScanNum = 0U;

            for (uint32_t iDet = 0; iDet < 64; ++iDet)
            {
                RadarReturn_t& detection = mPersistentDetections.at(iScan).detections.at(iDet);
                detection.x              = 0.0F;
                detection.y              = 0.0F;
                detection.z              = 0.0F;
                detection.probability    = 0.0F;
            }
        }

        // Bind the VBO and copy the initial data to the graphics card
        glBindBuffer(GL_ARRAY_BUFFER,mRadarVbo);
        glBufferData(GL_ARRAY_BUFFER,mMaxnumScans * sizeof(DetectionData_t),&mPersistentDetections,GL_DYNAMIC_DRAW);
    

mPersistentDetections在哪里: std::array<DetectionData_t,mMaxnumScans> mPersistentDetections;

稍后,在代码中,我使用currentScanNum的新传入数据更新缓冲区:

// Offset is: 64 Radar returns plus one scanNumber
uint32_t offset = scanNum* ((64*sizeof(RadarReturn_t)) + 1*sizeof(gluint));
glBufferSubData(GL_ARRAY_BUFFER,offset,sizeof(gluint),&mPersistentDetections.at(scanNum).currentScanNum)

,对于detections,如下所示:

uint32_t dataSize = 64 * sizeof(RadarReturn_t);
glBufferSubData(GL_ARRAY_BUFFER,offset + sizeof(gluint),dataSize,&mPersistentDetections.at(scanNum).detections);

这就是我代表VAO的方式:

    // Bind the VAO
    glBindVertexArray(mRadarVao);

    // Specify the layout of timestamp data
    glVertexAttribIPointer(0,1,GL_UNSIGNED_INT,sizeof(DetectionData_t),(GLvoid*) 0);

    // Specify the layout of the radar return data
    glVertexAttribPointer(1,4,GL_FLOAT,GL_FALSE,(GLvoid*) (sizeof(gluint)));

最后是平局:

glDrawArrays(GL_POINTS,mMaxnumScans* 64);

如果我为mMaxnumScans = 100绘制此图形,则由于某种原因将无法在此处绘制100x64顶点。您能指出我哪里出问题了吗?


编辑: 根据@ Rabbid76的建议,我对Detections_t结构进行了如下修改

struct Detections_t
{    
    std::array<RadarReturn_t,64> detections;
    std::array<uint32_t,64> scanNumbers;
}

我还适当修改glBufferDataglBufferSubData的电话。这是我仍然遇到问题的地方。我无法获得正确的步幅参数。

glVertexAttribPointer(0,mDetectionAttributeSize,sizeof(RadarReturn_t),reinterpret_cast<void*>offsetof(DetectionData_t,detectionData_t::detections)));


glVertexAttribIPointer(1,mTimestampAttributeSize,GL_INT,reinterpret_cast<void*>(offsetof(DetectionData_t,DetectionData_t::scanCounter)));

如果将属性0的跨度设置为sizeof(Detection_t),则不会绘制所有点。只有sizeof(RadarReturn_t)绘制所有点。

如果我将属性1的跨度设置为sizeof(Detection_t),则只需几次扫描,检测的颜色(我正在使用scanNumber来更改alpha值)就会变得透明。

如果有人能告诉我属性0和属性1的步幅值是多少,我将不胜感激。

解决方法

我要回答我的问题。我可以通过更改RadarReturn_t结构来使其正常工作:

struct RadarReturn_t
{
    float32_t x;
    float32_t y;
    float32_t z;
    float32_t prob;
    int32_t   scanCounter;
};

然后使用如下属性:

glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,sizeof(RadarReturn_t),nullptr));

glVertexAttribIPointer(1,1,GL_INT,(void*) (4 * sizeof(GL_FLOAT)));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。