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

C++ 如何在渲染之间更改片段着色器颜色?,c++,opengl,C++,Opengl,我正在努力编写这个简单的船场景。这是一个家庭作业问题,但我真的被难倒了。我上传了两个模型。一个是一个立方体,它有一个片段着色器,可以将自身着色为蓝色。第二种是船,它有一个碎片着色器,可以将自身着色为白色。当我使用两个不同的着色器时,船模型是不可见的。经过许多努力和探索 我被难住了,所以我正在尝试计划B,即找到一种在渲染两个对象之间更改片段着色器颜色的方法,但我不知道如何做到这一点 void render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH

我正在努力编写这个简单的船场景。这是一个家庭作业问题,但我真的被难倒了。我上传了两个模型。一个是一个立方体,它有一个片段着色器,可以将自身着色为蓝色。第二种是船,它有一个碎片着色器,可以将自身着色为白色。当我使用两个不同的着色器时,船模型是不可见的。经过许多努力和探索

我被难住了,所以我正在尝试计划B,即找到一种在渲染两个对象之间更改片段着色器颜色的方法,但我不知道如何做到这一点

void render() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //BOAT START
    //Rocks the ship, simulating ocean rocking
    if(shiprocker < 5000){
        shiprocker++;
        theta += 0.00002f;
    }
    if(shiprocker ==15000){
        shiprocker = -5000;
    }
    if(shiprocker > 4999){
        shiprocker++;
        theta -= 0.00002f;
    }
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  

    boat_model->mR = glm::rotate(            
        glm::mat4( 1.0f ),
        glm::degrees( theta ),
        glm::vec3(0.0f, 0.0f, 1.0f)
        );

    glm::mat4 mtx_trans = glm::translate(
        glm::mat4(1.0f),
        glm::vec3( 0.0f, 0.0f, -15.0f )
        );

    boat_model->mM =  mtx_trans * boat_model->mR;        
    boat_model->render();
    //BOAT END


    //OCEAN CUBE START
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  

    glm::mat4 mtx_trans_cube = glm::translate(
        glm::mat4( 1.0f ),
        glm::vec3( -20.0f, -50.0f, -50.0f ) 
        );

    plane_model->mM = glm::scale(  
        mtx_trans_cube,              
        glm::vec3( 10.0f, 10.0f, 10.0f )
        );

    //gl_FragColor = (0.0f, 0.0f, 1.0f , 1.0f); wont compile
    //glColor3f(0.0f, 0.0f, 1.0f); changes nothing

    camera->set_uniform_view_perspective( plane_model->shader->program_ID );
    plane_model->render();
    //OCEAN CUBE END


    glutSwapBuffers();
}



int main (int argc, char** argv) {

    // Initialize GLUT
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_MULTISAMPLE | GLUT_RGB);


    //WINDOW SETTINGS
    glutInitWindowSize(1000, 1000);
    glutCreateWindow("SailBoat");

    //PASSIVE FUNCS
    glutReshapeFunc(change_viewport);
    glutDisplayFunc(render);
    glutIdleFunc( animate );

    //ERROR CHECK
    if (GLEW_OK != glewInit()) {
        exit(1);
    }

    //Clear color used for sky tones.
    glClearColor(0.529f, 0.807f, .98f, 1.0f);
    glEnable (GL_DEPTH_TEST);
    glEnable (GL_MULTISAMPLE);

    Shader* boatShader = new Shader( VERTEX_SHADER, BOAT_FRAGMENT_SHADER );
    Shader* cubeShader = new Shader( VERTEX_SHADER, CUBE_FRAGMENT_SHADER );

    //BOAT
    boat_model = new Model(boatShader); 
    load_model(boat_model ,MODEL_BOAT_FILENAME);
    boat_model->upload_2_server();


    //OCEAN CUBE
    plane_model = new Model( boatShader );
    load_model(plane_model ,MODEL_PLANE_FILENAME);
    plane_model->upload_2_server();

    // Set up the camera 
    theta = 0.0f;
    shiprocker = 0;
    camera = new FPSCamera(60.0f, 1.0f, 1.0f, 10000.0f, true);
    glutMainLoop();

    return 0;
}

}

可以在GLSL中使用统一变量在渲染调用之间传递值。设置片段着色器,如下所示:

#version 150

in vec4 color;
out vec4 fColor;
uniform vec3 boatColor;

void main () {
    fColor = vec4(boatColor, 0.5);
}
<>和在C++代码中:

glUseProgram(program); // Where program is your shader program
GLint uniform = glGetUniformLocation(program, "boatColor"); // since boatColor is what we called the uniform variable in our fragment shader
glUniform3f(uniform, 1.0f, 0.0f, 0.0f); // Set the boatColor variable to be a solid red
// Render your first boat
glUniform3f(uniform, 0.0f, 0.0f, 1.0f); // Set the second boat to be a solid blue
// Render your second boat
glUseProgram(0);

这应该很有效。如果这里有其他人有更好的方法,请告诉我;我对GLSL比较陌生。

你试过使用GLSL统一变量吗?在你的
模型中。渲染
函数中,你是调用
着色器->使用
还是类似的方法?这看起来是一个非常好的方法,Chemo先生。如果你有很多相对较小的对象,并且关心最好的性能,你也可以考虑使用属性而不是制服。它稍微复杂一些,因为它们首先转到顶点着色器,然后需要传递到片段着色器。但根据平台和驾驶员的效率,更新制服的成本可能会适中,而更新属性的效率可能会更高。不过,您可能希望对其进行基准测试。谢谢您的帮助。我现在一切正常。我在C++代码和着色器之间通信困难,但你帮了我很多忙!我很乐意帮忙!那样的话,请接受我的回答。:)
glUseProgram(program); // Where program is your shader program
GLint uniform = glGetUniformLocation(program, "boatColor"); // since boatColor is what we called the uniform variable in our fragment shader
glUniform3f(uniform, 1.0f, 0.0f, 0.0f); // Set the boatColor variable to be a solid red
// Render your first boat
glUniform3f(uniform, 0.0f, 0.0f, 1.0f); // Set the second boat to be a solid blue
// Render your second boat
glUseProgram(0);