Commit b7e4976f authored by Ken Martin's avatar Ken Martin

compute cam matrix, add posiitonal light in progress

parent fc6ca437
......@@ -20,6 +20,7 @@
#include "vtkPerspectiveTransform.h"
#include "vtkTransform.h"
#include "vtkCallbackCommand.h"
#include "vtkRenderer.h"
#include <math.h>
......@@ -1062,6 +1063,37 @@ void vtkCamera::ComputeProjectionTransform(double aspect,
}
//----------------------------------------------------------------------------
// Return the projection transform matrix. See ComputeProjectionTransform.
vtkMatrix4x4 *vtkCamera::GetProjectionTransformMatrix(vtkRenderer *ren)
{
double aspect[2];
int lowerLeft[2];
int usize, vsize;
vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft+1);
// some renderer subclasses may have more complicated computations for the
// aspect ratio. So take that into account by computing the difference
// between our simple aspect ratio and what the actual renderer is reporting.
ren->ComputeAspect();
ren->GetAspect(aspect);
double aspect2[2];
ren->vtkViewport::ComputeAspect();
ren->vtkViewport::GetAspect(aspect2);
double aspectModification = aspect[0] * aspect2[1] / (aspect[1] * aspect2[0]);
if (usize && vsize)
{
matrix->DeepCopy(this->GetProjectionTransformMatrix(
aspectModification * usize / vsize, -1, 1));
matrix->Transpose();
}
return matrix;
}
//----------------------------------------------------------------------------
// Return the projection transform matrix. See ComputeProjectionTransform.
vtkMatrix4x4 *vtkCamera::GetProjectionTransformMatrix(double aspect,
......
......@@ -401,6 +401,12 @@ public:
double nearz,
double farz);
// Description:
// Return the projection transform matrix, which converts from camera
// coordinates to viewport coordinates. This method computes
// the aspect, nearz and farz, then calls the more specific
// signature of GetCompositeProjectionTransformMatrix
virtual vtkMatrix4x4 *GetProjectionTransformMatrix(vtkRenderer *ren);
// Description:
// In addition to the instance variables such as position and orientation,
......
......@@ -404,6 +404,7 @@ endforeach()
if(VTK_REPLACE_OPENGL_OVERRIDES)
set(vtk_module_vtkPolyDataMapper_override "vtkVBOPolyDataMapper")
set(vtk_module_vtkLight_override "vtkOpenGL2Light")
# set(vtk_module_vtkCamera_override "vtkOpenGL2Camera")
endif()
# Now we iterate and create that class file...
......
......@@ -19,6 +19,7 @@ set(Module_SRCS
vtkglShaderProgram.cxx
vtkglTexture2D.cxx
vtkOpenGL2Light.cxx
# vtkOpenGL2Camera.cxx
vtkVBOPolyDataMapper.cxx
${CMAKE_CURRENT_BINARY_DIR}/${vtk-module}ObjectFactory.cxx
)
......@@ -26,6 +27,7 @@ set(Module_SRCS
set(shader_files
glsl/vtkglPolyDataVSLightKit.glsl
glsl/vtkglPolyDataVSHeadlight.glsl
glsl/vtkglPolyDataVSPositionalLights.glsl
glsl/vtkglPolyDataFS.glsl
)
......
......@@ -33,15 +33,15 @@ uniform vec3 specularColor;
uniform float specularPower;
// camera and actor matrix values
uniform mat4 modelView;
uniform mat4 projection;
uniform mat4 MCVCMatrix;
uniform mat4 VCDCMatrix;
uniform mat3 normalMatrix;
varying vec4 fcolor;
void main()
{
gl_Position = projection * modelView * vertexMC;
gl_Position = VCDCMatrix * MCVCMatrix * vertexMC;
vec3 normalVC = normalize(normalMatrix * normalMC);
// diffuse and specular lighting
......
......@@ -32,8 +32,10 @@ uniform vec3 specularColor;
uniform float specularPower;
// camera and actor matrix values
uniform mat4 modelView; // combined actor (model) and view matricies
uniform mat4 projection; // the camera's projection matrix
uniform mat4 WCVCMatrix; // world to view matrix
uniform mat4 MCWCMatrix; // model to world matrix
uniform mat4 MCVCMatrix; // combined Model to View transform
uniform mat4 VCDCMatrix; // the camera's projection matrix
uniform mat3 normalMatrix; // transform model coordinate directions to view coordinates
......@@ -47,8 +49,8 @@ varying vec4 fcolor;
void main()
{
// compute the projected vertex position
vec4 vertexVC = modelView * vertexMC;
gl_Position = projection * vertexVC;
vec4 vertexVC = MCVCMatrix * vertexMC;
gl_Position = VCDCMatrix * vertexVC;
// now compute the vertex color
vec3 normalVC = normalize(normalMatrix * normalMC);
......
/*=========================================================================
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.
=========================================================================*/
// the lighting model for this shader is complex
// and supports the full VTK light API
// all variables that represent positions or directions have a suffix
// indicating the coordinate system they are in. The possible values are
// MC - Model Coordinates
// WC - WC world coordinates
// VC - View Coordinates
// DC - Display Coordinates
attribute vec4 vertexMC;
attribute vec3 normalMC;
// material property values
uniform float opacity;
uniform vec3 diffuseColor;
uniform vec3 specularColor;
uniform float specularPower;
// camera and actor matrix values
uniform mat4 WCVCMatrix; // world to view matrix
uniform mat4 MCWCMatrix; // model to world matrix
uniform mat4 MCVCMatrix; // combined Model to View transform
uniform mat4 VCDCMatrix; // the camera's projection matrix
uniform mat3 normalMatrix; // transform model coordinate directions to view coordinates
uniform int numberOfLights; // only allow for up to 6 active lights
uniform vec3 lightColor[6]; // intensity weighted color
uniform vec3 lightDirectionVC[6]; // normalized
uniform vec4 lightPositionWC[6];
uniform vec3 lightAttenuation[6];
uniform float lightConeAngle[6];
uniform float lightExponent[6];
// the resulting vertex color to be passed down to the fragment shader
varying vec4 fcolor;
void main()
{
// compute the projected vertex position
vec4 vertexVC = MCVCMatrix * vertexMC;
gl_Position = VCDCMatrix * vertexVC;
// now compute the vertex color
vec3 normalVC = normalize(normalMatrix * normalMC);
vec3 viewDirectionVC = normalize(vec3(0.0, 0.0, 1.0) - vertexVC);
vec3 diffuse = vec3(0,0,0);
vec3 specular = vec3(0,0,0);
for (int lightNum = 0; lightNum < numberOfLights; lightNum++)
{
// diffuse and specular lighting
float df = max(0.0, dot(normalVC, lightDirectionVC[lightNum]));
diffuse += (df * lightColor[lightNum]);
if (dot(normalVC, lightDirectionVC[lightNum]) > 0.0)
{
float sf = pow( max(0.0, dot(
reflect(lightDirectionVC[lightNum], normalVC), viewDirectionVC)), specularPower);
specular += (sf * lightColor[lightNum]);
}
}
diffuse = diffuse * diffuseColor;
specular = specular * specularColor;
fcolor = vec4(diffuse + specular, opacity);
}
......@@ -27,6 +27,7 @@
#include "vtkCellArray.h"
#include "vtkVector.h"
#include "vtkProperty.h"
#include "vtkMatrix3x3.h"
#include "vtkMatrix4x4.h"
#include "vtkglBufferObject.h"
......@@ -41,6 +42,7 @@
// Bring in our shader symbols.
#include "vtkglPolyDataVSLightKit.h"
#include "vtkglPolyDataVSHeadlight.h"
#include "vtkglPolyDataVSPositionalLights.h"
#include "vtkglPolyDataFS.h"
class vtkVBOPolyDataMapper::Private
......@@ -81,7 +83,7 @@ void vtkVBOPolyDataMapper::ReleaseGraphicsResources(vtkWindow*)
}
//-----------------------------------------------------------------------------
void vtkVBOPolyDataMapper::UpdateShader(vtkRenderer* ren, vtkActor *actor)
void vtkVBOPolyDataMapper::UpdateShader(vtkRenderer* ren, vtkActor *vtkNotUsed(actor))
{
// first see if anything has changed, if not, just return
// do this by checking lightcollection mtime
......@@ -124,12 +126,17 @@ void vtkVBOPolyDataMapper::UpdateShader(vtkRenderer* ren, vtkActor *actor)
case 1:
this->Internal->fragmentShaderFile = vtkglPolyDataFS;
this->Internal->vertexShaderFile = vtkglPolyDataVSHeadlight;
// this->Internal->vertexShaderFile = vtkglPolyDataVSPositionalLights;
break;
case 2:
this->Internal->fragmentShaderFile = vtkglPolyDataFS;
this->Internal->vertexShaderFile = vtkglPolyDataVSLightKit;
this->Internal->vertexShaderFile = vtkglPolyDataVSHeadlight;
// this->Internal->vertexShaderFile = vtkglPolyDataVSLightKit;
// this->Internal->vertexShaderFile = vtkglPolyDataVSPositionalLights;
break;
case 3:
this->Internal->fragmentShaderFile = vtkglPolyDataFS;
this->Internal->vertexShaderFile = vtkglPolyDataVSPositionalLights;
break;
}
......@@ -160,7 +167,7 @@ void vtkVBOPolyDataMapper::UpdateShader(vtkRenderer* ren, vtkActor *actor)
}
//-----------------------------------------------------------------------------
void vtkVBOPolyDataMapper::SetLightingShaderParameters(vtkRenderer* ren, vtkActor *actor)
void vtkVBOPolyDataMapper::SetLightingShaderParameters(vtkRenderer* ren, vtkActor *vtkNotUsed(actor))
{
// for headlight there are no lighting parameters
if (this->Internal->vertexShaderFile == vtkglPolyDataVSHeadlight)
......@@ -208,23 +215,78 @@ void vtkVBOPolyDataMapper::SetLightingShaderParameters(vtkRenderer* ren, vtkActo
this->Internal->program.setUniformValue("lightDirectionVC", numberOfLights, lightDirection);
this->Internal->program.setUniformValue("numberOfLights", numberOfLights);
if (this->Internal->vertexShaderFile == vtkglPolyDataVSLightKit)
{
return;
}
// if positional lights pass down more parameters
float lightAttenuation[6][3];
float lightConeAngle[6];
float lightExponent[6];
numberOfLights = 0;
for(lc->InitTraversal(sit);
(light = lc->GetNextLight(sit)); )
{
float status = light->GetSwitch();
if (status > 0.0)
{
double *attn = light->GetAttenuationValues();
lightAttenuation[numberOfLights][0] = attn[0];
lightAttenuation[numberOfLights][1] = attn[1];
lightAttenuation[numberOfLights][2] = attn[2];
lightExponent[numberOfLights] = light->GetExponent();
lightConeAngle[numberOfLights] = light->GetConeAngle();
numberOfLights++;
}
}
this->Internal->program.setUniformValue("lightAttenuation", numberOfLights, lightAttenuation);
this->Internal->program.setUniformValue("lightExponent", numberOfLights, lightExponent);
this->Internal->program.setUniformValue("lightConeAngle", numberOfLights, lightConeAngle);
}
//-----------------------------------------------------------------------------
void vtkVBOPolyDataMapper::SetCameraShaderParameters(vtkRenderer* ren, vtkActor *actor)
{
Eigen::Affine3f mv, proj;
glGetFloatv(GL_MODELVIEW_MATRIX, mv.matrix().data());
glGetFloatv(GL_PROJECTION_MATRIX, proj.matrix().data());
vtkgl::Matrix3f normalMatrix = mv.linear().inverse().transpose();
this->Internal->program.setUniformValue("modelView", mv.matrix());
this->Internal->program.setUniformValue("projection", proj.matrix());
this->Internal->program.setUniformValue("normalMatrix", normalMatrix);
// pass down the various model and camera transformations
vtkCamera *cam = ren->GetActiveCamera();
// really just view matrix in spite of it's name
vtkTransform* viewTF = cam->GetModelViewTransformObject();
this->Internal->program.setUniformValue("WCVCMatrix", viewTF->GetMatrix());
// set the MCWC matrix
this->Internal->program.setUniformValue("MCWCMatrix", actor->GetMatrix());
// compute the combined ModelView matrix and send it down to save time in the shader
vtkMatrix4x4 *tmpMat = vtkMatrix4x4::New();
vtkMatrix4x4::Multiply4x4(viewTF->GetMatrix(), actor->GetMatrix(), tmpMat);
tmpMat->Transpose();
this->Internal->program.setUniformValue("MCVCMatrix", tmpMat);
// set the normal matrix and send it down
// (make this a function in camera at some point returning a 3x3)
tmpMat->DeepCopy(cam->GetCameraLightTransformMatrix());
vtkMatrix3x3 *tmpMat3d = vtkMatrix3x3::New();
for(int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
tmpMat3d->SetElement(i,j,tmpMat->GetElement(i,j));
}
}
this->Internal->program.setUniformValue("normalMatrix", tmpMat3d);
tmpMat->DeepCopy(cam->GetProjectionTransformMatrix(ren));
this->Internal->program.setUniformValue("VCDCMatrix", tmpMat);
tmpMat->Delete();
tmpMat3d->Delete();
}
//-----------------------------------------------------------------------------
void vtkVBOPolyDataMapper::SetPropertyShaderParameters(vtkRenderer* ren, vtkActor *actor)
void vtkVBOPolyDataMapper::SetPropertyShaderParameters(vtkRenderer* vtkNotUsed(ren), vtkActor *actor)
{
// Query the actor for some of the properties that can be applied.
float opacity = static_cast<float>(actor->GetProperty()->GetOpacity());
......
......@@ -16,6 +16,8 @@
#include <GL/glew.h>
#include "vtkglShader.h"
#include "vtkglTexture2D.h"
#include "vtkMatrix3x3.h"
#include "vtkMatrix4x4.h"
namespace vtkgl {
......@@ -380,6 +382,54 @@ bool ShaderProgram::setUniformValue(const std::string &name,
return true;
}
bool ShaderProgram::setUniformValue(const std::string &name,
vtkMatrix4x4 *matrix)
{
GLint location = static_cast<GLint>(findUniform(name));
if (location == -1) {
m_error = "Could not set uniform " + name + ". No such uniform.";
return false;
}
float data[16];
for (int i = 0; i < 16; ++i)
{
data[i] = matrix->Element[i/4][i%4];
}
glUniformMatrix4fv(location, 1, GL_FALSE,
data);
return true;
}
bool ShaderProgram::setUniformValue(const std::string &name,
vtkMatrix3x3 *matrix)
{
GLint location = static_cast<GLint>(findUniform(name));
if (location == -1) {
m_error = "Could not set uniform " + name + ". No such uniform.";
return false;
}
float data[9];
for (int i = 0; i < 9; ++i)
{
data[i] = matrix->GetElement(i/3,i%3);
}
glUniformMatrix3fv(location, 1, GL_FALSE,
data);
return true;
}
bool ShaderProgram::setUniformValue(const std::string &name, const int count,
const float *v)
{
GLint location = static_cast<GLint>(findUniform(name));
if (location == -1) {
m_error = "Could not set uniform " + name + ". No such uniform.";
return false;
}
glUniform1fv(location, count, (const GLfloat *)v);
return true;
}
bool ShaderProgram::setUniformValue(const std::string &name, const int count,
const float (*v)[3])
{
......
......@@ -24,6 +24,9 @@
#include <vector> // For member variables.
#include <map> // For member variables.
class vtkMatrix3x3;
class vtkMatrix4x4;
namespace vtkgl {
class Shader;
......@@ -153,9 +156,13 @@ public:
/** Set the @p name uniform value to float @p f. */
bool setUniformValue(const std::string &name, float f);
/** Set the @p name uniform value to @p matrix. */
/** Set the @p name uniform array to @p f with @p count elements */
bool setUniformValue(const std::string &name, const int count, const float *f);
bool setUniformValue(const std::string &name, const int count, const float (*f)[3]);
bool setUniformValue(const std::string &name, vtkMatrix3x3 *mat);
bool setUniformValue(const std::string &name, vtkMatrix4x4 *mat);
/** Set the @p name uniform value to @p matrix. */
bool setUniformValue(const std::string &name, const Matrix3f &matrix);
bool setUniformValue(const std::string &name, const Matrix4f &matrix);
......
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