Commit 1c573012 authored by Ken Martin's avatar Ken Martin

Add basic support for shadows

First cut at adding shadows back into VTK. It does
not use spot intensity maps and currently you have to
build the render passes yourself. But I will soon add
a Renderer method to turn shadows on that handles all
the details for you.
parent f7e845a7
......@@ -62,6 +62,8 @@ set(Module_SRCS
vtkSequencePass.cxx
vtkShader.cxx
vtkShaderProgram.cxx
vtkShadowMapBakerPass.cxx
vtkShadowMapPass.cxx
vtkSobelGradientMagnitudePass.cxx
vtkTextureObject.cxx
vtkTextureUnitManager.cxx
......
......@@ -5,6 +5,8 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestVBOPointsLines.cxx
TestGaussianBlurPass.cxx
TestBlurAndSobelPasses.cxx
TestShadowMapBakerPass.cxx
TestShadowMapPass.cxx
TestSobelGradientMagnitudePass.cxx
)
......
/*=========================================================================
Program: Visualization Toolkit
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// test baking shadow maps
//
// The command line arguments are:
// -I => run in interactive mode; unless this is used, the program will
// not allow interaction and exit
#include "vtkCamera.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkPointData.h"
#include "vtkPolyDataMapper.h"
#include "vtkPLYReader.h"
#include "vtkNew.h"
#include "vtkProperty.h"
#include "vtkLightKit.h"
#include "vtkPolyDataNormals.h"
#include "vtkTimerLog.h"
#include "vtkOpenGLRenderer.h"
#include "vtkPlaneSource.h"
#include "vtkOpenGLTexture.h"
#include "vtkCameraPass.h"
#include "vtkLightsPass.h"
#include "vtkSequencePass.h"
#include "vtkOpaquePass.h"
#include "vtkRenderPassCollection.h"
#include "vtkShadowMapBakerPass.h"
#include "vtkShadowMapPassInternal.h"
#include "vtkRenderStepsPass.h"
#include "vtkRegressionTestImage.h"
#include "vtkTestUtilities.h"
#include "vtkRenderWindowInteractor.h"
//----------------------------------------------------------------------------
int TestShadowMapBakerPass(int argc, char *argv[])
{
vtkNew<vtkActor> actor;
vtkNew<vtkRenderer> renderer;
vtkNew<vtkPolyDataMapper> mapper;
renderer->SetBackground(0.3, 0.4, 0.6);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(600, 600);
renderWindow->AddRenderer(renderer.Get());
renderer->AddActor(actor.Get());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renderWindow.Get());
vtkNew<vtkLightKit> lightKit;
lightKit->AddLightsToRenderer(renderer.Get());
const char* fileName =
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/dragon.ply");
vtkNew<vtkPLYReader> reader;
reader->SetFileName(fileName);
reader->Update();
// vtkNew<vtkPolyDataNormals> norms;
// norms->SetInputConnection(reader->GetOutputPort());
// norms->Update();
mapper->SetInputConnection(reader->GetOutputPort());
//mapper->SetInputConnection(norms->GetOutputPort());
actor->SetMapper(mapper.Get());
actor->GetProperty()->SetAmbientColor(0.2, 0.2, 1.0);
actor->GetProperty()->SetDiffuseColor(1.0, 0.65, 0.7);
actor->GetProperty()->SetSpecularColor(1.0, 1.0, 1.0);
actor->GetProperty()->SetSpecular(0.5);
actor->GetProperty()->SetDiffuse(0.7);
actor->GetProperty()->SetAmbient(0.5);
actor->GetProperty()->SetSpecularPower(20.0);
actor->GetProperty()->SetOpacity(1.0);
//actor->GetProperty()->SetRepresentationToWireframe();
renderWindow->SetMultiSamples(0);
// create the basic VTK render steps
vtkNew<vtkRenderStepsPass> basicPasses;
vtkNew<vtkOpaquePass> opaque;
vtkNew<vtkLightsPass> lights;
vtkNew<vtkSequencePass> opaqueSequence;
vtkNew<vtkRenderPassCollection> passes2;
passes2->AddItem(lights.Get());
passes2->AddItem(opaque.Get());
opaqueSequence->SetPasses(passes2.Get());
vtkNew<vtkCameraPass> opaqueCameraPass;
opaqueCameraPass->SetDelegatePass(opaqueSequence.Get());
vtkNew<vtkShadowMapBakerPass> bakerPass;
// bakerPass->SetOpaquePass(basicPasses->GetOpaquePass());
bakerPass->SetOpaquePass(opaqueCameraPass.Get());
bakerPass->SetResolution(1024);
// To cancel self-shadowing.
bakerPass->SetPolygonOffsetFactor(3.1f);
bakerPass->SetPolygonOffsetUnits(10.0f);
basicPasses->SetOpaquePass(bakerPass.Get());
// tell the renderer to use our render pass pipeline
vtkOpenGLRenderer *glrenderer =
vtkOpenGLRenderer::SafeDownCast(renderer.GetPointer());
glrenderer->SetPass(basicPasses.Get());
vtkNew<vtkTimerLog> timer;
timer->StartTimer();
renderWindow->Render();
timer->StopTimer();
double firstRender = timer->GetElapsedTime();
cerr << "baking time: " << firstRender << endl;
// get a shadow map
vtkTextureObject *to = bakerPass->GetShadowMaps()->Vector[2];
// by default the textures have depth comparison on
// but for simple display we need to turn it off
to->SetDepthTextureCompare(false);
// now render this texture so we can see the depth map
vtkNew<vtkActor> actor2;
vtkNew<vtkPolyDataMapper> mapper2;
vtkNew<vtkOpenGLTexture> texture;
texture->SetTextureObject(to);
actor2->SetTexture(texture.Get());
actor2->SetMapper(mapper2.Get());
vtkNew<vtkPlaneSource> plane;
mapper2->SetInputConnection(plane->GetOutputPort());
renderer->RemoveActor(actor.Get());
renderer->AddActor(actor2.Get());
glrenderer->SetPass(NULL);
renderer->GetActiveCamera()->SetPosition(0,0,1);
renderer->GetActiveCamera()->SetFocalPoint(0,0,0);
renderer->GetActiveCamera()->SetViewUp(0,1,0);
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(2.0);
renderWindow->Render();
int retVal = vtkRegressionTestImage( renderWindow.Get() );
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
bakerPass->ReleaseGraphicsResources(renderWindow.Get());
return EXIT_SUCCESS;
}
/*=========================================================================
Program: Visualization Toolkit
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// test baking shadow maps
//
// The command line arguments are:
// -I => run in interactive mode; unless this is used, the program will
// not allow interaction and exit
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCameraPass.h"
#include "vtkCellArray.h"
#include "vtkLight.h"
#include "vtkLightsPass.h"
#include "vtkNew.h"
#include "vtkOpaquePass.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLTexture.h"
#include "vtkPLYReader.h"
#include "vtkPlaneSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderPassCollection.h"
#include "vtkRenderStepsPass.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkSequencePass.h"
#include "vtkShadowMapBakerPass.h"
#include "vtkShadowMapPass.h"
#include "vtkShadowMapPassInternal.h"
#include "vtkTestUtilities.h"
#include "vtkTimerLog.h"
//----------------------------------------------------------------------------
int TestShadowMapPass(int argc, char *argv[])
{
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(0.3, 0.4, 0.6);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(600, 600);
renderWindow->AddRenderer(renderer.Get());
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renderWindow.Get());
vtkNew<vtkLight> light1;
light1->SetFocalPoint(0,0,0);
light1->SetPosition(0,1,0.2);
light1->SetColor(0.95,0.97,1.0);
light1->SetIntensity(0.8);
renderer->AddLight(light1.Get());
vtkNew<vtkLight> light2;
light2->SetFocalPoint(0,0,0);
light2->SetPosition(1.0,1.0,1.0);
light2->SetColor(1.0,0.8,0.7);
light2->SetIntensity(0.3);
renderer->AddLight(light2.Get());
const char* fileName =
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/dragon.ply");
vtkNew<vtkPLYReader> reader;
reader->SetFileName(fileName);
reader->Update();
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.Get());
actor->GetProperty()->SetAmbientColor(0.135, 0.2225, 0.3);
actor->GetProperty()->SetDiffuseColor(0.54, 0.89, 0.63);
actor->GetProperty()->SetSpecularColor(1.0, 1.0, 1.0);
actor->GetProperty()->SetSpecular(0.51);
actor->GetProperty()->SetDiffuse(0.7);
actor->GetProperty()->SetAmbient(0.7);
actor->GetProperty()->SetSpecularPower(30.0);
actor->GetProperty()->SetOpacity(1.0);
renderer->AddActor(actor.Get());
//actor->GetProperty()->SetRepresentationToWireframe();
// add a plane
vtkNew<vtkPlaneSource> plane;
double *plybounds = mapper->GetBounds();
plane->SetOrigin(-0.2, plybounds[2], -0.2);
plane->SetPoint1( 0.2, plybounds[2], -0.2);
plane->SetPoint2(-0.2, plybounds[2], 0.2);
vtkNew<vtkPolyDataMapper> planeMapper;
planeMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> planeActor;
planeActor->SetMapper(planeMapper.Get());
renderer->AddActor(planeActor.Get());
renderWindow->SetMultiSamples(0);
vtkNew<vtkOpaquePass> opaque;
vtkNew<vtkLightsPass> lights;
vtkNew<vtkSequencePass> opaqueSequence;
vtkNew<vtkRenderPassCollection> passes2;
passes2->AddItem(lights.Get());
passes2->AddItem(opaque.Get());
opaqueSequence->SetPasses(passes2.Get());
vtkNew<vtkCameraPass> opaqueCameraPass;
opaqueCameraPass->SetDelegatePass(opaqueSequence.Get());
vtkNew<vtkShadowMapBakerPass> bakerPass;
// bakerPass->SetOpaquePass(basicPasses->GetOpaquePass());
bakerPass->SetOpaquePass(opaqueCameraPass.Get());
bakerPass->SetResolution(1024);
// To cancel self-shadowing.
bakerPass->SetPolygonOffsetFactor(3.1f);
bakerPass->SetPolygonOffsetUnits(10.0f);
// tell the renderer to use our render pass pipeline
vtkOpenGLRenderer *glrenderer =
vtkOpenGLRenderer::SafeDownCast(renderer.GetPointer());
vtkNew<vtkShadowMapPass> shadows;
shadows->SetShadowMapBakerPass(bakerPass.Get());
shadows->SetOpaquePass(opaqueSequence.Get());
vtkNew<vtkSequencePass> seq;
vtkNew<vtkRenderPassCollection> passes;
passes->AddItem(bakerPass.Get());
passes->AddItem(shadows.Get());
passes->AddItem(lights.Get());
seq->SetPasses(passes.Get());
vtkNew<vtkCameraPass> cameraP;
cameraP->SetDelegatePass(seq.Get());
glrenderer->SetPass(cameraP.Get());
vtkNew<vtkTimerLog> timer;
timer->StartTimer();
renderWindow->Render();
timer->StopTimer();
double firstRender = timer->GetElapsedTime();
cerr << "first render time: " << firstRender << endl;
timer->StartTimer();
int numRenders = 8;
for (int i = 0; i < numRenders; ++i)
{
renderer->GetActiveCamera()->Azimuth(80.0/numRenders);
renderer->GetActiveCamera()->Elevation(80.0/numRenders);
renderWindow->Render();
}
timer->StopTimer();
double elapsed = timer->GetElapsedTime();
cerr << "interactive render time: " << elapsed / numRenders << endl;
unsigned int numTris = reader->GetOutput()->GetPolys()->GetNumberOfCells();
cerr << "number of triangles: " << numTris << endl;
cerr << "triangles per second: " << numTris*(numRenders/elapsed) << endl;
renderer->GetActiveCamera()->SetPosition(-0.2,0.2,1);
renderer->GetActiveCamera()->SetFocalPoint(0,0,0);
renderer->GetActiveCamera()->SetViewUp(0,1,0);
renderer->GetActiveCamera()->OrthogonalizeViewUp();
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(2.5);
renderWindow->Render();
int retVal = vtkRegressionTestImage( renderWindow.Get() );
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
bakerPass->ReleaseGraphicsResources(renderWindow.Get());
return EXIT_SUCCESS;
}
......@@ -27,6 +27,9 @@ attribute vec4 vertexMC;
// optional normal declaration
//VTK::Normal::Dec
// extra lighting parameters
//VTK::Light::Dec
// Texture coordinates
//VTK::TCoord::Dec
......@@ -55,4 +58,6 @@ void main()
//VTK::PrimID::Impl
//VTK::PositionVC::Impl
//VTK::Light::Impl
}
......@@ -50,13 +50,15 @@
#include "vtkTransform.h"
#include "vtkUnsignedIntArray.h"
#include "vtkShadowMapPass.h"
// Bring in our fragment lit shader symbols.
#include "vtkPolyDataVS.h"
#include "vtkPolyDataFS.h"
#include "vtkPolyDataWideLineGS.h"
#include <algorithm>
#include <sstream>
//-----------------------------------------------------------------------------
......@@ -466,10 +468,93 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderColor(
void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
std::map<vtkShader::Type, vtkShader *> shaders,
vtkRenderer *, vtkActor *)
vtkRenderer *, vtkActor *actor)
{
std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
// check for shadow maps
vtkInformation *info = actor->GetPropertyKeys();
std::string shadowFactor = "";
if (info && info->Has(vtkShadowMapPass::ShadowMapTextures()))
{
int *shadowMapTextures = 0;
int numLights = 0;
std::string VSSource = shaders[vtkShader::Vertex]->GetSource();
shadowMapTextures = info->Get(vtkShadowMapPass::ShadowMapTextures());
numLights = info->Length(vtkShadowMapPass::ShadowMapTextures());
// how many lights have shadow maps
int numSMT = 0;
for (int i = 0; i < numLights; i++)
{
if (shadowMapTextures[i] >= 0)
{
numSMT++;
}
}
std::ostringstream toString;
toString << numSMT;
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Dec",
"//VTK::Light::Dec\n"
"#define VTK_NUM_SHADOW_MAPS " + toString.str() + "\n"
"uniform sampler2DShadow shadowMaps[VTK_NUM_SHADOW_MAPS];\n"
"varying vec4 shadowCoordsVSOutput[VTK_NUM_SHADOW_MAPS];\n"
, false);
vtkShaderProgram::Substitute(VSSource,"//VTK::Light::Dec",
"//VTK::Light::Dec\n"
"#define VTK_NUM_SHADOW_MAPS " + toString.str() + "\n"
"uniform mat4 shadowTransforms[VTK_NUM_SHADOW_MAPS];\n"
"varying vec4 shadowCoordsVSOutput[VTK_NUM_SHADOW_MAPS];\n"
, false);
// build the code for the lighting factors
std::string lfc =
"float factors[6];\n";
for (int i = 0, numSMT = 0; i < 6; i++)
{
toString.str("");
toString.clear();
toString << i;
lfc += " factors[" + toString.str() + "] = 1.0;\n";
if (shadowMapTextures[i] >= 0 && i < numLights)
{
std::ostringstream toString2;
toString2 << numSMT;
lfc +=
" if(shadowCoordsVSOutput[" + toString2.str() + "].w > 0.0)\n"
" {\n"
" vec2 projected = shadowCoordsVSOutput[" + toString2.str() + "].xy/shadowCoordsVSOutput[" + toString2.str() + "].w;\n"
" if(projected.x >= 0.0 && projected.x <= 1.0\n"
" && projected.y >= 0.0 && projected.y <= 1.0)\n"
" {\n"
" factors[" + toString.str() + "] = textureProj(shadowMaps["
+ toString2.str() + "],shadowCoordsVSOutput[" + toString2.str() + "]);\n"
" }\n"
// " factors[" + toString.str() + "] = 0.0;\n"
" }\n";
numSMT++;
}
}
lfc += "//VTK::Light::Impl";
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
lfc.c_str(), false);
vtkShaderProgram::Substitute(VSSource,"//VTK::Light::Impl",
"//VTK::Light::Impl\n"
" for (int i = 0; i < VTK_NUM_SHADOW_MAPS; i++)\n"
" {\n"
" shadowCoordsVSOutput[i] = shadowTransforms[i]*vertexVCVSOutput;\n"
" }\n"
, false);
shaders[vtkShader::Vertex]->SetSource(VSSource);
shadowFactor = "*factors[lightNum]";
}
switch (this->LastLightComplexity)
{
case 0: // no lighting
......@@ -503,11 +588,11 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" for (int lightNum = 0; lightNum < numberOfLights; lightNum++)\n"
" {\n"
" float df = max(0.0, dot(normalVCVSOutput, -lightDirectionVC[lightNum]));\n"
" diffuse += (df * lightColor[lightNum]);\n"
" diffuse += ((df" + shadowFactor + ") * lightColor[lightNum]);\n"
" if (dot(normalVCVSOutput, lightDirectionVC[lightNum]) < 0.0)\n"
" {\n"
" float sf = pow( max(0.0, dot(lightHalfAngleVC[lightNum],normalVCVSOutput)), specularPower);\n"
" specular += (sf * lightColor[lightNum]);\n"
" specular += ((sf" + shadowFactor + ") * lightColor[lightNum]);\n"
" }\n"
" }\n"
" diffuse = diffuse * diffuseColor;\n"
......@@ -566,11 +651,11 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" }\n"
" }\n"
" float df = max(0.0, attenuation*dot(normalVCVSOutput, -vertLightDirectionVC));\n"
" diffuse += (df * lightColor[lightNum]);\n"
" diffuse += ((df" + shadowFactor + ") * lightColor[lightNum]);\n"
" if (dot(normalVCVSOutput, vertLightDirectionVC) < 0.0)\n"
" {\n"
" float sf = attenuation*pow( max(0.0, dot(lightHalfAngleVC[lightNum],normalVCVSOutput)), specularPower);\n"
" specular += (sf * lightColor[lightNum]);\n"
" specular += ((sf" + shadowFactor + ") * lightColor[lightNum]);\n"
" }\n"
" }\n"
" diffuse = diffuse * diffuseColor;\n"
......@@ -1393,8 +1478,10 @@ void vtkOpenGLPolyDataMapper::SetMapperShaderParameters(vtkOpenGLHelper &cellBO,
}
//-----------------------------------------------------------------------------
void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(vtkOpenGLHelper &cellBO,
vtkRenderer* ren, vtkActor *vtkNotUsed(actor))
void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(
vtkOpenGLHelper &cellBO,
vtkRenderer* ren,
vtkActor *actor)
{
// for unlit and headlight there are no lighting parameters
if (this->LastLightComplexity < 2 || this->DrawingEdges)
......@@ -1404,6 +1491,35 @@ void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(vtkOpenGLHelper &cellB
vtkShaderProgram *program = cellBO.Program;
// check for shadow maps
vtkInformation *info = actor->GetPropertyKeys();
std::string shadowFactor = "";
if (info && info->Has(vtkShadowMapPass::ShadowMapTextures()))
{
int *shadowMapTextures = info->Get(vtkShadowMapPass::ShadowMapTextures());
double *shadowTransforms = info->Get(vtkShadowMapPass::ShadowMapTransforms());
int numLights = info->Length(vtkShadowMapPass::ShadowMapTextures());
// how many lights have shadow maps
int numSMT = 0;
int tunits[6];
float transforms[6*16];
for (int i = 0; i < numLights; i++)
{
if (shadowMapTextures[i] >= 0)
{
tunits[numSMT] = shadowMapTextures[i];
for (int i = 0; i < 16; i++)
{
transforms[numSMT*16+i] = shadowTransforms[numSMT*16+i];
}
numSMT++;
}
}
program->SetUniform1iv("shadowMaps", numSMT, tunits);
program->SetUniformMatrix4x4v("shadowTransforms", numSMT, transforms);
}
// for lightkit case there are some parameters to set
vtkCamera *cam = ren->GetActiveCamera();
vtkTransform* viewTF = cam->GetModelViewTransformObject();
......
......@@ -547,6 +547,14 @@ bool vtkShaderProgram::SetUniformMatrix3x3(const char *name,
bool vtkShaderProgram::SetUniformMatrix4x4(const char *name,
float *matrix)
{
return this->SetUniformMatrix4x4v(name,1,matrix);
}
bool vtkShaderProgram::SetUniformMatrix4x4v(
const char *name,
const int count,
float *matrix)
{
GLint location = static_cast<GLint>(this->FindUniform(name));
if (location == -1)
......@@ -554,7 +562,7 @@ bool vtkShaderProgram::SetUniformMatrix4x4(const char *name,
this->Error = "Could not set uniform " + std::string(name) + ". No such uniform.";
return false;
}
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
glUniformMatrix4fv(location, count, GL_FALSE, matrix);
return true;
}
......
......@@ -174,6 +174,7 @@ public:
bool SetUniform2fv(const char *name, const int count, const float (*f)[2]);
bool SetUniform3fv(const char *name, const int count, const float (*f)[3]);
bool SetUniform4fv(const char *name, const int count, const float (*f)[4]);
bool SetUniformMatrix4x4v(const char *name, const int count, float *v);
// How many outputs does this program produce
// only valid for OpenGL 3.2 or later
......
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkShadowMapBakerPass.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkShadowMapBakerPass - Implement a builder of shadow map pass.
// .SECTION Description
// Bake a list of shadow maps, once per spot light.
// It work in conjunction with the vtkShadowMapPass, which uses the
// shadow maps for rendering the opaque geometry (a technique to render hard
// shadows in hardware).
//
// This pass expects an initialized depth buffer and color buffer.
// Initialized buffers means they have been cleared with farest z-value and
// background color/gradient/transparent color.
// An opaque pass may have been performed right after the initialization.
//
//
//
// Its delegate is usually set to a vtkOpaquePass.
//
// .SECTION Implementation
// The first pass of the algorithm is to generate a shadow map per light
// (depth map from the light point of view) by rendering the opaque objects
//
// .SECTION See Also
// vtkRenderPass, vtkOpaquePass, vtkShadowMapPass
#ifndef vtkShadowMapBakerPass_h
#define vtkShadowMapBakerPass_h
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkRenderPass.h"
class vtkOpenGLRenderWindow;
class vtkInformationIntegerKey;
class vtkCamera;
class vtkLight;
class vtkFrameBufferObject;
class vtkShadowMapBakerPassTextures; // internal
class vtkShadowMapBakerPassLightCameras; // internal
class VTKRENDERINGOPENGL2_EXPORT vtkShadowMapBakerPass : public vtkRenderPass
{
public:
static vtkShadowMapBakerPass *New();
vtkTypeMacro(vtkShadowMapBakerPass,vtkRenderPass);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// If this key exists on the PropertyKeys of a prop, the prop is viewed as a
// light occluder (ie it casts shadows). This key is not mutually exclusive
// with the RECEIVER() key.
static vtkInformationIntegerKey *OCCLUDER();
// If this key exists on the Propertykeys of a prop, the prop is viewed as a
// light/shadow receiver. This key is not mutually exclusive with the
// OCCLUDER() key.
static vtkInformationIntegerKey *RECEIVER();
//BTX
// Description:
// Perform rendering according to a render state \p s.
// \pre s_exists: s!=0
virtual void Render(const vtkRenderState *s);
//ETX
// Description:
// Release graphics resources and ask components to release their own
// resources.
// \pre w_exists: w!=0
void ReleaseGraphicsResources(vtkWindow *w);
// Description:
// Delegate for rendering the opaque polygonal geometry.
// If it is NULL, nothing will be rendered and a warning will be emitted.
// It is usually set to a vtkCameraPass with a sequence of
// vtkLightPass/vtkOpaquePass.
// Initial value is a NULL pointer.
vtkGetObjectMacro(OpaquePass,vtkRenderPass);
virtual void SetOpaquePass(vtkRenderPass *opaquePass);
// Description:
// Delegate for compositing of the shadow maps across processors.
// If it is NULL, there is no z compositing.
// It is usually set to a vtkCompositeZPass (Parallel package).
// Initial value is a NULL pointer.