C++ 如何使用多个着色器程序?

C++ 如何使用多个着色器程序?,c++,opengl,rendering,glew,freeglut,C++,Opengl,Rendering,Glew,Freeglut,使用一个着色器程序,我的代码如下所示: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); InitFunctions(); glUseProgram(ShaderProgram); //render objects glutSwapBuffers(); 但我想添加另一个着色器程序,但它似乎清除了屏幕。即使在渲染对象后放置此选项也会清除屏幕: glUseProgram(ShaderProgramNew); 当我在glUseProgram

使用一个着色器程序,我的代码如下所示:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
InitFunctions();
glUseProgram(ShaderProgram);

//render objects

glutSwapBuffers();
但我想添加另一个着色器程序,但它似乎清除了屏幕。即使在渲染对象后放置此选项也会清除屏幕:

glUseProgram(ShaderProgramNew);
当我在glUseProgram()的两次使用中使用相同的着色器时,屏幕上唯一一次没有清除屏幕

要加载着色器,我使用以下函数:

GLuint ShaderProgramManager::loadProgram(char* VertexShaderFileLocation, char*     FragmentShaderFileLocation){

cout << "Creating Shader...\n";
cout << "Initalizing Variables\n";
GLuint ShaderProgram = glCreateProgram();
GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

string VString = loadShader(VertexShaderFileLocation);
string FString = loadShader(FragmentShaderFileLocation);

const GLchar* VText = (const GLchar*)VString.c_str();
const GLchar* FText = (const GLchar*)FString.c_str();

cout << "Load VertexShader and FragmentShader\n";

const GLchar* pp[1];
pp[0] = FText;
GLint Lengthss[1];
Lengthss[0] = strlen(FText);
glShaderSource(FragmentShader, 1, (const GLchar**)&pp, Lengthss);
glCompileShader(FragmentShader);

const GLchar* p[1];
p[0] = VText;
GLint Lengths[1];
Lengths[0] = strlen(VText);
glShaderSource(VertexShader, 1, (const GLchar**)&p, Lengths);
glCompileShader(VertexShader);

GLint success;
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(FragmentShader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_FRAGMENT_SHADER, InfoLog);
}


glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(VertexShader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
}

cout << "Shaders Compiled.\n";



cout << "Attach Shaders\n";
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);

cout << "Link Program\n";
glLinkProgram(ShaderProgram);

cout << "Validate Program\n";
glValidateProgram(ShaderProgram);
cout << "Complete.\n";
return ShaderProgram;

当我想在一次渲染过程中使用两个不同的着色器时,此解决方案非常适合我

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram01);

// Do Modelview and projection matrix stuff and uniforms

// Render objects with fstshaderProgram

glUseProgram(shaderProgram02);
// Do Modelview and projection matrix stuff and uniforms

// Render objects with 2nd shaderProgram

glutSwapBuffers();
非常重要的是你必须重新穿上所有需要的制服。对于这种方法,我假设您正确加载着色器,并且它们工作正常。
使用glut,每次迭代只调用一个glutSwapBuffers()

如果不查看着色器程序,则无法回答此问题。着色器的创建。制服和属性是如何配置的等等。我不介意人们投反对票,但我希望有一个原因可以解决这个问题。我没有投反对票,但在你的编辑中,你上传了很多编译程序的通用代码,这可能很好,因为你的一个着色器工作。但没有关于ShaderProgram中的内容的详细信息—新内容和设置。我打赌ShaderProgramNew是无效的或使用不当。我不认为ShaderProgramNew是无效的,因为如果我把它放在两个glUseProgram()中,它都会按预期工作。无论你的着色器是好是坏,我想不出一种可能的情况,在这种情况下只要调用
glUseProgram()
使用任何类型的着色器都会清除以前的渲染。这里肯定还有别的事,你是对的!在调用
glUseProgram()
之后,我在渲染函数开始时上传了我所有的制服,而不是只上传该着色器程序的制服,所以它现在可以工作了?是的。虽然这可能会解决OP的问题,但解释确实不正确。您不必每次调用
glUseProgram()
后都重新上传制服。唯一重要的是,在正确的程序绑定时设置制服。之后,他们坚持这个计划。引用规范:“制服是程序对象特定的状态。一旦加载,制服将保留其值,只要程序对象未重新链接,只要使用程序对象,制服的值就会恢复。”
ShaderProgramManager spm;

    ShaderProgram = spm.loadProgram("data/Shaders/VertexShader.txt", "data/Shaders/FragmentShader.txt");

        gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld");
        rotmLocation = glGetUniformLocation(ShaderProgram, "rotm");
        PermLocation = glGetUniformLocation(ShaderProgram, "persm");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram01);

// Do Modelview and projection matrix stuff and uniforms

// Render objects with fstshaderProgram

glUseProgram(shaderProgram02);
// Do Modelview and projection matrix stuff and uniforms

// Render objects with 2nd shaderProgram

glutSwapBuffers();