Commit a2b9cfef authored by Tim Thirion's avatar Tim Thirion

Add a lighting map pass for OpenGL2 backend

parent 7ef0f12e
......@@ -27,6 +27,7 @@ set(Module_SRCS
vtkGenericCompositePolyDataMapper2.cxx
vtkGenericOpenGLRenderWindow.cxx
vtkImageProcessingPass.cxx
vtkLightingMapPass.cxx
vtkLightsPass.cxx
vtkOpaquePass.cxx
vtkOpenGLActor.cxx
......
vtk_add_test_cxx(${vtk-module}CxxTests tests
#TestRenderWidget.cxx # Very experimental, fails, does nothing useful yet.
TestDepthOfFieldPass.cxx
TestLightingMapLuminancePass.cxx
TestLightingMapNormalsPass.cxx
TestPointGaussianMapper.cxx
TestPointGaussianMapperOpacity.cxx
TestUserShader.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestLightingMapPass.cxx
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.
=========================================================================*/
// This test ... TO DO
//
// The command line arguments are:
// -I => run in interactive mode; unless this is used, the program will
// not allow interaction and exit
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkActor.h"
#include "vtkCameraPass.h"
#include "vtkCellArray.h"
#include "vtkInformation.h"
#include "vtkLight.h"
#include "vtkOpenGLRenderer.h"
#include "vtkPLYReader.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderPassCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSequencePass.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkLightingMapPass.h"
int TestLightingMapLuminancePass(int argc, char *argv[])
{
bool interactive = false;
for (int i = 0; i < argc; ++i)
{
if (!strcmp(argv[i], "-I"))
{
interactive = true;
}
}
// 0. Prep data
const char* fileName =
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/dragon.ply");
vtkSmartPointer<vtkPLYReader> reader
= vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName(fileName);
reader->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
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();
// 1. Set up renderer, window, & interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkRenderWindow> window =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
window->AddRenderer(renderer);
interactor->SetRenderWindow(window);
vtkSmartPointer<vtkLight> light =
vtkSmartPointer<vtkLight>::New();
light->SetLightTypeToSceneLight();
light->SetPosition(0.0, 0.0, 1.0);
light->SetPositional(true);
light->SetFocalPoint(0.0, 0.0, 0.0);
light->SetIntensity(1.0);
renderer->AddLight(light);
renderer->AddActor(actor);
// 2. Set up rendering passes
vtkSmartPointer<vtkLightingMapPass> lightingPass =
vtkSmartPointer<vtkLightingMapPass>::New();
lightingPass->SetRenderType(vtkLightingMapPass::LUMINANCE);
vtkSmartPointer<vtkRenderPassCollection> passes =
vtkSmartPointer<vtkRenderPassCollection>::New();
passes->AddItem(lightingPass);
vtkSmartPointer<vtkSequencePass> sequence =
vtkSmartPointer<vtkSequencePass>::New();
sequence->SetPasses(passes);
vtkSmartPointer<vtkCameraPass> cameraPass =
vtkSmartPointer<vtkCameraPass>::New();
cameraPass->SetDelegatePass(sequence);
vtkOpenGLRenderer *glRenderer =
vtkOpenGLRenderer::SafeDownCast(renderer.GetPointer());
glRenderer->SetPass(cameraPass);
// 3. Render image and compare against baseline
window->Render();
int retVal = vtkRegressionTestImage(window);
if (interactive || retVal == vtkRegressionTester::DO_INTERACTOR)
{
interactor->Start();
}
return !retVal;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestLightingMapPass.cxx
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.
=========================================================================*/
// This test ... TO DO
//
// The command line arguments are:
// -I => run in interactive mode; unless this is used, the program will
// not allow interaction and exit
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkActor.h"
#include "vtkCameraPass.h"
#include "vtkCellArray.h"
#include "vtkInformation.h"
#include "vtkLight.h"
#include "vtkOpenGLRenderer.h"
#include "vtkPLYReader.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderPassCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSequencePass.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkLightingMapPass.h"
int TestLightingMapNormalsPass(int argc, char *argv[])
{
bool interactive = false;
for (int i = 0; i < argc; ++i)
{
if (!strcmp(argv[i], "-I"))
{
interactive = true;
}
}
// 0. Prep data
const char* fileName =
vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/dragon.ply");
vtkSmartPointer<vtkPLYReader> reader
= vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName(fileName);
reader->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
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();
// 1. Set up renderer, window, & interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkRenderWindow> window =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
window->AddRenderer(renderer);
interactor->SetRenderWindow(window);
vtkSmartPointer<vtkLight> light =
vtkSmartPointer<vtkLight>::New();
light->SetLightTypeToSceneLight();
light->SetPosition(0.0, 0.0, 1.0);
light->SetPositional(true);
light->SetFocalPoint(0.0, 0.0, 0.0);
light->SetIntensity(1.0);
renderer->AddLight(light);
renderer->AddActor(actor);
// 2. Set up rendering passes
vtkSmartPointer<vtkLightingMapPass> lightingPass =
vtkSmartPointer<vtkLightingMapPass>::New();
lightingPass->SetRenderType(vtkLightingMapPass::NORMALS);
vtkSmartPointer<vtkRenderPassCollection> passes =
vtkSmartPointer<vtkRenderPassCollection>::New();
passes->AddItem(lightingPass);
vtkSmartPointer<vtkSequencePass> sequence =
vtkSmartPointer<vtkSequencePass>::New();
sequence->SetPasses(passes);
vtkSmartPointer<vtkCameraPass> cameraPass =
vtkSmartPointer<vtkCameraPass>::New();
cameraPass->SetDelegatePass(sequence);
vtkOpenGLRenderer *glRenderer =
vtkOpenGLRenderer::SafeDownCast(renderer.GetPointer());
glRenderer->SetPass(cameraPass);
// 3. Render image and compare against baseline
window->Render();
int retVal = vtkRegressionTestImage(window);
if (interactive || retVal == vtkRegressionTester::DO_INTERACTOR)
{
interactor->Start();
}
return !retVal;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLightingMapPass.cxx
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.
=========================================================================*/
#include "vtkLightingMapPass.h"
#include "vtkClearRGBPass.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkObjectFactory.h"
#include "vtkProp.h"
#include "vtkRenderer.h"
#include "vtkRenderState.h"
#include "vtkSmartPointer.h"
#include <cassert>
vtkStandardNewMacro(vtkLightingMapPass);
vtkInformationKeyMacro(vtkLightingMapPass, RENDER_LUMINANCE, Integer);
vtkInformationKeyMacro(vtkLightingMapPass, RENDER_NORMALS, Integer);
// ----------------------------------------------------------------------------
vtkLightingMapPass::vtkLightingMapPass()
{
}
// ----------------------------------------------------------------------------
vtkLightingMapPass::~vtkLightingMapPass()
{
}
// ----------------------------------------------------------------------------
void vtkLightingMapPass::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
}
// ----------------------------------------------------------------------------
// Description:
// Perform rendering according to a render state \p s.
// \pre s_exists: s!=0
void vtkLightingMapPass::Render(const vtkRenderState *s)
{
assert("pre: s_exists" && s != 0);
// Render filtered geometry according to our keys
this->NumberOfRenderedProps = 0;
this->RenderOpaqueGeometry(s);
}
// ----------------------------------------------------------------------------
// Description:
// Opaque pass with key checking.
// \pre s_exists: s!=0
void vtkLightingMapPass::RenderOpaqueGeometry(const vtkRenderState *s)
{
assert("pre: s_exists" && s!=0);
// Clear the RGB buffer first
vtkSmartPointer<vtkClearRGBPass> clear =
vtkSmartPointer<vtkClearRGBPass>::New();
clear->Render(s);
int c = s->GetPropArrayCount();
int i = 0;
while (i < c)
{
vtkProp *p = s->GetPropArray()[i];
vtkSmartPointer<vtkInformation> keys = p->GetPropertyKeys();
if (!keys)
{
keys.TakeReference(vtkInformation::New());
}
switch (this->GetRenderType())
{
case LUMINANCE:
keys->Set(vtkLightingMapPass::RENDER_LUMINANCE(), 1);
break;
case NORMALS:
keys->Set(vtkLightingMapPass::RENDER_NORMALS(), 1);
break;
}
p->SetPropertyKeys(keys);
int rendered =
p->RenderOpaqueGeometry(s->GetRenderer());
this->NumberOfRenderedProps += rendered;
++i;
}
// Remove keys
i = 0;
while (i < c)
{
vtkProp *p = s->GetPropArray()[i];
vtkInformation *keys = p->GetPropertyKeys();
switch (this->GetRenderType())
{
case LUMINANCE:
keys->Remove(vtkLightingMapPass::RENDER_LUMINANCE());
break;
case NORMALS:
keys->Remove(vtkLightingMapPass::RENDER_NORMALS());
break;
}
p->SetPropertyKeys(keys);
++i;
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLightingMapPass.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 vtkLightingMapPass - TO DO
// .SECTION Description
// Renders lighting information directly instead of final shaded colors.
// The information keys allow the selection of either normal rendering or
// luminance. For normals, the (nx, ny, nz) tuple are rendered directly into
// the (r,g,b) fragment. For luminance, the diffuse and specular intensities are
// rendered into the red and green channels, respectively. The blue channel is
// zero. For both luminances and normals, the alpha channel is set to 1.0 if
// present.
//
// .SECTION See Also
// vtkRenderPass vtkDefaultPass
#ifndef vtkLightingMapPass_h
#define vtkLightingMapPass_h
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkDefaultPass.h"
class vtkInformationIntegerKey;
class VTKRENDERINGOPENGL2_EXPORT vtkLightingMapPass : public vtkDefaultPass
{
public:
static vtkLightingMapPass *New();
vtkTypeMacro(vtkLightingMapPass, vtkDefaultPass);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set the type of lighting render to perform
enum RenderMode { LUMINANCE, NORMALS };
vtkSetMacro(RenderType, RenderMode);
vtkGetMacro(RenderType, RenderMode);
// Description:
// If this key exists on the PropertyKeys of a prop, the active scalar array
// on the prop will be rendered as its color. This key is mutually exclusive
// with the RENDER_LUMINANCE key.
static vtkInformationIntegerKey *RENDER_LUMINANCE();
// Description:
// if this key exists on the ProperyKeys of a prop, the active vector array on
// the prop will be rendered as its color. This key is mutually exclusive with
// the RENDER_LUMINANCE key.
static vtkInformationIntegerKey *RENDER_NORMALS();
//BTX
// Description:
// Perform rendering according to a render state \p s.
// \pre s_exists: s!=0
virtual void Render(const vtkRenderState *s);
//ETX
protected:
// Description:
// Default constructor.
vtkLightingMapPass();
// Description:
// Destructor.
virtual ~vtkLightingMapPass();
// Description:
// Opaque pass with key checking.
// \pre s_exists: s!=0
virtual void RenderOpaqueGeometry(const vtkRenderState *s);
private:
vtkLightingMapPass(const vtkLightingMapPass&); // Not implemented.
void operator=(const vtkLightingMapPass&); // Not implemented.
RenderMode RenderType;
};
#endif
......@@ -24,6 +24,7 @@
#include "vtkInformation.h"
#include "vtkLight.h"
#include "vtkLightCollection.h"
#include "vtkLightingMapPass.h"
#include "vtkMath.h"
#include "vtkMatrix3x3.h"
#include "vtkMatrix4x4.h"
......@@ -577,8 +578,19 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
{
std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
// check for shadow maps
// check for normal rendering
vtkInformation *info = actor->GetPropertyKeys();
if (info && info->Has(vtkLightingMapPass::RENDER_NORMALS()))
{
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
" vec3 n = (normalVCVSOutput + 1.0) * 0.5;\n"
" gl_FragData[0] = vec4(n.x, n.y, n.z, 1.0);"
);
shaders[vtkShader::Fragment]->SetSource(FSSource);
return;
}
// check for shadow maps
std::string shadowFactor = "";
if (info && info->Has(vtkShadowMapPass::ShadowMapPass()))
{
......@@ -594,22 +606,37 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
}
}
// If rendering, set diffuse and specular colors to pure white
if (info && info->Has(vtkLightingMapPass::RENDER_LUMINANCE()))
{
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" diffuseColor = vec3(1, 1, 1);\n"
" specularColor = vec3(1, 1, 1);\n"
" //VTK::Light::Impl\n",
false
);
}
switch (this->LastLightComplexity[this->LastBoundBO])
{
case 0: // no lighting
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
"gl_FragData[0] = vec4(ambientColor + diffuseColor, opacity);"
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" gl_FragData[0] = vec4(ambientColor + diffuseColor, opacity);\n"
" //VTK::Light::Impl\n",
false
);
break;
case 1: // headlight
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
"float df = max(0.0, normalVCVSOutput.z);\n"
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" float df = max(0.0, normalVCVSOutput.z);\n"
" float sf = pow(df, specularPower);\n"
" vec3 diffuse = df * diffuseColor;\n"
" vec3 specular = sf * specularColor;\n"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);"
);
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);\n"
" //VTK::Light::Impl\n",
false
);
break;
case 2: // light kit
......@@ -620,7 +647,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
"uniform vec3 lightColor[6];\n"
"uniform vec3 lightDirectionVC[6]; // normalized\n"
"uniform vec3 lightHalfAngleVC[6]; // normalized"
);
);
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
"vec3 diffuse = vec3(0,0,0);\n"
" vec3 specular = vec3(0,0,0);\n"
......@@ -636,8 +663,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" }\n"
" diffuse = diffuse * diffuseColor;\n"
" specular = specular * specularColor;\n"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);\n"
);
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);"
" //VTK::Light::Impl",
false
);
break;
case 3: // positional
......@@ -653,7 +682,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
"uniform float lightConeAngle[6];\n"
"uniform float lightExponent[6];\n"
"uniform int lightPositional[6];"
);
);
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Impl",
" vec3 diffuse = vec3(0,0,0);\n"
" vec3 specular = vec3(0,0,0);\n"
......@@ -699,11 +728,34 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" }\n"
" diffuse = diffuse * diffuseColor;\n"
" specular = specular * specularColor;\n"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);\n"
" //VTK::Light::Impl",
false
);
break;
}
// If rendering luminance values, write those values to the fragment
if (info && info->Has(vtkLightingMapPass::RENDER_LUMINANCE()))
{
switch (this->LastLightComplexity[this->LastBoundBO])
{
case 0: // no lighting
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" gl_FragData[0] = vec4(0.0, 0.0, 0.0, 1.0);"
);
break;
case 1: // headlight
case 2: // light kit
case 3: // positional
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" float ambientY = dot(vec3(0.2126, 0.7152, 0.0722), ambientColor);\n"
" gl_FragData[0] = vec4(ambientY, diffuse.x, specular.x, 1.0);"
);
break;
}
}
shaders[vtkShader::Fragment]->SetSource(FSSource);
}
......@@ -1182,8 +1234,9 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderValues(
this->ReplaceShaderPrimID(shaders, ren, actor);
this->ReplaceShaderPositionVC(shaders, ren, actor);
//cout << "VS: " << VSSource << endl;
//cout << "FS: " << FSSource << endl;
//cout << "VS: " << shaders[vtkShader::Vertex]->GetSource() << endl;
//cout << "GS: " << shaders[vtkShader::Geometry]->GetSource() << endl;
//cout << "FS: " << shaders[vtkShader::Fragment]->GetSource() << endl;
}
//-----------------------------------------------------------------------------
......@@ -1557,6 +1610,9 @@ void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(
vtkLightCollection *lc = ren->GetLights();
vtkLight *light;
bool renderLuminance = info &&
info->Has(vtkLightingMapPass::RENDER_LUMINANCE());
vtkCollectionSimpleIterator sit;
float lightColor[6][3];
float lightDirection[6][3];
......@@ -1569,9 +1625,18 @@ void vtkOpenGLPolyDataMapper::SetLightingShaderParameters(
{
double *dColor = light->GetDiffuseColor();
double intensity = light->GetIntensity();
lightColor[numberOfLights][0] = dColor[0] * intensity;
lightColor[numberOfLights][1] = dColor[1] * intensity;
lightColor[numberOfLights][2] = dColor[2] * intensity;
if (renderLuminance)
{
lightColor[numberOfLights][0] = intensity;
lightColor[numberOfLights][1] = intensity;
lightColor[numberOfLights][2] = intensity;
}
else
{
lightColor[numberOfLights][0] = dColor[0] * intensity;
lightColor[numberOfLights][1] = dColor[1] * intensity;
lightColor[numberOfLights][2] = dColor[2] * intensity;
}
// get required info from light
double *lfp = light->GetTransformedFocalPoint();
double *lp = light->GetTransformedPosition();
......
......@@ -228,7 +228,7 @@ protected:
vtkRenderer *ren, vtkActor *act);
// Description:
// Set the shader parameteres related to the mapper/input data, called by UpdateShader
// Set the shader parameters related to the mapper/input data, called by UpdateShader
virtual void SetMapperShaderParameters(vtkOpenGLHelper &cellBO, vtkRenderer *ren, vtkActor *act);
// Description:
......
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