GLM mat4x4到布局限定符

Woo*_*ter 2 c++ opengl glsl glm-math

我目前正在学习OpenGL作为一个爱好项目,我已经达到了我想用实例化做一些粒子效果的地步.

为了给我的每个粒子提供自己的变换,我正在构建一个带有变换矩阵的向量并使用缓冲区的值:

    glBindBuffer(GL_ARRAY_BUFFER, particleEffect->getTransformationBufferID());
    std::vector<glm::mat4x4> particleTransformations;
    const std::vector<Particle>& particles = particleEffect->getParticles();
    for(std::vector<Particle>::const_iterator particleIt = particles.cbegin();
        particleIt != particles.cend();
        ++ particleIt)
    {
        particleTransformations.push_back(particleIt->getTransformation());
    }
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(particleTransformations[0]) * particles.size(),  particleTransformations.data());
    glEnableVertexAttribArray(4);
    glVertexAttribPointer(4, 16, GL_FLOAT, GL_FALSE, 0, 0);
Run Code Online (Sandbox Code Playgroud)

我正在以这种方式初始化我的转换缓冲区:

        glGenBuffers(1, &transformationBufferID_);
        glBindBuffer(GL_ARRAY_BUFFER, transformationBufferID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4x4) * particles_.size(), nullptr, GL_STREAM_DRAW);
Run Code Online (Sandbox Code Playgroud)

我使用这个简单的绘图代码:

    glVertexAttribDivisor(0, 0);
    glVertexAttribDivisor(1, 0);
    glVertexAttribDivisor(2, 0);
    glVertexAttribDivisor(3, 0);
    glVertexAttribDivisor(4, 1); //(4, 1), because each particle has its own transformation matrix at (layout location = 4)?!
    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, particleEffect->getVertices().size(), particleEffect->getParticles().size());//getVertices() are the same vertices for each particle
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(3);
    glDisableVertexAttribArray(4);
Run Code Online (Sandbox Code Playgroud)

我的顶点着色器标题如下所示:

    #version 430 core
    layout(location = 0) in vec3 vertexPosition;
    layout(location = 1) in vec3 normals;
    layout(location = 2) in vec4 colors;
    layout(location = 3) in vec2 uvCoordinates;
    layout(location = 4) in mat4 transformation;
Run Code Online (Sandbox Code Playgroud)

这会导致glError 1281崩溃,但前提是我使用glEnableVertexAttribArray(4).否则这不会崩溃.当我使用单位矩阵而不是我的变换矩阵时,我也能够绘制我的简单粒子网格.

我使用glGetAttribLocation(programID,"transformation")来确定位置是否正确.是的,这是正确的.

And*_*man 6

您的问题实际上根本不是layout限定符,您需要了解顶点属性的一些细微差别.

在GPU上,每个顶点属性是一个4分量向量,不管你声明它float,vec2,vec3vec4.对于我刚刚提到的所有类型都可以正常工作,该4分量向量的未使用部分分别为0,0,1.

对于mat4,然而,故事是非常不同的.A mat4实际上是四个vec4s 的数组,这意味着layout(location = 4) in mat4 transformation;实际上占据了4个不同的位置(所有顺序).

transformation由分配给位置四个4分量矢量4,5,67.glVertexAttribPointer(4, 16, GL_FLOAT, GL_FALSE, 0, 0);是错误的,这需要分成多个调用,如下所示:

// Setup 4 different vertex attributes (one for each column of your matrix).

// Each matrix has a stride of 64-bytes and each column of the matrix advances 16-bytes
glVertexAttribPointer (4, 4, GL_FLOAT, GL_FALSE, 64, 0);
glVertexAttribPointer (5, 4, GL_FLOAT, GL_FALSE, 64, 16);
glVertexAttribPointer (6, 4, GL_FLOAT, GL_FALSE, 64, 32);
glVertexAttribPointer (7, 4, GL_FLOAT, GL_FALSE, 64, 48);
Run Code Online (Sandbox Code Playgroud)

您还需要为所有这四个属性位置启用,禁用和设置顶点属性除数,以使代码正常工作.