Skip to content

Commit cfc53da

Browse files
* d3d12book 第六章 steap2
+ 恢复输入控制 + 恢复摄像机 + 恢复一个输入修改摄像机的控制器 * 制作第六章内容
1 parent 09c79d6 commit cfc53da

14 files changed

+1405
-87
lines changed

Chapter 6 Drawing in Direct3D/Chapter 6 Drawing in Direct3D.vcxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
</ItemDefinitionGroup>
9898
<ItemGroup>
9999
<ClCompile Include="Core\BufferManager.cpp" />
100+
<ClCompile Include="Core\Camera.cpp" />
101+
<ClCompile Include="Core\CameraController.cpp" />
100102
<ClCompile Include="Core\Color.cpp" />
101103
<ClCompile Include="Core\ColorBuffer.cpp" />
102104
<ClCompile Include="Core\CommandAllocatorPool.cpp" />
@@ -108,6 +110,7 @@
108110
<ClCompile Include="Core\DynamicUploadBuffer.cpp" />
109111
<ClCompile Include="Core\EngineTuning.cpp" />
110112
<ClCompile Include="Core\GameCore.cpp" />
113+
<ClCompile Include="Core\GameInput.cpp" />
111114
<ClCompile Include="Core\GpuBuffer.cpp" />
112115
<ClCompile Include="Core\GraphicsCommon.cpp" />
113116
<ClCompile Include="Core\GraphicsCore.cpp" />
@@ -127,6 +130,8 @@
127130
</ItemGroup>
128131
<ItemGroup>
129132
<ClInclude Include="Core\BufferManager.h" />
133+
<ClInclude Include="Core\Camera.h" />
134+
<ClInclude Include="Core\CameraController.h" />
130135
<ClInclude Include="Core\Color.h" />
131136
<ClInclude Include="Core\ColorBuffer.h" />
132137
<ClInclude Include="Core\CommandAllocatorPool.h" />
@@ -140,6 +145,7 @@
140145
<ClInclude Include="Core\EngineTuning.h" />
141146
<ClInclude Include="Core\EsramAllocator.h" />
142147
<ClInclude Include="Core\GameCore.h" />
148+
<ClInclude Include="Core\GameInput.h" />
143149
<ClInclude Include="Core\GpuBuffer.h" />
144150
<ClInclude Include="Core\GpuResource.h" />
145151
<ClInclude Include="Core\GraphicsCommon.h" />

Chapter 6 Drawing in Direct3D/Chapter 6 Drawing in Direct3D.vcxproj.filters

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,9 @@
105105
<ClCompile Include="Core\GraphicsCore.cpp">
106106
<Filter>Core\Graphics</Filter>
107107
</ClCompile>
108-
<ClCompile Include="Core\SystemTime.cpp">
109-
<Filter>Core\Graphics</Filter>
110-
</ClCompile>
111108
<ClCompile Include="Core\Color.cpp">
112109
<Filter>Core\Graphics</Filter>
113110
</ClCompile>
114-
<ClCompile Include="Core\EngineTuning.cpp">
115-
<Filter>Core\Graphics</Filter>
116-
</ClCompile>
117111
<ClCompile Include="Core\Math\Frustum.cpp">
118112
<Filter>Core\Math</Filter>
119113
</ClCompile>
@@ -162,6 +156,21 @@
162156
<ClCompile Include="Core\ReadbackBuffer.cpp">
163157
<Filter>Core\Graphics\Resource</Filter>
164158
</ClCompile>
159+
<ClCompile Include="Core\EngineTuning.cpp">
160+
<Filter>Core</Filter>
161+
</ClCompile>
162+
<ClCompile Include="Core\SystemTime.cpp">
163+
<Filter>Core</Filter>
164+
</ClCompile>
165+
<ClCompile Include="Core\GameInput.cpp">
166+
<Filter>Core</Filter>
167+
</ClCompile>
168+
<ClCompile Include="Core\Camera.cpp">
169+
<Filter>Core\Graphics</Filter>
170+
</ClCompile>
171+
<ClCompile Include="Core\CameraController.cpp">
172+
<Filter>Core</Filter>
173+
</ClCompile>
165174
</ItemGroup>
166175
<ItemGroup>
167176
<ClInclude Include="Core\CommandContext.h">
@@ -197,18 +206,12 @@
197206
<ClInclude Include="Core\GraphicsCore.h">
198207
<Filter>Core\Graphics</Filter>
199208
</ClInclude>
200-
<ClInclude Include="Core\SystemTime.h">
201-
<Filter>Core\Graphics</Filter>
202-
</ClInclude>
203209
<ClInclude Include="Core\Color.h">
204210
<Filter>Core\Graphics</Filter>
205211
</ClInclude>
206212
<ClInclude Include="Core\d3dx12.h">
207213
<Filter>Core\Graphics</Filter>
208214
</ClInclude>
209-
<ClInclude Include="Core\EngineTuning.h">
210-
<Filter>Core\Graphics</Filter>
211-
</ClInclude>
212215
<ClInclude Include="Core\Math\BoundingPlane.h">
213216
<Filter>Core\Math</Filter>
214217
</ClInclude>
@@ -287,6 +290,21 @@
287290
<ClInclude Include="Core\ReadbackBuffer.h">
288291
<Filter>Core\Graphics\Resource</Filter>
289292
</ClInclude>
293+
<ClInclude Include="Core\EngineTuning.h">
294+
<Filter>Core</Filter>
295+
</ClInclude>
296+
<ClInclude Include="Core\SystemTime.h">
297+
<Filter>Core</Filter>
298+
</ClInclude>
299+
<ClInclude Include="Core\GameInput.h">
300+
<Filter>Core</Filter>
301+
</ClInclude>
302+
<ClInclude Include="Core\Camera.h">
303+
<Filter>Core\Graphics</Filter>
304+
</ClInclude>
305+
<ClInclude Include="Core\CameraController.h">
306+
<Filter>Core</Filter>
307+
</ClInclude>
290308
</ItemGroup>
291309
<ItemGroup>
292310
<Text Include="Core\readme\readme_command.txt">
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5+
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6+
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7+
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8+
//
9+
// Developed by Minigraph
10+
//
11+
// Author: James Stanard
12+
//
13+
14+
#include "pch.h"
15+
#include "Camera.h"
16+
#include <cmath>
17+
18+
using namespace Math;
19+
20+
void BaseCamera::SetLookDirection( Vector3 forward, Vector3 up )
21+
{
22+
// Given, but ensure normalization
23+
Scalar forwardLenSq = LengthSquare(forward);
24+
forward = Select(forward * RecipSqrt(forwardLenSq), -Vector3(kZUnitVector), forwardLenSq < Scalar(0.000001f));
25+
26+
// Deduce a valid, orthogonal right vector
27+
Vector3 right = Cross(forward, up);
28+
Scalar rightLenSq = LengthSquare(right);
29+
right = Select(right * RecipSqrt(rightLenSq), Quaternion(Vector3(kYUnitVector), -XM_PIDIV2) * forward, rightLenSq < Scalar(0.000001f));
30+
31+
// Compute actual up vector
32+
up = Cross(right, forward);
33+
34+
// Finish constructing basis
35+
m_Basis = Matrix3(right, up, -forward);
36+
m_CameraToWorld.SetRotation(Quaternion(m_Basis));
37+
}
38+
39+
void BaseCamera::Update()
40+
{
41+
m_PreviousViewProjMatrix = m_ViewProjMatrix;
42+
43+
m_ViewMatrix = Matrix4(~m_CameraToWorld);
44+
m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix;
45+
m_ReprojectMatrix = m_PreviousViewProjMatrix * Invert(GetViewProjMatrix());
46+
47+
m_FrustumVS = Frustum( m_ProjMatrix );
48+
m_FrustumWS = m_CameraToWorld * m_FrustumVS;
49+
}
50+
51+
52+
void Camera::UpdateProjMatrix( void )
53+
{
54+
float Y = 1.0f / std::tanf( m_VerticalFOV * 0.5f );
55+
float X = Y * m_AspectRatio;
56+
57+
float Q1, Q2;
58+
59+
// ReverseZ puts far plane at Z=0 and near plane at Z=1. This is never a bad idea, and it's
60+
// actually a great idea with F32 depth buffers to redistribute precision more evenly across
61+
// the entire range. It requires clearing Z to 0.0f and using a GREATER variant depth test.
62+
// Some care must also be done to properly reconstruct linear W in a pixel shader from hyperbolic Z.
63+
if (m_ReverseZ)
64+
{
65+
Q1 = m_NearClip / (m_FarClip - m_NearClip);
66+
Q2 = Q1 * m_FarClip;
67+
}
68+
else
69+
{
70+
Q1 = m_FarClip / (m_NearClip - m_FarClip);
71+
Q2 = Q1 * m_NearClip;
72+
}
73+
74+
SetProjMatrix( Matrix4(
75+
Vector4( X, 0.0f, 0.0f, 0.0f ),
76+
Vector4( 0.0f, Y, 0.0f, 0.0f ),
77+
Vector4( 0.0f, 0.0f, Q1, -1.0f ),
78+
Vector4( 0.0f, 0.0f, Q2, 0.0f )
79+
) );
80+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5+
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6+
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7+
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8+
//
9+
// Developed by Minigraph
10+
//
11+
// Author: James Stanard
12+
//
13+
14+
#pragma once
15+
16+
#include "VectorMath.h"
17+
#include "Math/Frustum.h"
18+
19+
namespace Math
20+
{
21+
class BaseCamera
22+
{
23+
public:
24+
25+
// Call this function once per frame and after you've changed any state. This
26+
// regenerates all matrices. Calling it more or less than once per frame will break
27+
// temporal effects and cause unpredictable results.
28+
void Update();
29+
30+
// Public functions for controlling where the camera is and its orientation
31+
void SetEyeAtUp( Vector3 eye, Vector3 at, Vector3 up );
32+
void SetLookDirection( Vector3 forward, Vector3 up );
33+
void SetRotation( Quaternion basisRotation );
34+
void SetPosition( Vector3 worldPos );
35+
void SetTransform( const AffineTransform& xform );
36+
void SetTransform( const OrthogonalTransform& xform );
37+
38+
const Quaternion GetRotation() const { return m_CameraToWorld.GetRotation(); }
39+
const Vector3 GetRightVec() const { return m_Basis.GetX(); }
40+
const Vector3 GetUpVec() const { return m_Basis.GetY(); }
41+
const Vector3 GetForwardVec() const { return -m_Basis.GetZ(); }
42+
const Vector3 GetPosition() const { return m_CameraToWorld.GetTranslation(); }
43+
44+
// Accessors for reading the various matrices and frusta
45+
const Matrix4& GetViewMatrix() const { return m_ViewMatrix; }
46+
const Matrix4& GetProjMatrix() const { return m_ProjMatrix; }
47+
const Matrix4& GetViewProjMatrix() const { return m_ViewProjMatrix; }
48+
const Matrix4& GetReprojectionMatrix() const { return m_ReprojectMatrix; }
49+
const Frustum& GetViewSpaceFrustum() const { return m_FrustumVS; }
50+
const Frustum& GetWorldSpaceFrustum() const { return m_FrustumWS; }
51+
52+
protected:
53+
54+
BaseCamera() : m_CameraToWorld(kIdentity), m_Basis(kIdentity) {}
55+
56+
void SetProjMatrix( const Matrix4& ProjMat ) { m_ProjMatrix = ProjMat; }
57+
58+
OrthogonalTransform m_CameraToWorld;
59+
60+
// Redundant data cached for faster lookups.
61+
Matrix3 m_Basis;
62+
63+
// Transforms homogeneous coordinates from world space to view space. In this case, view space is defined as +X is
64+
// to the right, +Y is up, and -Z is forward. This has to match what the projection matrix expects, but you might
65+
// also need to know what the convention is if you work in view space in a shader.
66+
Matrix4 m_ViewMatrix; // i.e. "World-to-View" matrix
67+
68+
// The projection matrix transforms view space to clip space. Once division by W has occurred, the final coordinates
69+
// can be transformed by the viewport matrix to screen space. The projection matrix is determined by the screen aspect
70+
// and camera field of view. A projection matrix can also be orthographic. In that case, field of view would be defined
71+
// in linear units, not angles.
72+
Matrix4 m_ProjMatrix; // i.e. "View-to-Projection" matrix
73+
74+
// A concatenation of the view and projection matrices.
75+
Matrix4 m_ViewProjMatrix; // i.e. "World-To-Projection" matrix.
76+
77+
// The view-projection matrix from the previous frame
78+
Matrix4 m_PreviousViewProjMatrix;
79+
80+
// Projects a clip-space coordinate to the previous frame (useful for temporal effects).
81+
Matrix4 m_ReprojectMatrix;
82+
83+
Frustum m_FrustumVS; // View-space view frustum
84+
Frustum m_FrustumWS; // World-space view frustum
85+
86+
};
87+
88+
class Camera : public BaseCamera
89+
{
90+
public:
91+
Camera();
92+
93+
// Controls the view-to-projection matrix
94+
void SetPerspectiveMatrix( float verticalFovRadians, float aspectHeightOverWidth, float nearZClip, float farZClip );
95+
void SetFOV( float verticalFovInRadians ) { m_VerticalFOV = verticalFovInRadians; UpdateProjMatrix(); }
96+
void SetAspectRatio( float heightOverWidth ) { m_AspectRatio = heightOverWidth; UpdateProjMatrix(); }
97+
void SetZRange( float nearZ, float farZ) { m_NearClip = nearZ; m_FarClip = farZ; UpdateProjMatrix(); }
98+
void ReverseZ( bool enable ) { m_ReverseZ = enable; UpdateProjMatrix(); }
99+
100+
float GetFOV() const { return m_VerticalFOV; }
101+
float GetNearClip() const { return m_NearClip; }
102+
float GetFarClip() const { return m_FarClip; }
103+
float GetClearDepth() const { return m_ReverseZ ? 0.0f : 1.0f; }
104+
105+
private:
106+
107+
void UpdateProjMatrix( void );
108+
109+
float m_VerticalFOV; // Field of view angle in radians
110+
float m_AspectRatio;
111+
float m_NearClip;
112+
float m_FarClip;
113+
bool m_ReverseZ; // Invert near and far clip distances so that Z=0 is the far plane
114+
};
115+
116+
inline void BaseCamera::SetEyeAtUp( Vector3 eye, Vector3 at, Vector3 up )
117+
{
118+
SetLookDirection(at - eye, up);
119+
SetPosition(eye);
120+
}
121+
122+
inline void BaseCamera::SetPosition( Vector3 worldPos )
123+
{
124+
m_CameraToWorld.SetTranslation( worldPos );
125+
}
126+
127+
inline void BaseCamera::SetTransform( const AffineTransform& xform )
128+
{
129+
// By using these functions, we rederive an orthogonal transform.
130+
SetLookDirection(-xform.GetZ(), xform.GetY());
131+
SetPosition(xform.GetTranslation());
132+
}
133+
134+
inline void BaseCamera::SetRotation( Quaternion basisRotation )
135+
{
136+
m_CameraToWorld.SetRotation(Normalize(basisRotation));
137+
m_Basis = Matrix3(m_CameraToWorld.GetRotation());
138+
}
139+
140+
inline Camera::Camera() : m_ReverseZ(true)
141+
{
142+
SetPerspectiveMatrix( XM_PIDIV4, 9.0f / 16.0f, 1.0f, 1000.0f );
143+
}
144+
145+
inline void Camera::SetPerspectiveMatrix( float verticalFovRadians, float aspectHeightOverWidth, float nearZClip, float farZClip )
146+
{
147+
m_VerticalFOV = verticalFovRadians;
148+
m_AspectRatio = aspectHeightOverWidth;
149+
m_NearClip = nearZClip;
150+
m_FarClip = farZClip;
151+
152+
UpdateProjMatrix();
153+
154+
m_PreviousViewProjMatrix = m_ViewProjMatrix;
155+
}
156+
157+
} // namespace Math

0 commit comments

Comments
 (0)