【问题标题】:Fragment shader color error with multiple buffers具有多个缓冲区的片段着色器颜色错误
【发布时间】:2017-12-17 06:19:42
【问题描述】:

我最近一直在尝试 OpenGL,但又遇到了一个问题。 如果在我的程序中我通过制服设置颜色,我可以用我选择的任何颜色绘制多个顶点数组。但是传递为顶点数组对象生成的两个缓冲区会导致奇怪的着色,其中 0 表示顶点位置,1 表示颜色。

我的主要功能:

int main(){
    Window window(960,540);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    Reader read1("src/shaders/test.vert");
    Reader read2("src/shaders/test.frag");
    char * r1 = read1.getData();
    char * r2 = read2.getData();

    GLfloat vert[] = {
        0, 0, 0,
        0, 3, 0,
        8, 3, 0,
        8, 0, 0
    };
    GLushort indices[] = { 
        0,1,2, 
        2,3,0
    };

    GLfloat colors[] = {
        1, 0, 1, 1,
        1, 0, 1, 1,
        1, 0, 1, 1,
        1, 0, 1, 1,
    };

    VertexArray vao;
    Buffer* vbo = new Buffer(vert, 4 * 4, 3);

    vao.addBuffer(vbo, 0);
    vao.addBuffer(new Buffer(colors,4 * 4 , 4), 1);


    indexBuffer ibo(indices, 6);
    Shader shader(r1, r2);
    shader.enable();
    shader.setUniformMat4("pr_matrix", mat4::orthographic(0.0f, 16.0f, 0.0f, 9.0f, -1.0f, 1.0f));
    shader.setUniformMat4("ml_matrix", mat4::translation(vec3(4, 3, 0)));

    shader.setUniform2f("light_pos", vec2(8.0f, 4.5f));
    shader.setUniform4f("colour", vec4(0.2, 0.3, 0.8, 1));

    while (!window.closed()){
        window.clear();

        double x, y;
        x = window.getX();
        y = window.getY();

        shader.setUniform2f("light_pos", vec2((float)((x)*16.0f / 960.0f), (float)(9 - 9 * (y) / 540.0f)));

        vao.bind();
        ibo.bind();
        shader.setUniform4f("colour", vec4(0.2, 0.3, 0.8, 1));
        shader.setUniformMat4("ml_matrix", mat4::translation(vec3(4, 3, 0)));
        glDrawElements(GL_TRIANGLES, ibo.getCount(), GL_UNSIGNED_SHORT, 0);
        ibo.unbind();
        vao.unbind();

        window.update();
    }
    return 0;
}

我的顶点着色器:

#version 410 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;

uniform mat4 pr_matrix ;
uniform mat4 vw_matrix = mat4(1.0f);
uniform mat4 ml_matrix = mat4(1.0f);

out DATA{
    vec4 position;
    vec4 color;
} vs_out;

out vec4 pos;

void main(){
    gl_Position = pr_matrix * vw_matrix * ml_matrix * vec4(position,1) ;
    vs_out.position = ml_matrix * vec4(position,1);
    vs_out.color = color;
}

我的片段着色器:

#version 410 core
layout(location = 0) out vec4 color ;

uniform vec4 colour;
uniform vec2 light_pos;

in DATA{
    vec4 position;
    vec4 color;
} fs_in;

void main(){
    float intensity = 1.0f / length(fs_in.position.xy - light_pos);
    //color = fs_in.color * intensity;
    color = fs_in.color * intensity;
}

如果需要更正我的缓冲区类:

Buffer::Buffer(GLfloat *data, GLsizei count, GLuint compCountExt) : compCount (compCountExt) {

    glGenBuffers(1, &bufferId);
    glBindBuffer(GL_ARRAY_BUFFER,bufferId);
    glBufferData(GL_ARRAY_BUFFER, count* sizeof(GLfloat), data, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
}

void Buffer::bind() const {
    glBindBuffer(GL_ARRAY_BUFFER, bufferId);
}

void Buffer::unbind() const {
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

编辑:

vertexArray 类的代码:

VertexArray::VertexArray(){
    glGenVertexArrays(1,&arrayID);

}
void VertexArray::bind() const{
    glBindVertexArray(arrayID);
}
void VertexArray::unbind() const{
    glBindVertexArray(0);
}
VertexArray::~VertexArray(){
}
void VertexArray::addBuffer(Buffer* buffer, GLuint index){
    bind();

    glBindBuffer(GL_ARRAY_BUFFER, arrayID);
    glEnableVertexAttribArray(index);
    glVertexAttribPointer(index, buffer->getComCount(), GL_FLOAT, GL_FALSE, 0, 0);

    buffer->unbind();
    unbind();

}

在这个类中有对顶点属性指针的调用。

【问题讨论】:

  • glVertexAttribPointer 的电话在哪里?并且请尝试证明在提交之前阅读您的帖子并且只使用适当的标签。例如,visual-studio-2013 标记表示“不要使用此标记,除非您对 Visual Studio 有特定问题——而不仅仅是编码问题”
  • @BDL 我现在在问题中添加了 vertexArray 类。对不起,首先是不合适的标签..
  • @Rabbid76 感谢您的建议先生。我现在已经上传了包含你提到的 glfunctions 的 vertexArray 类。抱歉把帖子写得太长了,下次我会努力做到这一点..

标签: c++ opengl


【解决方案1】:

glVertexAttribPointer 指的是当前绑定的数组缓冲区。这意味着您必须在使用 glVertexAttribPointer 之前绑定数组缓冲区:

void VertexArray::addBuffer(Buffer* buffer, GLuint index){
    bind();

    // glBindBuffer(GL_ARRAY_BUFFER, arrayID);    <---- skip
    buffer->bind();                            // <---- bind the array buffer
    glEnableVertexAttribArray(index);
    glVertexAttribPointer(index, buffer->getComCount(), GL_FLOAT, GL_FALSE, 0, 0);

    buffer->unbind();
    unbind();
}


OpenGL 4.6 Specification - 10.3.9 Vertex Arrays in Buffer Objects:

缓冲区对象绑定点被添加到与每个关联的客户端状态 顶点数组索引。指定顶点数组的位置和组织的命令将绑定到ARRAY_BUFFER的缓冲区对象名称复制到 与指定的顶点数组索引对应的绑定点。例如,VertexAttribPointer 命令复制ARRAY_BUFFER_BINDING 的值。

【讨论】:

  • 天哪,先生!它解决了这个问题。先生,我非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 2010-12-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
相关资源
最近更新 更多