응애맘마조

230904 강의 본문

공부/3D강의

230904 강의

TH.Wert 2023. 9. 4. 19:29

큐브맵 텍스쳐에 대해 강의했습니다. 반사가 되어도 잘 나타날 수 있도록 여섯 방면에서 구현하는 것입니다.

(며칠 전부터 솔루션에서 실행하고 프로그램 종료 시 오류가 나는 현상이 발견되었습니다. 조치되는 대로 내용 작성하겠습니다.)

#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 클래스도 만들었지만 아직 완성되지 않아서 프로그램에서 확인은 할 수 없습니다. 내일 완성될 예정이므로 내일 작성하겠습니다.

 

읽어주셔서 감사합니다.

'공부 > 3D강의' 카테고리의 다른 글

230906 강의  (0) 2023.09.06
230905 강의  (0) 2023.09.05
230901 강의  (0) 2023.09.01
230831 강의  (0) 2023.08.31
230830 강의  (0) 2023.08.30
Comments