// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkGLSLModCamera.h" #include "vtkActor.h" #include "vtkObjectFactory.h" #include "vtkOpenGLActor.h" #include "vtkOpenGLCamera.h" #include "vtkOpenGLRenderer.h" #include "vtkShaderProgram.h" #include VTK_ABI_NAMESPACE_BEGIN //------------------------------------------------------------------------------ vtkStandardNewMacro(vtkGLSLModCamera); //------------------------------------------------------------------------------ vtkGLSLModCamera::vtkGLSLModCamera() : CoordinateShiftAndScaleInUse(false) , ApplyShiftAndScaleFromShader(false) { } //------------------------------------------------------------------------------ vtkGLSLModCamera::~vtkGLSLModCamera() = default; //------------------------------------------------------------------------------ void vtkGLSLModCamera::PrintSelf(ostream& os, vtkIndent indent) { os << "TempMatrix3: \n"; this->TempMatrix3->PrintSelf(os, indent.GetNextIndent()); os << "TempMatrix4: \n"; this->TempMatrix4->PrintSelf(os, indent.GetNextIndent()); os << " SSMatrix: \n"; this->SSMatrix->PrintSelf(os, indent); os << "CoordinateShiftAndScaleInUse: " << this->CoordinateShiftAndScaleInUse << std::endl; this->Superclass::PrintSelf(os, indent); } //------------------------------------------------------------------------------ void vtkGLSLModCamera::EnableShiftScale(bool coordShiftAndScaleInUse, vtkMatrix4x4* ssMatrix) { this->CoordinateShiftAndScaleInUse = coordShiftAndScaleInUse; this->SSMatrix = ssMatrix; } //------------------------------------------------------------------------------ void vtkGLSLModCamera::DisableShiftScale() { this->CoordinateShiftAndScaleInUse = false; this->SSMatrix = nullptr; } //------------------------------------------------------------------------------ bool vtkGLSLModCamera::ReplaceShaderValues(vtkOpenGLRenderer*, std::string& vertexShader, std::string& tessControlShader, std::string& tessEvalShader, std::string& geometryShader, std::string& fragmentShader, vtkAbstractMapper* vtkNotUsed(mapper), vtkActor* vtkNotUsed(actor)) { std::ostringstream oss; oss << "uniform mat4 MCDCMatrix;\n"; oss << "uniform mat4 MCVCMatrix;\n"; oss << "uniform mat3 normalMatrix;\n"; oss << "uniform highp int cameraParallel;\n"; vtkShaderProgram::Substitute(vertexShader, "//VTK::Camera::Dec", oss.str()); vtkShaderProgram::Substitute(geometryShader, "//VTK::Camera::Dec", oss.str()); vtkShaderProgram::Substitute(fragmentShader, "//VTK::Camera::Dec", oss.str()); vtkShaderProgram::Substitute(tessControlShader, "//VTK::Camera::Dec", oss.str()); vtkShaderProgram::Substitute(tessEvalShader, "//VTK::Camera::Dec", oss.str()); return true; } //------------------------------------------------------------------------------ bool vtkGLSLModCamera::SetShaderParameters(vtkOpenGLRenderer* renderer, vtkShaderProgram* program, vtkAbstractMapper* vtkNotUsed(mapper), vtkActor* actor, vtkOpenGLVertexArrayObject* vtkNotUsed(VAO) /*=nullptr*/) { vtkOpenGLCamera* cam = (vtkOpenGLCamera*)(renderer->GetActiveCamera()); // [WMVDP]C == {world, model, view, display, physical} coordinates // E.g., WCDC == world to display coordinate transformation vtkMatrix4x4* wcdc; vtkMatrix4x4* wcvc; vtkMatrix3x3* norms; vtkMatrix4x4* vcdc; cam->GetKeyMatrices(renderer, wcvc, norms, vcdc, wcdc); // FIXME: Add replacements in ReplaceShaderValues? // if (program->IsUniformUsed("ZCalcR")) // { // if (cam->GetParallelProjection()) // { // program->SetUniformf("ZCalcS", vcdc->GetElement(2, 2)); // } // else // { // program->SetUniformf("ZCalcS", -0.5 * vcdc->GetElement(2, 2) + 0.5); // } // if (this->DrawingSpheres(cellBO, actor)) // { // program->SetUniformf("ZCalcR", // actor->GetProperty()->GetPointSize() / (ren->GetSize()[0] * vcdc->GetElement(0, 0))); // } // else // { // program->SetUniformf("ZCalcR", // actor->GetProperty()->GetLineWidth() / (ren->GetSize()[0] * vcdc->GetElement(0, 0))); // } // } // // handle coincident // float factor = 0.0; // float offset = 0.0; // this->GetCoincidentParameters(ren, actor, factor, offset); // if ((factor != 0.0 || offset != 0.0) && cellBO.Program->IsUniformUsed("cOffset") && // cellBO.Program->IsUniformUsed("cFactor")) // { // cellBO.Program->SetUniformf("cOffset", offset); // cellBO.Program->SetUniformf("cFactor", factor); // } vtkNew env; if (program->IsUniformUsed("envMatrix")) { double up[3]; double right[3]; double front[3]; renderer->GetEnvironmentUp(up); renderer->GetEnvironmentRight(right); vtkMath::Cross(right, up, front); for (int i = 0; i < 3; i++) { env->SetElement(i, 0, right[i]); env->SetElement(i, 1, up[i]); env->SetElement(i, 2, front[i]); } vtkMatrix3x3::Invert(norms, this->TempMatrix3); vtkMatrix3x3::Multiply3x3(this->TempMatrix3, env, this->TempMatrix3); program->SetUniformMatrix("envMatrix", this->TempMatrix3); } if (this->CoordinateShiftAndScaleInUse && this->SSMatrix) { if (!actor->GetIsIdentity()) { vtkMatrix4x4* mcwc; vtkMatrix3x3* anorms; static_cast(actor)->GetKeyMatrices(mcwc, anorms); vtkMatrix4x4::Multiply4x4(this->SSMatrix, mcwc, this->TempMatrix4); if (program->IsUniformUsed("MCWCMatrix")) { program->SetUniformMatrix("MCWCMatrix", this->TempMatrix4); } if (program->IsUniformUsed("MCWCNormalMatrix")) { program->SetUniformMatrix("MCWCNormalMatrix", anorms); } vtkMatrix4x4::Multiply4x4(this->TempMatrix4, wcdc, this->TempMatrix4); program->SetUniformMatrix("MCDCMatrix", this->TempMatrix4); if (program->IsUniformUsed("MCVCMatrix")) { vtkMatrix4x4::Multiply4x4(this->SSMatrix, mcwc, this->TempMatrix4); vtkMatrix4x4::Multiply4x4(this->TempMatrix4, wcvc, this->TempMatrix4); program->SetUniformMatrix("MCVCMatrix", this->TempMatrix4); } if (program->IsUniformUsed("normalMatrix")) { vtkMatrix3x3::Multiply3x3(anorms, norms, this->TempMatrix3); program->SetUniformMatrix("normalMatrix", this->TempMatrix3); } } else { vtkMatrix4x4::Multiply4x4(this->SSMatrix, wcdc, this->TempMatrix4); program->SetUniformMatrix("MCDCMatrix", this->TempMatrix4); if (program->IsUniformUsed("MCVCMatrix")) { vtkMatrix4x4::Multiply4x4(this->SSMatrix, wcvc, this->TempMatrix4); program->SetUniformMatrix("MCVCMatrix", this->TempMatrix4); } if (program->IsUniformUsed("normalMatrix")) { program->SetUniformMatrix("normalMatrix", norms); } } } else { if (!actor->GetIsIdentity()) { vtkMatrix4x4* mcwc; vtkMatrix3x3* anorms; ((vtkOpenGLActor*)actor)->GetKeyMatrices(mcwc, anorms); if (program->IsUniformUsed("MCWCMatrix")) { program->SetUniformMatrix("MCWCMatrix", mcwc); } if (program->IsUniformUsed("MCWCNormalMatrix")) { program->SetUniformMatrix("MCWCNormalMatrix", anorms); } vtkMatrix4x4::Multiply4x4(mcwc, wcdc, this->TempMatrix4); program->SetUniformMatrix("MCDCMatrix", this->TempMatrix4); if (program->IsUniformUsed("MCVCMatrix")) { vtkMatrix4x4::Multiply4x4(mcwc, wcvc, this->TempMatrix4); program->SetUniformMatrix("MCVCMatrix", this->TempMatrix4); } if (program->IsUniformUsed("normalMatrix")) { vtkMatrix3x3::Multiply3x3(anorms, norms, this->TempMatrix3); program->SetUniformMatrix("normalMatrix", this->TempMatrix3); } } else { program->SetUniformMatrix("MCDCMatrix", wcdc); if (program->IsUniformUsed("MCVCMatrix")) { program->SetUniformMatrix("MCVCMatrix", wcvc); } if (program->IsUniformUsed("normalMatrix")) { program->SetUniformMatrix("normalMatrix", norms); } } } if (program->IsUniformUsed("cameraParallel")) { program->SetUniformi("cameraParallel", cam->GetParallelProjection()); } return true; } VTK_ABI_NAMESPACE_END