为两个不同的 VAOS 使用两个不同的着色器

Posted

技术标签:

【中文标题】为两个不同的 VAOS 使用两个不同的着色器【英文标题】:Using two different shaders for two different VAOS 【发布时间】:2018-06-12 15:59:15 【问题描述】:

我有两个单独的 VAO 对象,它们在 while 循环中呈现。每个都需要使用不同的着色器程序进行绘制。我可以让它们单独渲染,但只有天空盒一起渲染。

do
    // Clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Access the active camera
    glm::mat4 ViewMatrix;
    if(worldCamMode)
    
        worldCam->update();
        ViewMatrix = worldCamParent->getViewMtx();
    
    else
    
        playerCam->update();
        ViewMatrix = playerCamParent->getViewMtx();
    

    // Retrieve the projection and model matrices
    glm::mat4 ProjectionMatrix = getProjectionMatrix();
    glm::mat4 ModelMatrix = glm::mat4(1.0f);
    glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
    glm::mat4 MVPX = ProjectionMatrix * ViewMatrix;

    // Render the skybox first
    glm::mat4 view = glm::mat4(glm::mat3(ViewMatrix));
    cloudySkybox->render(cubemapTexture, view, ProjectionMatrix, skyboxProgramID);

    int viewHandle = glGetUniformLocation(lampID, "view");
    if (viewHandle == -1) 
        std::cout << "Uniform: view is not an active uniform label\n";
    
    glUniformMatrix4fv( viewHandle, 1, false, &MVPX[0][0]);
    glUseProgram(lampID);
    testObj.render(lampID);

    // Swap buffers
    glfwSwapBuffers(window);
    glfwPollEvents();

 // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
       glfwWindowShouldClose(window) == 0 );

要渲染的第一个对象是 cloudySkybox。这是唯一会渲染并且 testObj 不会渲染的东西,除非我注释掉 cloudySkybox 行。我已经缩小范围,看看是什么破坏了 testObj。 testObj 渲染得很好,直到我使用 glUseProgram(shaderID);然后它停止渲染。有谁知道为什么会这样? testObj.render()函数与glUseProgram(differentShader)格式一致

void skybox::render(unsigned int cubemapTexture, glm::mat4 view, glm::mat4 projection, int shaderID)

    glUseProgram(shaderID);
    //glDepthMask(GL_FALSE);

    //int viewUniformHandle = glGetUniformLocation(shaderID, "view");
    //if (viewUniformHandle == -1)
    //  exit(1);
    //glUniformMatrix4fv( viewUniformHandle, 1, false, glm::value_ptr(view) );

    //int projectionUniformHandle = glGetUniformLocation(shaderID, "projection");
    //if (projectionUniformHandle == -1)
    //  exit(1);
    //glUniformMatrix4fv( projectionUniformHandle, 1, false, glm::value_ptr(projection) );

    //glBindVertexArray(skyboxVAO);
    //glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
    //glDrawArrays(GL_TRIANGLES, 0, 36);
    //glDepthMask(GL_TRUE);

    //glBindVertexArray(0);
    //glFlush();




void Model::render(int programID)

    glUseProgram(programID);

    int modelUniformHandle = glGetUniformLocation(programID, "model");
    if (modelUniformHandle == -1)
        exit(1);

    glm::mat4 model;

    for (int i = 0; i < VAOs.size(); i++) 

        glUseProgram(programID);
        glBindVertexArray(VAOs[i]);
        model = glm::mat4(1.0f);

        glBindTexture(GL_TEXTURE_2D, TexID[this->shape[i].mesh.material_ids[i]]);
        glUniformMatrix4fv(modelUniformHandle, 1, false, glm::value_ptr(model));
        glDrawElements(GL_TRIANGLES, this->shape[i].mesh.indices.size(), GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
        glFlush();
    

【问题讨论】:

【参考方案1】:

glUniform 对通过调用glUseProgram 成为当前状态一部分的程序对象进行操作。在调用glUniformMatrix4fv之前设置程序glUseProgram(lampID)

【讨论】:

天哪,非常感谢。两个切换语句可以改变的东西真是太神奇了

以上是关于为两个不同的 VAOS 使用两个不同的着色器的主要内容,如果未能解决你的问题,请参考以下文章

为啥 glGetAttribLocation 为两个不同的属性返回相同的值?

如何在渲染之间更改片段着色器颜色?

如何在 Metal 中组合使用不同着色器的渲染命令编码器

跨不同着色器使用多个 image2d 的问题

我可以为同一个渲染作业使用不同的着色器程序吗?

具有独特着色器的 OpenGL 多次绘制调用会产生空白屏幕