当我尝试从 vbo 获取颜色时,glDrawElements 没有输出

Posted

技术标签:

【中文标题】当我尝试从 vbo 获取颜色时,glDrawElements 没有输出【英文标题】:No output from glDrawElements when I try to take color from vbo 【发布时间】:2020-11-06 09:47:51 【问题描述】:

我是 OpenGL 的新手,并试图将我当前的代码扩展为使用作为统一变量提供的颜色来显示正方形的代码,该代码将根据 vbo 中给出的颜色显示正方形。

int main(int argc, char **argv)

    //! The pointer to the GLFW window
    GLFWwindow *window;

    //! Initialize GLFW
    if (!glfwInit())
        return -1;

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    window = glfwCreateWindow(512, 512, "Testing COde", NULL, NULL);
    if (!window)
    
        glfwTerminate();
        return -1;
    

    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err)
    
        std::cerr << "GLEW Init Failed : %s" << std::endl;
    

    std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
    std::cout << "Version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // Format (x,y,r,g,b,a)
    float position[] = 
        -0.5f ,  0.5f,  1.0f ,  0.0f,  1.0f, 1.0f,
        -0.5f , -0.5f,  0.0f ,  1.0f,  1.0f, 1.0f,
         0.5f , -0.5f,  1.0f ,  1.0f,  0.0f, 1.0f,
         0.5f ,  0.5f,  1.0f ,  1.0f,  1.0f, 1.0f
    ;     

    uint indeces[] = 
        0, 1, 2,
        0, 2, 3
    ;

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 4 * 6 * sizeof(float), position, GL_STATIC_DRAW);
    
    GLuint ibo;
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * 2 * sizeof(uint), indeces, GL_STATIC_DRAW);

    struct shaderbundle* str_shader = parseShader("res/shaders/vertexshader.glsl","res/shaders/fragmentshader.glsl");

    uint shader = CreateShader(str_shader->vertex, str_shader->fragment);
    glUseProgram(shader);

    uint vPosition = glGetAttribLocation( shader, "position" );
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (GLvoid*)(0));

    uint inColor = glGetAttribLocation( shader, "in_color" );
    if (inColor != -1) 
        glEnableVertexAttribArray(inColor);
        glVertexAttribPointer(inColor  , 4, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (GLvoid*)(2*sizeof(float)));
    
    else 
        "no color recieved";
    

    uint u_color = glGetUniformLocation( shader, "u_color" );
    if (u_color != -1) 
        glUniform4f(u_color,1.0f, 0.4f, 0.6f ,1.0f);
    
    else 
        "no color recieved";
    
    
    while (glfwWindowShouldClose(window) == 0)
    
        glClear(GL_COLOR_BUFFER_BIT);

        // glDrawArrays(GL_TRIANGLES, 0, 3 * 2);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

        // Swap front and back buffers
        glfwSwapBuffers(window);

        // Poll for and process events
        glfwPollEvents();
    

    glDeleteProgram(shader);

    glfwTerminate();
    return 0;

为此,我使用以下片段着色器:

#version 330 core
out vec4 color;
uniform vec4 u_color;
in  vec4 in_color;
void main() 
    // color = in_color;
    color = u_color;
;

但是当我使用 in_color 而不是 u_color 时,屏幕上什么也没有显示。位置数组的内容采用格式(x-位置、y-位置、r-color、g-colo、b-color、alpha)。所以在 glGetVertexAttribPointer 中,我使用 stride 作为6*sizeof(float),偏移量是0 用于位置,2*float 用于颜色。我尝试使用glGetError() 进行调试,但它没有返回任何内容。请帮我找出我到底做错了什么。

【问题讨论】:

【参考方案1】:

您不能直接设置片段着色器输入。 in_color 需要是顶点着色器输入(属性)。将顶点着色器输入传递给片段着色器。例如:

顶点着色器

#version 330 core

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 in_color;

out vec4 vert_color;

void main()

    vert_color  = in_color;
    gl_Position = position;

片段着色器

#version 330 core

out vec4 color;
in vec4 vert_color;

void main() 

    color = vert_color;

【讨论】:

@MandarSadye 不管怎样,这是相关的:Is it possible to declare a shader variable as both input and output? 抱歉问了太多问题。感谢您的帮助。

以上是关于当我尝试从 vbo 获取颜色时,glDrawElements 没有输出的主要内容,如果未能解决你的问题,请参考以下文章

为啥 glBufferSubData 需要等到 glDrawElements 不使用 VBO?

OpenGL- glDrawElements 只绘制第一个元素

GLES2.0 上的 VBO glDrawElements 和 glVertexAttribPointer 不显示任何内容

opengl vbo 纹理

glDrawElements 不绘制任何东西

使用 glDrawElements (iOS) 重用相同的缓冲区