簡體   English   中英

OpenGL 實例化渲染僅繪制第一個實例

[英]OpenGL instanced rendering only draws first instance

我一直在嘗試在我現有的 opengl 框架中實現實例化渲染。 我有一個 vec3 偏移數組,我將其緩沖到 VBO 中,然后調用 glDrawElementsInstanced(...) 和(應該)然后將每個頂點偏移指定的量。 問題是,第一個實例工作正常(更改索引 0 處的數組中的值會在繪制后更改 position)。 但是,它沒有繪制其他實例,我不知道它可能是什么。

過程:

  1. 通過使用適當的 VBL 創建 VAO 和頂點 VBO 和 IBO 來初始化渲染器
  2. 將“偏移”VBO 和 VBL 添加到具有布局 3 的屬性的 VAO(並划分)
  3. 收集所有要繪制的頂點和所有偏移量
  4. 在各自的對象中緩沖頂點、索引和偏移數據
  5. 綁定 VAO 並使用相應的實例計數調用 glDrawElementsInstanced(...)

我已經使用renderdoc,我似乎可以在緩沖區中的某個地方找到數據(偏移數組),盡管當我直接在網格查看器中查看它時,實例0之后的每個實例都將偏移列清空(不是零,而是空白 - position、texcoord 和正常列仍按預期充滿數據)。

代碼:

頂點着色器:

#version 330 core

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec3 offset;

//MVP
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Proj;

//Lighting
uniform mat4 u_InvTranspModel;
uniform mat4 u_LightMVP;

out vec2 v_TexCoord;
out vec3 v_Normal;
out vec3 v_FragPos;
out vec4 v_LightSpacePos;

void main()
{   
    gl_Position = u_Proj * u_View * u_Model * (position+vec4(offset,0));
    v_TexCoord = texCoord;
    v_Normal = mat3(u_InvTranspModel) * normal;

    //Light
    v_FragPos = vec3(u_Model*position);
    v_LightSpacePos = u_LightMVP * position;
}

VAO添加緩沖方法:

void VertexArray::addBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout, int start)
{
    this.bind();
    vb.bind();
    const std::vector<VertexBufferElement> elements = layout.getElements();
    unsigned int offset = 0;
    for (unsigned int i = 0; i < elements.size(); i++)
    {
        const VertexBufferElement element = elements[i];
        glEnableVertexAttribArray(i + start);
        glVertexAttribPointer(i + start, element.count, element.type, element.normalized,
            layout.getStride(), (const void*)offset);
        offset += element.count * VertexBufferElement::getTypeSize(element.type);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glVertexAttribDivisor(i + start, (int)element.instanced);
    }
    glBindVertexArray(0);
}

VBO 緩沖方法(數據來自浮點向量):

void VertexBuffer::bufferData(const void* data, unsigned int count) {
    glBindBuffer(GL_ARRAY_BUFFER, m_ID);
    glBufferData(GL_ARRAY_BUFFER, count * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), data);
}

偏移數組:

glm::vec3 offsets[10]
    {
        {0,30,0}, { 50, 0, 50 }, { -5, 0, 5}, { -35, 0, 0}, { -35, 0, 40 },
        {0,20,0}, { 10, 0, 10 }, { -52, 0, 53}, { -335, 0, 0}, { -351, 0, 430 }
    };

我設法解決了這個問題:

在 glVertexAttribPointer(...) 階段,我使用來自 layout.getStride() 的數據。 我已將此步幅大小乘以數組的大小,而唯一需要乘以數組大小的部分是當我緩沖頂點時:glVertexAttribDivider(i,1) 方法將其划分得很好。

顯然發生的事情是着色器正在讀取第一個實例數據,然后跳到下一個實例的數據末尾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM