Commit 04c45455 authored by Ken Martin's avatar Ken Martin
Browse files

Add a mechanism where shader uniforms can be updates

Added an event that fires when the shader updsates so that
programs can use it to update any uniforms they want to
parent 1b5d4d38
......@@ -194,6 +194,8 @@
// - A int* being the number of the button
// - vtkCommand::TDxButtonReleaseEvent
// - A int* being the number of the button
// - vtkCommand::UpdateShaderEvent
// - A vtkOpenGLHelper* currently being used
//
// .SECTION See Also
// vtkObject vtkCallbackCommand vtkOldStyleCallbackCommand
......@@ -309,6 +311,7 @@
_vtk_add_event(WindowSupportsOpenGLEvent)\
_vtk_add_event(WindowIsDirectEvent)\
_vtk_add_event(UncheckedPropertyModifiedEvent)\
_vtk_add_event(UpdateShaderEvent)\
_vtk_add_event(MessageEvent)
#define vtkEventDeclarationMacro(_enum_name)\
......
......@@ -12,20 +12,74 @@
=========================================================================*/
#include "vtkCamera.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCommand.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkOpenGLPolyDataMapper.h"
#include "vtkPLYReader.h"
#include "vtkNew.h"
#include "vtkProperty.h"
#include "vtkPolyDataNormals.h"
#include "vtkProperty.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkShaderProgram.h"
#include "vtkTestUtilities.h"
#include "vtkTimerLog.h"
#include "vtkRenderWindowInteractor.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
// -----------------------------------------------------------------------
// Update a uniform in the shader for each render. We do this with a
// callback for the UpdateShaderEvent
class vtkShaderCallback : public vtkCommand
{
public:
static vtkShaderCallback *New()
{ return new vtkShaderCallback; }
vtkRenderer *Renderer;
virtual void Execute(vtkObject *, unsigned long, void*cbo)
{
vtkOpenGLHelper *cellBO = reinterpret_cast<vtkOpenGLHelper*>(cbo);
float diffuseColor[3];
#if 0 // trippy mode
float inputHSV[3];
double theTime = vtkTimerLog::GetUniversalTime();
double twopi = 2.0*3.1415926;
inputHSV[0] = sin(twopi*fmod(theTime,3.0)/3.0)/4.0 + 0.25;
inputHSV[1] = sin(twopi*fmod(theTime,4.0)/4.0)/2.0 + 0.5;
inputHSV[2] = 0.7*(sin(twopi*fmod(theTime,19.0)/19.0)/2.0 + 0.5);
vtkMath::HSVToRGB(inputHSV,diffuseColor);
cellBO->Program->SetUniform3f("diffuseColorUniform", diffuseColor);
inputHSV[0] = sin(twopi*fmod(theTime,5.0)/5.0)/4.0 + 0.75;
inputHSV[1] = sin(twopi*fmod(theTime,7.0)/7.0)/2.0 + 0.5;
inputHSV[2] = 0.5*(sin(twopi*fmod(theTime,17.0)/17.0)/2.0 + 0.5);
vtkMath::HSVToRGB(inputHSV,diffuseColor);
this->Renderer->SetBackground(diffuseColor[0], diffuseColor[1], diffuseColor[2]);
inputHSV[0] = sin(twopi*fmod(theTime,11.0)/11.0)/2.0+0.5;
inputHSV[1] = sin(twopi*fmod(theTime,13.0)/13.0)/2.0 + 0.5;
inputHSV[2] = 0.5*(sin(twopi*fmod(theTime,17.0)/17.0)/2.0 + 0.5);
vtkMath::HSVToRGB(inputHSV,diffuseColor);
this->Renderer->SetBackground2(diffuseColor[0], diffuseColor[1], diffuseColor[2]);
#else
diffuseColor[0] = 0.4;
diffuseColor[1] = 0.7;
diffuseColor[2] = 0.6;
cellBO->Program->SetUniform3f("diffuseColorUniform", diffuseColor);
#endif
}
vtkShaderCallback() {}
};
//----------------------------------------------------------------------------
int TestUserShader2(int argc, char *argv[])
......@@ -38,6 +92,7 @@ int TestUserShader2(int argc, char *argv[])
renderWindow->SetSize(400, 400);
renderWindow->AddRenderer(renderer.Get());
renderer->AddActor(actor.Get());
renderer->GradientBackgroundOn();
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renderWindow.Get());
......@@ -62,11 +117,12 @@ int TestUserShader2(int argc, char *argv[])
actor->GetProperty()->SetSpecularPower(20.0);
actor->GetProperty()->SetOpacity(1.0);
// Use our own hardcoded shader code. Generally this is a bad idea as there
// are so many things VTK supports that hardcoded shaders will not handle
// depth peeling, picking, etc, but if you really want to, here is an example.
// The mapper will set a bunch of uniforms regardless of if you are using
// them. But feel free to use them :-)
// Use our own hardcoded shader code. Generally this is a bad idea in a
// general purpose program as there are so many things VTK supports that
// hardcoded shaders will not handle depth peeling, picking, etc, but if you
// know what your data will be like it can be very useful. The mapper will set
// a bunch of uniforms regardless of if you are using them. But feel free to
// use them :-)
mapper->SetVertexShaderCode(
"//VTK::System::Dec\n" // always start with this line
"attribute vec4 vertexMC;\n"
......@@ -88,15 +144,21 @@ int TestUserShader2(int argc, char *argv[])
"//VTK::System::Dec\n" // always start with this line
"//VTK::Output::Dec\n" // always have this line in your FS
"varying vec3 normalVCVSOutput;\n"
"uniform vec3 diffuseColorUniform;\n"
"void main () {\n"
" float df = max(0.0, normalVCVSOutput.z);\n"
" float sf = pow(df, 20.0);\n"
" vec3 diffuse = df * vec3(0.4,0.9,0.7);\n"
" vec3 diffuse = df * diffuseColorUniform;\n"
" vec3 specular = sf * vec3(0.4,0.4,0.4);\n"
" gl_FragData[0] = vec4(diffuse + specular, 1.0);\n"
" gl_FragData[0] = vec4(0.3*abs(normalVCVSOutput) + 0.7*diffuse + specular, 1.0);\n"
"}\n"
);
// Setup a callback to change some uniforms
VTK_CREATE(vtkShaderCallback, myCallback);
myCallback->Renderer = renderer.Get();
mapper->AddObserver(vtkCommand::UpdateShaderEvent,myCallback);
renderWindow->Render();
renderer->GetActiveCamera()->SetPosition(-0.2,0.4,1);
renderer->GetActiveCamera()->SetFocalPoint(0,0,0);
......
7b26fde777b26b1ee5c67b26d3c76e7e
3fb7549af8fdf86d30e35e783d1348e5
......@@ -1390,6 +1390,9 @@ void vtkOpenGLPolyDataMapper::UpdateShaders(
this->SetCameraShaderParameters(cellBO, ren, actor);
this->SetLightingShaderParameters(cellBO, ren, actor);
// allow the program to set what it wants
this->InvokeEvent(vtkCommand::UpdateShaderEvent,&cellBO);
vtkOpenGLCheckErrorMacro("failed after UpdateShader");
}
......
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