Commit 27762850 authored by Ken Martin's avatar Ken Martin

Keep track of what shader uniforms were being used in the shader

Since a single mapper can use multiple shader programs it makes sense to
keep track of uniforms used in the shader program itself as opposed to
the mapper.
parent 67c0a8a8
......@@ -2508,8 +2508,6 @@ void vtkSurfaceLICMapper::ReplaceShaderValues(
// " gl_FragData[2] = vec4(19.0, 19.0, tcoordVC.x, gl_FragCoord.z);\n"
, false);
this->ShaderVariablesUsed.push_back("normalMatrix");
shaders[vtkShader::Vertex]->SetSource(VSSource);
shaders[vtkShader::Fragment]->SetSource(FSSource);
......
......@@ -307,7 +307,6 @@ void vtkOpenGLGlyph3DHelper::ReplaceShaderNormal(
}
vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Impl",
"normalVCVSOutput = normalMatrix * glyphNormalMatrix * normalMC;");
this->ShaderVariablesUsed.push_back("normalMatrix");
}
shaders[vtkShader::Vertex]->SetSource(VSSource);
......
......@@ -198,12 +198,6 @@ void vtkOpenGLPolyDataMapper::ReleaseGraphicsResources(vtkWindow* win)
this->Modified();
}
bool vtkOpenGLPolyDataMapper::IsShaderVariableUsed(const char *name)
{
return std::binary_search(this->ShaderVariablesUsed.begin(),
this->ShaderVariablesUsed.end(), name);
}
void vtkOpenGLPolyDataMapper::AddShaderReplacement(
vtkShader::Type shaderType, // vertex, fragment, etc
std::string originalValue,
......@@ -247,7 +241,6 @@ void vtkOpenGLPolyDataMapper::BuildShaders(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *ren, vtkActor *actor)
{
this->ShaderVariablesUsed.clear();
this->GetShaderTemplate(shaders, ren, actor);
typedef std::map<const vtkOpenGLPolyDataMapper::ReplacementSpec,
......@@ -284,8 +277,6 @@ void vtkOpenGLPolyDataMapper::BuildShaders(
shaders[i->first.ShaderType]->SetSource(ssrc);
}
}
std::sort(this->ShaderVariablesUsed.begin(),this->ShaderVariablesUsed.end());
}
bool vtkOpenGLPolyDataMapper::HaveWideLines(
......@@ -1033,14 +1024,11 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderNormal(
if (this->VBO->NormalOffset)
{
if (vtkShaderProgram::Substitute(VSSource,
vtkShaderProgram::Substitute(VSSource,
"//VTK::Normal::Dec",
"attribute vec3 normalMC;\n"
"uniform mat3 normalMatrix;\n"
"varying vec3 normalVCVSOutput;"))
{
this->ShaderVariablesUsed.push_back("normalMatrix");
}
"varying vec3 normalVCVSOutput;");
vtkShaderProgram::Substitute(VSSource,
"//VTK::Normal::Impl",
"normalVCVSOutput = normalMatrix * normalMC;");
......@@ -1067,13 +1055,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderNormal(
{
if (this->HaveCellNormals)
{
if (vtkShaderProgram::Substitute(FSSource,
"//VTK::Normal::Dec",
"uniform mat3 normalMatrix;\n"
"uniform samplerBuffer textureN;\n"))
{
this->ShaderVariablesUsed.push_back("normalMatrix");
}
vtkShaderProgram::Substitute(FSSource,
"//VTK::Normal::Dec",
"uniform mat3 normalMatrix;\n"
"uniform samplerBuffer textureN;\n");
vtkShaderProgram::Substitute(FSSource,
"//VTK::Normal::Impl",
"vec3 normalVCVSOutput = normalize(normalMatrix *\n"
......@@ -1119,7 +1104,6 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderNormal(
vtkShaderProgram::Substitute(FSSource,
"//VTK::Normal::Dec",
"uniform int cameraParallel;");
this->ShaderVariablesUsed.push_back("cameraParallel");
vtkShaderProgram::Substitute(FSSource,"//VTK::Normal::Impl",
"vec3 fdx = normalize(vec3(dFdx(vertexVC.x),dFdx(vertexVC.y),dFdx(vertexVC.z)));\n"
......@@ -1158,13 +1142,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderPositionVC(
"//VTK::PositionVC::Impl",
"vertexVCVSOutput = MCVCMatrix * vertexMC;\n"
" gl_Position = MCDCMatrix * vertexMC;\n");
if (vtkShaderProgram::Substitute(VSSource,
"//VTK::Camera::Dec",
"uniform mat4 MCDCMatrix;\n"
"uniform mat4 MCVCMatrix;"))
{
this->ShaderVariablesUsed.push_back("MCVCMatrix");
}
vtkShaderProgram::Substitute(VSSource,
"//VTK::Camera::Dec",
"uniform mat4 MCDCMatrix;\n"
"uniform mat4 MCVCMatrix;");
vtkShaderProgram::Substitute(GSSource,
"//VTK::PositionVC::Dec",
"in vec4 vertexVCVSOutput[];\n"
......@@ -1750,12 +1731,12 @@ void vtkOpenGLPolyDataMapper::SetCameraShaderParameters(vtkOpenGLHelper &cellBO,
((vtkOpenGLActor *)actor)->GetKeyMatrices(mcwc,anorms);
vtkMatrix4x4::Multiply4x4(mcwc, wcdc, this->TempMatrix4);
program->SetUniformMatrix("MCDCMatrix", this->TempMatrix4);
if (this->IsShaderVariableUsed("MCVCMatrix"))
if (program->IsUniformUsed("MCVCMatrix"))
{
vtkMatrix4x4::Multiply4x4(mcwc, wcvc, this->TempMatrix4);
program->SetUniformMatrix("MCVCMatrix", this->TempMatrix4);
}
if (this->IsShaderVariableUsed("normalMatrix"))
if (program->IsUniformUsed("normalMatrix"))
{
vtkMatrix3x3::Multiply3x3(anorms, norms, this->TempMatrix3);
program->SetUniformMatrix("normalMatrix", this->TempMatrix3);
......@@ -1764,17 +1745,17 @@ void vtkOpenGLPolyDataMapper::SetCameraShaderParameters(vtkOpenGLHelper &cellBO,
else
{
program->SetUniformMatrix("MCDCMatrix", wcdc);
if (this->IsShaderVariableUsed("MCVCMatrix"))
if (program->IsUniformUsed("MCVCMatrix"))
{
program->SetUniformMatrix("MCVCMatrix", wcvc);
}
if (this->IsShaderVariableUsed("normalMatrix"))
if (program->IsUniformUsed("normalMatrix"))
{
program->SetUniformMatrix("normalMatrix", norms);
}
}
if (this->IsShaderVariableUsed("cameraParallel"))
if (program->IsUniformUsed("cameraParallel"))
{
program->SetUniformi("cameraParallel", cam->GetParallelProjection());
}
......
......@@ -295,19 +295,6 @@ protected:
vtkMatrix4x4 *TempMatrix4;
vtkMatrix3x3 *TempMatrix3;
// this vector can be used while building
// the shader program to record specific variables
// that are being used by the program. This is
// useful later on when setting uniforms. At
// that point IsShaderVariableUsed can be called
// to see if the uniform should be set or not.
std::vector<std::string> ShaderVariablesUsed;
// used to see if the shader building code indicated that
// a specific variable is being used. Only some variables
// are currently populated.
bool IsShaderVariableUsed(const char *);
// if set to true, tcoords will be passed to the
// VBO even if the mapper knows of no texture maps
// normally tcoords are only added to the VBO if the
......
......@@ -285,6 +285,9 @@ bool vtkShaderProgram::Link()
return false;
}
// clear out the list of uniforms used
this->UniformsUsed.clear();
#if GL_ES_VERSION_2_0 != 1
// bind the outputs if specified
if (this->NumberOfOutputs)
......@@ -781,6 +784,36 @@ inline int vtkShaderProgram::FindUniform(const char *name)
return location;
}
bool vtkShaderProgram::IsUniformUsed(const char *name)
{
if (name == NULL)
{
return false;
}
// see if we have cached the result
typedef std::map<std::string, bool>::iterator iter;
iter found = this->UniformsUsed.find(name);
// if not, go query openGL
if (found == this->UniformsUsed.end())
{
if (!this->Linked)
{
vtkErrorMacro("attempt to find uniform when the shader program is not linked");
return false;
}
GLint location =
static_cast<int>(glGetUniformLocation(static_cast<GLuint>(Handle),
(const GLchar *)name));
this->UniformsUsed[name] = (location == -1 ? false : true);
return (location == -1 ? false : true);
}
return found->second;
}
// ----------------------------------------------------------------------------
void vtkShaderProgram::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -191,7 +191,11 @@ public:
const std::string replace,
bool all = true);
// Description:
// methods to inquire as to what uniforms/attributes are used by
// this shader. This can save some compute time if the uniforms
// or attributes are expensive to compute
bool IsUniformUsed(const char *);
protected:
vtkShaderProgram();
......@@ -271,6 +275,9 @@ protected:
std::map<std::string, int> Attributes;
std::map<std::string, bool> UniformsUsed;
friend class VertexArrayObject;
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment