在OpenGL应用程序中动态更改着色器

时间:2015-11-30 19:09:26

标签: c++ opengl

我想用着色器更改程序中对象的颜色 - 片段着色器是精确的。

我有两个着色器程序:box,triangle(名称是随机的 - 只是为了便于参考)。对于这两个程序,我使用相同的顶点着色器:

#version 330 core
layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

vec3 pos;

void main()
{
    gl_Position = projection * view * model * vec4(position, 1.0f);
}

然后我正在使用我的box_shader程序:

box_shader.Use();

// Create camera transformation
view = camera.GetViewMatrix();
glm::mat4 projection;
projection = glm::perspective(camera.Zoom, (float)WIDTH/(float)HEIGHT, 0.1f, 100.0f);

// Get the uniform locations
GLint modelLoc = glGetUniformLocation(box_shader.Program, "model");
GLint viewLoc = glGetUniformLocation(box_shader.Program, "view");
GLint projLoc = glGetUniformLocation(box_shader.Program, "projection");
// Pass the matrices to the shader
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

稍后在该计划中,我想使用triangle_shader计划。我在尝试的是:

triangl_shader.Use()
DrawTraingles();

所以我不再打电话给glGetUniformLocation,而是使用之前创建的那些。不幸的是,我没有看到用DrawTraingles()绘制的三角形,但是,当我不切换着色器程序时,它们会出现。

对于我的着色器加载和使用,我使用此类:learnopengl所以关于Use()函数的一切都在那里。

有人可以告诉我应该怎么做才能使用不同的着色器吗?

修改

我发现的是在glGetUniformLocations之后添加packet_shader.Use(),所以现在看起来像这样:

packet_shader.Use();

// Get the uniform locations
modelLoc = glGetUniformLocation(packet_shader.Program, "model");
viewLoc = glGetUniformLocation(packet_shader.Program, "view");
projLoc = glGetUniformLocation(packet_shader.Program, "projection");
// Pass the matrices to the shader
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

虽然,我不确定这是否是表现问题的最佳选择。有人能告诉我它没事吗?

1 个答案:

答案 0 :(得分:1)

制服是GL中的 per-program 状态。所以这里有两个问题:

  1. 每个程序中的统一位置可能完全不同。对于每个程序,您必须查询统一位置,并且必须单独存储它们以供后期使用。
  2. 必须为每个程序单独设置统一值。即使您认为两个程序“共享”相同的制服,情况也并非如此。所有glUniform*()设置程序仅影响当前正在使用的程序 。由于您的每个程序都有自己的modelviewprojection制服,因此每次更改时都必须为每个程序设置这些。目前,看起来你从未为第二个程序设置那些,所以它们的初始默认值为全零。
  3. 如果您想在不同程序之间共享制服,可以考虑查看Uniform Buffer Objects (UBOs)