응애맘마조
230904 강의 본문
큐브맵 텍스쳐에 대해 강의했습니다. 반사가 되어도 잘 나타날 수 있도록 여섯 방면에서 구현하는 것입니다.
(며칠 전부터 솔루션에서 실행하고 프로그램 종료 시 오류가 나는 현상이 발견되었습니다. 조치되는 대로 내용 작성하겠습니다.)
#pragma once
class CubeRenderTarget
{
protected:
int width, height;
ID3D11Texture2D* rgb;
ID3D11Texture2D* depth;
ID3D11RenderTargetView* rgbTarget;
ID3D11DepthStencilView* depthTarget;
ID3D11ShaderResourceView* rgbResource;
ID3D11SamplerState* sampler;
//창사이즈 조절
void CreateBackBuffer(float width, float height);
void DeleteBackBuffer();
public:
CubeRenderTarget(UINT width = 256,
UINT height = 256);
~CubeRenderTarget();
virtual void SetTarget(Color clear = Color(0, 0, 0, 1));
virtual void SetRGBTexture(int slot);
virtual void ResizeScreen(float width, float height);
};
#include "framework.h"
void CubeRenderTarget::CreateBackBuffer(float width, float height)
{
DXGI_FORMAT rtvFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
//Create rgb
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = width;
desc.Height = height;
desc.ArraySize = 6;
desc.Format = rtvFormat;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
Check(D3D->GetDevice()->CreateTexture2D(&desc, NULL, &rgb));
}
//Create rgb Target
{
D3D11_RENDER_TARGET_VIEW_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
desc.Format = rtvFormat;
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
desc.Texture2DArray.ArraySize = 6;
Check(D3D->GetDevice()->CreateRenderTargetView(rgb, &desc, &rgbTarget));
}
//Create rgb SRV
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
desc.Format = rtvFormat;
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
desc.TextureCube.MipLevels = 1;
Check(D3D->GetDevice()->CreateShaderResourceView(rgb, &desc, &rgbResource));
}
DXGI_FORMAT dsvFormat = DXGI_FORMAT_D32_FLOAT;
//Create depth Texture
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = width;
desc.Height = height;
desc.ArraySize = 6;
desc.Format = dsvFormat;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
Check(D3D->GetDevice()->CreateTexture2D(&desc, NULL, &depth));
}
//CreateDSV
{
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
desc.Format = dsvFormat;
desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
desc.Texture2DArray.ArraySize = 6;
Check(D3D->GetDevice()->CreateDepthStencilView(depth, &desc, &depthTarget));
}
this->width = (float)width;
this->height = (float)height;
}
void CubeRenderTarget::DeleteBackBuffer()
{
SafeRelease(rgbTarget);
SafeRelease(depthTarget);
SafeRelease(rgbResource);
SafeRelease(rgb);
SafeRelease(depth);
}
CubeRenderTarget::CubeRenderTarget(UINT width, UINT height)
{
CreateBackBuffer(width, height);
{
D3D11_SAMPLER_DESC SamplerDesc;
SamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
SamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
SamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
SamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
SamplerDesc.MipLODBias = 0.0f;
SamplerDesc.MaxAnisotropy = 1;
SamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
SamplerDesc.MinLOD = -FLT_MAX;
SamplerDesc.MaxLOD = FLT_MAX;
D3D->GetDevice()->CreateSamplerState(&SamplerDesc, &sampler);
}
}
CubeRenderTarget::~CubeRenderTarget()
{
DeleteBackBuffer();
}
void CubeRenderTarget::SetTarget(Color clear)
{
D3D->SetRenderTarget(rgbTarget, depthTarget);
D3D->Clear(clear, rgbTarget, depthTarget);
}
void CubeRenderTarget::SetRGBTexture(int slot)
{
D3D->GetDC()->PSSetShaderResources(slot, 1, &rgbResource);
D3D->GetDC()->PSSetSamplers(slot, 1, &sampler);
}
void CubeRenderTarget::ResizeScreen(float width, float height)
{
if (width < 1 || height < 1)
return;
this->width = width;
this->height = height;
DeleteBackBuffer();
CreateBackBuffer(width, height);
}
여기서 CubeRenderTarget을 지정하는 클래스를 만들었습니다.
#pragma once
class Environment : public CubeRenderTarget
{
private:
static ID3D11Buffer* camBuffer;
struct GSCamBuffer
{
Matrix Views[6];
Matrix Projection;
} desc;
Viewport viewport;
public:
Vector3 position;
float fov, nearZ, farZ;
Environment(UINT width = 256, UINT height = 256);
~Environment();
shared_ptr<Texture> environment;
static void CreateStaticMember();
static void DeleteStaticMember();
virtual void ResizeScreen(float width, float height);
void RenderDetail();
void SetTarget(Color clear = Color(0, 0, 0, 1));
void SetRGBTexture(int slot);
void ResizeScreen(float width, float height);
};
#include "framework.h"
Environment::Environment(UINT width, UINT height)
: CubeRenderTarget(width, height)
{
environment = make_shared<Texture>();
viewport.width = (float)width;
viewport.height = (float)height;
fov = 90.0f * TORADIAN;
nearZ = 0.001f;
farZ = 10000.0f;
}
Environment::~Environment()
{
SafeReset(environment);
}
void Environment::CreateStaticMember()
{
{
D3D11_BUFFER_DESC desc = { 0 };
desc.ByteWidth = sizeof(GSCamBuffer);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;//상수버퍼
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, NULL, &camBuffer);
assert(SUCCEEDED(hr));
}
}
void Environment::DeleteStaticMember()
{
SafeRelease(camBuffer);
}
void Environment::ResizeScreen(float width, float height)
{
viewport.width = (float)width;
viewport.height = (float)height;
CubeRenderTarget::ResizeScreen(width, height);
}
void Environment::RenderDetail()
{
if (ImGui::SliderInt("TextureWidth", &width, 1, 2000))
{
ResizeScreen(width, height);
}
if (ImGui::SliderInt("TextureHeight", &height, 1, 2000))
{
ResizeScreen(width, height);
}
}
void Environment::SetTarget(Color clear)
{
//Create Views
{
float x = position.x;
float y = position.y;
float z = position.z;
struct LookAt
{
Vector3 LookAt;
Vector3 Up;
} lookAt[6];
lookAt[0] = { Vector3(x + 1.0f, y, z), Vector3(0, 1.0f, 0) };
lookAt[1] = { Vector3(x - 1.0f, y, z), Vector3(0, 1.0f, 0) };
lookAt[2] = { Vector3(x, y + 1.0f, z), Vector3(0, 0, -1.0f) };
lookAt[3] = { Vector3(x, y - 1.0f, z), Vector3(0, 0, +1.0f) };
lookAt[4] = { Vector3(x, y, z + 1.0f), Vector3(0, 1.0f, 0) };
lookAt[5] = { Vector3(x, y, z - 1.0f), Vector3(0, 1.0f, 0) };
for (UINT i = 0; i < 6; i++)
{
desc.Views[i] =
Matrix::CreateLookAt(position, lookAt[i].LookAt, lookAt[i].Up);
desc.Views[i] = desc.Views[i].Transpose();
}
}
desc.Projection =
Matrix::CreatePerspectiveFieldOfView(fov, width / height, nearZ, farZ);
desc.Projection = desc.Projection.Transpose();
D3D->GetDC()->RSSetViewports(1, viewport.Get11());
{
D3D11_MAPPED_SUBRESOURCE mappedResource;
D3D->GetDC()->Map(camBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy_s(mappedResource.pData, sizeof(GSCamBuffer), &desc, sizeof(GSCamBuffer));
D3D->GetDC()->Unmap(camBuffer, 0);
D3D->GetDC()->GSSetConstantBuffers(4, 1, &camBuffer);
}
}
void Environment::SetRGBTexture(int slot)
{
}
환경매핑을 할 Enviroment 클래스도 만들었지만 아직 완성되지 않아서 프로그램에서 확인은 할 수 없습니다. 내일 완성될 예정이므로 내일 작성하겠습니다.
읽어주셔서 감사합니다.
Comments