1 /*=========================================================================
2
3 Program: Visualization Toolkit
4
5 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6 All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13 =========================================================================*/
14 #include "vtkOpenGLCamera.h"
15
16 #include "vtkMatrix4x4.h"
17 #include "vtkMatrix3x3.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkRenderer.h"
20 #include "vtkOutputWindow.h"
21 #include "vtkOpenGLRenderWindow.h"
22 #include "vtkOpenGLError.h"
23
24 #include <math.h>
25
26 vtkStandardNewMacro(vtkOpenGLCamera);
27
28
vtkOpenGLCamera()29 vtkOpenGLCamera::vtkOpenGLCamera()
30 {
31 this->WCDCMatrix = vtkMatrix4x4::New();
32 this->WCVCMatrix = vtkMatrix4x4::New();
33 this->NormalMatrix = vtkMatrix3x3::New();
34 this->VCDCMatrix = vtkMatrix4x4::New();
35 this->LastRenderer = 0;
36 }
37
~vtkOpenGLCamera()38 vtkOpenGLCamera::~vtkOpenGLCamera()
39 {
40 this->WCDCMatrix->Delete();
41 this->WCVCMatrix->Delete();
42 this->NormalMatrix->Delete();
43 this->VCDCMatrix->Delete();
44 }
45
46 // Implement base class method.
Render(vtkRenderer * ren)47 void vtkOpenGLCamera::Render(vtkRenderer *ren)
48 {
49 vtkOpenGLClearErrorMacro();
50
51 int lowerLeft[2];
52 int usize, vsize;
53
54 vtkOpenGLRenderWindow *win = vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow());
55
56 // find out if we should stereo render
57 this->Stereo = (ren->GetRenderWindow())->GetStereoRender();
58 ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft+1);
59
60 // if were on a stereo renderer draw to special parts of screen
61 if (this->Stereo)
62 {
63 switch ((ren->GetRenderWindow())->GetStereoType())
64 {
65 case VTK_STEREO_CRYSTAL_EYES:
66 if (this->LeftEye)
67 {
68 if (ren->GetRenderWindow()->GetDoubleBuffer())
69 {
70 glDrawBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
71 glReadBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
72 }
73 else
74 {
75 glDrawBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
76 glReadBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
77 }
78 }
79 else
80 {
81 if (ren->GetRenderWindow()->GetDoubleBuffer())
82 {
83 glDrawBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
84 glReadBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
85 }
86 else
87 {
88 glDrawBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
89 glReadBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
90 }
91 }
92 break;
93 case VTK_STEREO_LEFT:
94 this->LeftEye = 1;
95 break;
96 case VTK_STEREO_RIGHT:
97 this->LeftEye = 0;
98 break;
99 default:
100 break;
101 }
102 }
103 else
104 {
105 if (ren->GetRenderWindow()->GetDoubleBuffer())
106 {
107 glDrawBuffer(static_cast<GLenum>(win->GetBackBuffer()));
108
109 // Reading back buffer means back left. see OpenGL spec.
110 // because one can write to two buffers at a time but can only read from
111 // one buffer at a time.
112 glReadBuffer(static_cast<GLenum>(win->GetBackBuffer()));
113 }
114 else
115 {
116 glDrawBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
117
118 // Reading front buffer means front left. see OpenGL spec.
119 // because one can write to two buffers at a time but can only read from
120 // one buffer at a time.
121 glReadBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
122 }
123 }
124
125 glViewport(lowerLeft[0], lowerLeft[1], usize, vsize);
126 glEnable(GL_SCISSOR_TEST);
127 glScissor(lowerLeft[0], lowerLeft[1], usize, vsize);
128
129 if ((ren->GetRenderWindow())->GetErase() && ren->GetErase()
130 && !ren->GetIsPicking())
131 {
132 ren->Clear();
133 }
134
135 vtkOpenGLCheckErrorMacro("failed after Render");
136 }
137
138 //----------------------------------------------------------------------------
UpdateViewport(vtkRenderer * ren)139 void vtkOpenGLCamera::UpdateViewport(vtkRenderer *ren)
140 {
141 vtkOpenGLClearErrorMacro();
142
143 int lowerLeft[2];
144 int usize, vsize;
145 ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft+1);
146
147 glViewport(lowerLeft[0], lowerLeft[1], usize, vsize);
148 glEnable(GL_SCISSOR_TEST);
149 glScissor(lowerLeft[0], lowerLeft[1], usize, vsize);
150
151 vtkOpenGLCheckErrorMacro("failed after UpdateViewport");
152 }
153
154 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)155 void vtkOpenGLCamera::PrintSelf(ostream& os, vtkIndent indent)
156 {
157 this->Superclass::PrintSelf(os,indent);
158 }
159
GetKeyMatrices(vtkRenderer * ren,vtkMatrix4x4 * & wcvc,vtkMatrix3x3 * & normMat,vtkMatrix4x4 * & vcdc,vtkMatrix4x4 * & wcdc)160 void vtkOpenGLCamera::GetKeyMatrices(vtkRenderer *ren, vtkMatrix4x4 *&wcvc,
161 vtkMatrix3x3 *&normMat, vtkMatrix4x4 *&vcdc, vtkMatrix4x4 *&wcdc)
162 {
163 // has the camera changed?
164 if (ren != this->LastRenderer ||
165 this->MTime > this->KeyMatrixTime ||
166 ren->GetMTime() > this->KeyMatrixTime)
167 {
168 this->WCVCMatrix->DeepCopy(this->GetModelViewTransformMatrix());
169
170 for(int i = 0; i < 3; ++i)
171 {
172 for (int j = 0; j < 3; ++j)
173 {
174 this->NormalMatrix->SetElement(i, j, this->WCVCMatrix->GetElement(i, j));
175 }
176 }
177 this->NormalMatrix->Invert();
178
179 this->WCVCMatrix->Transpose();
180
181 double aspect[2];
182 int lowerLeft[2];
183 int usize, vsize;
184 ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft+1);
185
186 ren->ComputeAspect();
187 ren->GetAspect(aspect);
188 double aspect2[2];
189 ren->vtkViewport::ComputeAspect();
190 ren->vtkViewport::GetAspect(aspect2);
191 double aspectModification = aspect[0] * aspect2[1] / (aspect[1] * aspect2[0]);
192
193 if (usize && vsize)
194 {
195 this->VCDCMatrix->DeepCopy(this->GetProjectionTransformMatrix(
196 aspectModification * usize / vsize, -1, 1));
197 this->VCDCMatrix->Transpose();
198 }
199
200 vtkMatrix4x4::Multiply4x4(this->WCVCMatrix, this->VCDCMatrix, this->WCDCMatrix);
201
202 this->KeyMatrixTime.Modified();
203 this->LastRenderer = ren;
204 }
205
206 wcvc = this->WCVCMatrix;
207 normMat = this->NormalMatrix;
208 vcdc = this->VCDCMatrix;
209 wcdc = this->WCDCMatrix;
210 }