【问题标题】:Multiple [in] attributes in shader - OpenGL着色器中的多个 [in] 属性 - OpenGL
【发布时间】:2015-05-03 17:11:01
【问题描述】:

我要学习 OpenGL 4,现在我使用纹理。我想将纹理应用到球体,我的顶点着色器如下所示:

#version 410

in vec4 vPosition;
in vec2 texCoord;

uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;

smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;
smooth out vec2 uvCoord;

void main (void)
{
    uvCoord = texCoord;
    vec3 vNormal = vPosition.xyz / vPosition.w;
    vVaryingNormal = normalMatrix * vNormal;
    vec4 vPosition4 = mvMatrix * vPosition;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
    vVaryingLightDir = normalize(vLightPosition - vPosition3);
    gl_Position = mvpMatrix * vPosition;
}

定义球体的坐标和三角索引后,我使用以下代码构建了一个 VAO:

void SphereShaderProgram::BuildVAO()
{
    // Generate and bind the vertex array object
    glGenVertexArrays(1, &_vao);
    glBindVertexArray(_vao);

    // Generate and bind the vertex buffer object
    glGenBuffers(1, &_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    glBufferData(GL_ARRAY_BUFFER, _sphereCoordinates.size() * sizeof(float), &_sphereCoordinates[0], GL_STATIC_DRAW);

    // Generate and bind the index buffer object
    glGenBuffers(1, &_ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _sphereIndexes.size() * sizeof(unsigned int), &_sphereIndexes[0], GL_STATIC_DRAW);

    // Generate and bind texture
    _texture = LoadTexture("ball.bmp");

    LoadAttributeVariables();

    glBindVertexArray(0);
}

GLuint ProgramManager::LoadTexture(const char* imagepath)
{    
    unsigned int width, height;
    unsigned char * data = LoadBMP(imagepath, &width, &height);

    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    return textureID;
}

为了加载属性,我做了以下(在使用纹理之前):

void SphereShaderProgram::LoadAttributeVariables()
{
    // Vertex Attributes
    GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
    glEnableVertexAttribArray(VertexPosition_location);
    glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
}

但是,现在,我有一个数组 (_sphereTexCoords),其中包含纹理坐标,我真的不知道在传递顶点坐标时如何将它传递给顶点着色器。我必须创建另一个 VBO 吗?我虽然想做这样的事情:

GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "texCoord");
glEnableVertexAttribArray(TextureCoord_Location);
glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);

但我真的不知道如何指定这与_sphereTexCoords 数组有关。

编辑

我试过了,但是没用。

void SphereShaderProgram::BuildVAO()
{
    // Generate and bind the vertex array object
    glGenVertexArrays(1, &_vao);
    glBindVertexArray(_vao);

    // Generate and bind the vertex buffer object
    glGenBuffers(2, _vbo);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, _sphereCoordinates.size() * sizeof(float), &_sphereCoordinates[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, _textureCoordinates.size() * sizeof(float), &_textureCoordinates[0], GL_STATIC_DRAW);

    // Generate and bind the index buffer object
    glGenBuffers(1, &_ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _sphereIndexes.size() * sizeof(unsigned int), &_sphereIndexes[0], GL_STATIC_DRAW);

    // Generate and bind texture
    _texture = LoadTexture("ball.bmp");

    LoadAttributeVariables();

    glBindVertexArray(0);
}

void SphereShaderProgram::LoadAttributeVariables()
{
    // Vertex Attributes
    GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
    glEnableVertexAttribArray(VertexPosition_location);
    glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "texCoord");
    glEnableVertexAttribArray(TextureCoord_Location);
    glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);
}

绑定程序时出错。

【问题讨论】:

    标签: c++ opengl textures shader


    【解决方案1】:

    你很亲密。我唯一看到的缺失是您在调用glVertexAttribPointer() 之前没有绑定正确的缓冲区。当您调用glVertexAttribPointer() 时,您指定属性的数据将从当前绑定到GL_ARRAY_BUFFER 的缓冲区中提取。

    因此,您的 LoadAttributeVariables() 方法应该是:

    GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
    glEnableVertexAttribArray(VertexPosition_location);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);
    glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
    
    GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "texCoord");
    glEnableVertexAttribArray(TextureCoord_Location);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);
    glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多