[DirectX11] 013~014 Camera
목차
Camera
D3DXMATRIX *D3DXMatrixLookAtLH
D3DXMATRIX *D3DXMatrixLookAtLH(
D3DXMATRIX *pOut,
CONST D3DXVECTOR3 *pEye,
CONST D3DXVECTOR3 *pAt,
CONST D3DXVECTOR3 *pUp
);
zaxis = normal(At - Eye) xaxis = normal(cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) xaxis.x yaxis.x zaxis.x 0 xaxis.y yaxis.y zaxis.y 0 xaxis.z yaxis.z zaxis.z 0 -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1
- Cross -> 외적
https://learn.microsoft.com/ko-kr/windows/win32/direct3d10/d3d10-d3dxmatrixlookatlh
D3DXMatrixLookAtLH 함수(D3DX10Math.h) - Win32 apps
D3DXMatrixLookAtLH 함수(D3DX10Math.h) - 왼손 보기 행렬을 빌드합니다.
learn.microsoft.com
http://telnet.or.kr/directx/graphics/reference/d3dx/functions/math/d3dxmatrixlookatlh.htm
D3DXMatrixLookAtLH 함수
D3DXMatrixLookAtLH 함수 왼손 좌표계 뷰 행렬을 생성 한다. 구문 D3DXMATRIX *D3DXMatrixLookAtLH( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp ); 파
telnet.or.kr
Camera GridDemo 코드
GridDemo.h
#pragma once #include "Systems/IExecute.h" class GridDemo : public IExecute { public: virtual void Initialize() override; virtual void Ready() override {} virtual void Destroy() override; virtual void Update() override; virtual void PreRender() override {} virtual void Render() override; virtual void PostRender() override {} virtual void ResizeScreen() override {} private: Shader* shader; UINT width = 256, height = 256; UINT vertexCount; Vertex* vertices; ID3D11Buffer* vertexBuffer; UINT indexCount; UINT* indices; ID3D11Buffer* indexBuffer; Matrix world; };
GridDemo.cpp
#include "stdafx.h" #include "GridDemo.h" void GridDemo::Initialize() { shader = new Shader(L"10_World.fx"); vertexCount = (width + 1) * (height + 1); vertices = new Vertex[vertexCount]; for (UINT y = 0; y <= height; y++) { for (UINT x = 0; x <= width; x++) { UINT i = (width + 1) * y + x; vertices[i].Position.x = (float)x; vertices[i].Position.y = 0.0f; vertices[i].Position.z = (float)y; } } //Create Vertex Buffer { D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(Vertex) * vertexCount; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA subResource = { 0 }; subResource.pSysMem = vertices; Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &vertexBuffer)); } indexCount = (width * height) * 6; indices = new UINT[indexCount]; UINT index = 0; for (UINT y = 0; y < height; y++) { for (UINT x = 0; x < width; x++) { indices[index + 0] = (width + 1) * y + x; indices[index + 1] = (width + 1) * (y + 1) + x; indices[index + 2] = (width + 1) * y + x + 1; indices[index + 3] = (width + 1) * y + x + 1; indices[index + 4] = (width + 1) * (y + 1) + x; indices[index + 5] = (width + 1) * (y + 1) + x + 1; index += 6; } } //Create Index Buffer { D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(UINT) * indexCount; desc.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA subResource = { 0 }; subResource.pSysMem = indices; Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &indexBuffer)); } SafeDeleteArray(vertices); SafeDeleteArray(indices); D3DXMatrixIdentity(&world); } void GridDemo::Destroy() { SafeDelete(shader); SafeRelease(vertexBuffer); SafeRelease(indexBuffer); } void GridDemo::Update() { } void GridDemo::Render() { shader->AsScalar("Index")->SetInt(0); shader->AsMatrix("World")->SetMatrix(world); shader->AsMatrix("View")->SetMatrix(Context::Get()->View()); shader->AsMatrix("Projection")->SetMatrix(Context::Get()->Projection()); UINT stride = sizeof(Vertex); UINT offset = 0; D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0); shader->DrawIndexed(0, 1, indexCount); }
Main.cpp
#include "stdafx.h" #include "Main.h" #include "Systems/Window.h" #include "GridDemo.h" void Main::Initialize() { Push(new GridDemo()); } void Main::Ready() { } void Main::Destroy() { for (IExecute* exe : executes) { exe->Destroy(); SafeDelete(exe); } } void Main::Update() { for (IExecute* exe : executes) exe->Update(); } void Main::PreRender() { for (IExecute* exe : executes) exe->PreRender(); } void Main::Render() { for (IExecute* exe : executes) exe->Render(); } void Main::PostRender() { for (IExecute* exe : executes) exe->PostRender(); } void Main::ResizeScreen() { for (IExecute* exe : executes) exe->ResizeScreen(); } void Main::Push(IExecute * execute) { executes.push_back(execute); execute->Initialize(); } int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR param, int command) { D3DDesc desc; desc.AppName = L"D3D Game"; desc.Instance = instance; desc.bFullScreen = false; desc.bVsync = false; desc.Handle = NULL; desc.Width = 1280; desc.Height = 720; desc.Background = Color(0.3f, 0.3f, 0.3f, 1.0f); D3D::SetDesc(desc); Main* main = new Main(); WPARAM wParam = Window::Run(main); SafeDelete(main); return wParam; }
실행화면

D3DXVec3Transform
mul(input.position, world);
= position의 값을 world 공간으로 변환하겠다.
D3DXVec3TransformCoord(위치, )
D3DXVec3TransformNormal(방향, )
https://learn.microsoft.com/ko-kr/windows/win32/direct3d10/d3d10-d3dxvec3transform
D3DXVec3Transform 함수(D3DX10Math.h) - Win32 apps
D3DXVec3Transform 함수(D3DX10Math.h) - 지정된 행렬로 벡터(x, y, z, 1)를 변환합니다.
learn.microsoft.com
http://telnet.or.kr/directx/graphics/reference/d3dx/functions/math/d3dxvec3transform.htm
D3DXVec3Transform 함수
D3DXVec3Transform 함수 지정된 행렬에 의해 벡터 (x, y, z, 1)를 변환 한다. 구문 D3DXVECTOR4 *WINAPI D3DXVec3Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); 파라미터 p
telnet.or.kr
Camera, Freedom, Context 코드
Camera.h
#pragma once class Camera { public: Camera(); virtual ~Camera(); virtual void Update() = 0; public: void Position(float x, float y, float z); void Position(Vector3& vec); void Position(Vector3* vec); void Rotation(float x, float y, float z); void Rotation(Vector3& vec); void Rotation(Vector3* vec); void RotationDegree(float x, float y, float z); void RotationDegree(Vector3& vec); void RotationDegree(Vector3* vec); void GetMatrix(Matrix* matrix); Vector3 Forward() { return forward; } Vector3 Up() { return up; } Vector3 Right() { return right; } protected: virtual void Rotation(); virtual void Move(); protected: void View(); protected: Matrix matView; //뷰 행렬 private: Vector3 position = Vector3(0, 0, 0); Vector3 rotation = Vector3(0, 0, 0); Vector3 forward = Vector3(0, 0, 1); Vector3 up = Vector3(0, 1, 0); Vector3 right = Vector3(1, 0, 0); Matrix matRotation; //회전 행렬 };
Camera.cpp
#include "Framework.h" #include "Camera.h" Camera::Camera() { D3DXMatrixIdentity(&matRotation); D3DXMatrixIdentity(&matView); Rotation(); Move(); } Camera::~Camera() { } void Camera::Position(float x, float y, float z) { Position(Vector3(x, y, z)); } void Camera::Position(Vector3 & vec) { position = vec; Move(); } void Camera::Position(Vector3 * vec) { *vec = position; } void Camera::Rotation(float x, float y, float z) { Rotation(Vector3(x, y, z)); } void Camera::Rotation(Vector3 & vec) { rotation = vec; Rotation(); } void Camera::Rotation(Vector3 * vec) { *vec = rotation; } void Camera::RotationDegree(float x, float y, float z) { RotationDegree(Vector3(x, y, z)); } void Camera::RotationDegree(Vector3 & vec) { //라디안으로 바꿔주는 수식 //rotation = vec * Math::PI / 180.0f; rotation = vec * 0.01745328f; Rotation(); } void Camera::RotationDegree(Vector3 * vec) { //라디안을 degree로 돌려주는 수식 //*vec = rotation * 180.0f / Math::PI; *vec = rotation * 57.29577957f; } void Camera::GetMatrix(Matrix * matrix) { //대입 방식 //*matrix = matView; //메모리복사 방식, 이 방법이 대입 방식보다 빠르다 memcpy(matrix, &matView, sizeof(Matrix)); } void Camera::Rotation() { Matrix X, Y, Z; //세 축이 회전 D3DXMatrixRotationX(&X, rotation.x); D3DXMatrixRotationY(&Y, rotation.y); D3DXMatrixRotationZ(&Z, rotation.z); //세 축이 회전한 축을 matRotation에 넣어준다 matRotation = X * Y * Z; D3DXVec3TransformNormal(&forward, &Vector3(0, 0, 1), &matRotation); D3DXVec3TransformNormal(&up, &Vector3(0, 1, 0), &matRotation); D3DXVec3TransformNormal(&right, &Vector3(1, 0, 0), &matRotation); } void Camera::Move() { View(); } void Camera::View() { D3DXMatrixLookAtLH(&matView, &position, &(position + forward), &up); }
Freedom.h
#pragma once #include "Camera.h" class Freedom : public Camera { public: Freedom(); ~Freedom(); void Update() override; void Speed(float move, float rotation = 2.0f); private: float move = 20.0f; float rotation = 2.0f; };
Freedom.cpp
#include "Framework.h" #include "Freedom.h" Freedom::Freedom() : Camera() { } Freedom::~Freedom() { } void Freedom::Update() { if(Mouse::Get()->Press(1) == false) return; Vector3 f = Forward(); Vector3 u = Up(); Vector3 r = Right(); //Vector3 f = Vector3(0, 0, 1); //Vector3 u = Vector3(0, 1, 0); //Vector3 r = Vector3(1, 0, 0); //Move { Vector3 P; Position(&P); if (Keyboard::Get()->Press('W')) P = P + f * move * Time::Delta(); else if (Keyboard::Get()->Press('S')) P = P - f * move * Time::Delta(); if (Keyboard::Get()->Press('D')) P = P + r * move * Time::Delta(); else if (Keyboard::Get()->Press('A')) P = P - r * move * Time::Delta(); if (Keyboard::Get()->Press('E')) P = P + u * move * Time::Delta(); else if (Keyboard::Get()->Press('Q')) P = P - u * move * Time::Delta(); Position(P); } //Rotation { Vector3 R; Rotation(&R); Vector3 val = Mouse::Get()->GetMoveValue(); R.x = R.x + val.y * rotation * Time::Delta(); R.y = R.y + val.x * rotation * Time::Delta(); R.z = 0.0f; Rotation(R); } } void Freedom::Speed(float move, float rotation) { this->move = move; this->rotation = rotation; }
Context.h
#pragma once class Context { public: static Context* Get(); static void Create(); static void Delete(); private: Context(); ~Context(); public: void ResizeScreen(); void Update(); void Render(); Matrix View(); Matrix Projection(); class Perspective* GetPerspective() { return perspective; } class Viewport* GetViewport() { return viewport; } private: static Context* instance; private: class Perspective* perspective; class Viewport* viewport; class Camera* camera; };
Context.cpp
#include "stdafx.h" #include "Main.h" #include "Systems/Window.h" #include "GridDemo.h" void Main::Initialize() { Push(new GridDemo()); } void Main::Ready() { } void Main::Destroy() { for (IExecute* exe : executes) { exe->Destroy(); SafeDelete(exe); } } void Main::Update() { for (IExecute* exe : executes) exe->Update(); } void Main::PreRender() { for (IExecute* exe : executes) exe->PreRender(); } void Main::Render() { for (IExecute* exe : executes) exe->Render(); } void Main::PostRender() { for (IExecute* exe : executes) exe->PostRender(); } void Main::ResizeScreen() { for (IExecute* exe : executes) exe->ResizeScreen(); } void Main::Push(IExecute * execute) { executes.push_back(execute); execute->Initialize(); } int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR param, int command) { D3DDesc desc; desc.AppName = L"D3D Game"; desc.Instance = instance; desc.bFullScreen = false; desc.bVsync = false; desc.Handle = NULL; desc.Width = 1280; desc.Height = 720; desc.Background = Color(0.3f, 0.3f, 0.3f, 1.0f); D3D::SetDesc(desc); Main* main = new Main(); WPARAM wParam = Window::Run(main); SafeDelete(main); return wParam; }
실행화면

'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 016 Texture (0) | 2023.01.14 |
---|---|
[DirectX11] 015 Cube (0) | 2023.01.13 |
[DirectX11] 012 Grid (1) | 2023.01.10 |
[DirectX11] 011 Index (0) | 2023.01.10 |
[DirectX11] 010 World (0) | 2023.01.09 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 016 Texture
[DirectX11] 016 Texture
2023.01.14 -
[DirectX11] 015 Cube
[DirectX11] 015 Cube
2023.01.13 -
[DirectX11] 012 Grid
[DirectX11] 012 Grid
2023.01.10 -
[DirectX11] 011 Index
[DirectX11] 011 Index
2023.01.10목차 Index Index를 활용한 사각형 그리기 0 1 2 2 1 3 순서로 그린다. IndexDemo 코드 10_World.fx 코드는 이전글과 동일 IndexDemo.h 더보기 #pragma once #include "Systems/IExecute.h" class IndexDemo : public IExecute { public: virtual void Initialize() override; virtual void Ready() override {} virtual void Destroy() override; virtual void Update() override; virtual void PreRender() override {} virtual void Render() override; virtua…
댓글을 사용할 수 없습니다.