37 Texture

gksrudtlr
|2025. 1. 20. 18:24

GeometryHelper Class

  • 전 시간까지 사각형을 그렸고 이제 UV좌표계를 이용해 물체에 텍스처를 붙일것이다
  • 하지만 그 전에 모양을 여러개 만들어 볼 것이다
  • Position과 UV를 Shader로 넘겨주는 VertexTextureData를 가지고 사각형, 큐브, 구, 그리드를 그려볼 것이다
class GeometryHelper
{
public:
	...

	static void CreateQuad(shared_ptr<Geometry<VertexTextureData>> geometry);
	static void CreateCube(shared_ptr<Geometry<VertexTextureData>> geometry);
	static void CreateSphere(shared_ptr<Geometry<VertexTextureData>> geometry);
	static void CreateGrid(shared_ptr<Geometry<VertexTextureData>> geometry);
};

GeometryHelper.cpp
...
void GeometryHelper::CreateQuad(shared_ptr<Geometry<VertexTextureData>> geometry)
{
	vector<VertexTextureData> vertexData;
	vertexData.resize(4);

	vertexData[0].position = Vec3(-0.5f, -0.5f, 0.0f);
	vertexData[0].uv = Vec2(0.0f,1.0f);
	vertexData[1].position = Vec3(-0.5f, 0.5f, 0.0f);
	vertexData[1].uv = Vec2(0.0f, 0.0f);
	vertexData[2].position = Vec3(0.5f, -0.5f, 0.0f);
	vertexData[2].uv = Vec2(1.0f,1.0f);
	vertexData[3].position = Vec3(0.5f, 0.5f, 0.0f);
	vertexData[3].uv = Vec2(1.0f,0.0f);
	geometry->SetVertices(vertexData);

	vector<uint32> indices = { 0,1,2,2,1,3 };
	geometry->SetIndices(indices);
}
...
  • 일단 먼저 사각형을 Texture로 채워 그려 넣을 것이다
  • 그래서 VertexDat.h에 uv를 사용하는 구조체 중 position과 uv만을 사용하는 VertexTextureData를 이용할 것이다
  • 이전에 만든 CreateQuad()안에 있는 내용을 복사해 붙여넣어준 뒤 VertexTextureData로 바꿔준다
  • 이때 Color가 아닌 UV로 맵핑을 하기 위해선 UV 좌표계에 대해 생각해 봐야한다

  • 사진처럼 UV좌표계는 0,0부터 오른쪽 아래로 갈수록 1로 커지며, 0~1사이의 값을 갖는다
  • 이를 우리가 만든 도형의 좌표와 일치시켜야 그 도형에 맞게 Texture가 들어갈 것이다
  • 즉 VertexData 배열에 position과 UV과표계를 일치시켜 UV를 넣어주면 되는 것이다
  • 예를 들어 VertexData[0].position은 첫번째 그려질 좌표로(-0.5, -0.5) 좌표를 가지며, 왼쪽, 아래에 위치하고 있는데, 이를 UV 좌표로 보면 (0,1)지점 이므로 VertexData[0].uv에 Vec2(0.0f,1.0f)좌표를 저장하는 식으로 매핑을 해준다

Shader

  • Shader는 이전과 동일하지만 Texture와, uv를 사용하므로 이들과 SamplerState가 추가 될 것이다
matrix World;
matrix View;
matrix Projection;
Texture2D Texture0;

struct VertexInput
{
    float4 position : POSITION;
    float2 uv : TEXCOORD;
};

struct VertexOutput
{
    float4 position : SV_POSITION;
    float2 uv : TEXCOORD;
};

VertexOutput VS(VertexInput input)
{
    VertexOutput output;
    output.position = mul(input.position, World);
    output.position = mul(output.position, View);
    output.position = mul(output.position, Projection);
    output.uv = input.uv;

    return output;
}

SamplerState Sampler0;

float4 PS(VertexOutput input) : SV_TARGET
{
    return Texture0.Sample(Sampler0, input.uv);
}

RasterizerState FillModeWireFrame
{
    FillMode = Wireframe;
};

technique11 T0
{
    pass P0
    {
        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }

    pass P1
    {
        SetRasterizerState(FillModeWireFrame);
        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }
};
  • Texture2D로 Texture0 변수를 만들어 CPU에서 이 이름으로 GPU로 넘겨줄 수 있게 이름을 지정해준다
  • VertexInput/Output 함수에선 Color가 아닌 UV를 사용할 것이므로 float2 uv : TEXCOORD로 변경해준다
  • VS()에서도 color를 넘겨주는 것을 uv로 바꿔주면 된다
  • 이때 PS()로 넘어가기 전 SamplerState를 만들어 이를 적용할 수 있도록 해준다
    • SamplerState : Texture를 UV 매핑시 이 과정을 통해 텍스터 데이터를 샘플링하고 필터링하는 방식을 정의하는데, 이는 매핑 과정에서 UV좌표가 Texture Data에 정확히 일치하지 않거나 Texture의 해상도와 화면의 픽셀 해상도가 달라질 때 이를 처리하는 방법을 지정하는 것이다
  • 이를 만들어 줬다면 PS()에서 Texture Data를 저장했던 Texture0을 이용해 Sample()을 호출해 SamplerState와 uv를 넘겨 매핑을 하게 해준다

TextureDemo Class

  • 우리는 저번 프로젝트에서 Texture를 Load시켜 사용하기 위해 Texture Class를 만들어 Texture를 Load하고, 이를 Poxel Shader에서 사용하기 위해 SRV(ShaderResourceView)를 만들어줬다
  • 하지만 이 방법은 동일한 Texture를 사용하게 된다면 여러번 Texture 파일을 Load하기 때문에 ResourceManager를 만들어 Resource 파일이 있는지 없는지 판단해 없다면 map에 key와 value로 저장하고, 존재한다면 key값을 통해 가져오는 식으로 만들어놨었다
class TextureDemo : public IExecute
{
public:
	void Init() override;
	void Update() override;
	void Render() override;

private:
	shared_ptr<Shader> shader;
	//밑에 3개는 Mesh로 묶어줄 예정
	shared_ptr<Geometry<VertexTextureData>> geometry;
	shared_ptr<VertexBuffer> vertexBuffer;
	shared_ptr<IndexBuffer> indexBuffer;

	Matrix world = Matrix::Identity;

	shared_ptr<GameObject> m_pCamera;
	shared_ptr<Texture> m_pTexture;
};

TextureDemo.cpp

void TextureDemo::Init()
{
	shader = make_shared<Shader> (L"05.Texture.fx");

	geometry = make_shared<Geometry<VertexTextureData>>();
	GeometryHelper::CreateQuad(geometry);

	vertexBuffer = make_shared<VertexBuffer>();
	vertexBuffer->Create(geometry->GetVertices());

	indexBuffer = make_shared<IndexBuffer>();
	indexBuffer->Create(geometry->GetIndices());

	m_pCamera = make_shared<GameObject>();
	m_pCamera->GetOrAddTransform();
	m_pCamera->AddComponent(make_shared<Camera>());
	m_pCamera->AddComponent(make_shared<CameraScript>());

	m_pCamera->GetTransform()->SetPosition(Vec3(0, 0, -10));

	m_pTexture = RESOURCES->Load<Texture>(L"Veigar", L"..\\Resources\\Textures\\veigar.jpg");
}

void TextureDemo::Update()
{
	m_pCamera->Update();
}

void TextureDemo::Render()
{
	shader->GetMatrix("World")->SetMatrix((float*)&world);
	shader->GetMatrix("View")->SetMatrix((float*)&Camera::S_MatView);
	shader->GetMatrix("Projection")->SetMatrix((float*)&Camera::S_MatProjection);
	shader->GetSRV("Texture0")->SetResource(m_pTexture->GetComPtr().Get());

	uint32 stride = vertexBuffer->GetStride();
	uint32 offset = vertexBuffer->GetOffset();
	DC->IASetVertexBuffers(0, 1, vertexBuffer->GetComPtr().GetAddressOf(), &stride, &offset);

	DC->IASetIndexBuffer(indexBuffer->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);

	shader->DrawIndexed(0, 0, indexBuffer->GetCount());
}
  • 이전 프로젝트에서 이런저런 과정을 통해 쉽게 Texure를 매핑할 수 있도록 만들었기 때문에 현재 프로젝트에선 쉽게 사용이 가능하다
  • 04.CameraDemo 파일을 복사해 이름을 TextureDemo로 바꿔준 뒤 Texture를 사용하기 위해 Texture 객체를 만들어준다
  • Init()에서는 m_pTexture에 미리 컴파일된 헤더에서 메크로로 만든 RsourceManage를 불러오는 RESOURCE를 이용해 Load함수를 호출해준다
  • 이때 이 함수는 Template로 이루어져 있으므로 Texture라는 것을 알려주고, Resource 파일들을 저장해 놓은 파일 위치와 key 값을 Load()에 넘겨주어 그 위치에 key값으로 된 파일이 저장되어 있는지 판단해 저장되어있다면 그 값을 return하고, 그렇지 않다면 저장 후 return해준다
  • Render()에서도 shader->GetSRV()를 콜하여 Shader 파일에서 만든 이름으로 SRV를 가져와 그 안에 SetResource()를 통해 m_pTexture의 주소를 넘겨 사용하고자하는 Texture를 Sahder에서 사용할 수 이도록 해준다

결과

  • 결과를 보면 우리가 그리는 물체에 정확히 Texture가 매핑되어 들어간 것을 볼 수 있

'DirectX' 카테고리의 다른 글

38 Geometry  (0) 2025.03.10
36 Camera  (0) 2025.01.20
35 Constant Buffer  (0) 2025.01.16
34 사각형 띄우기  (0) 2025.01.16
33 새 프로젝트 시작  (0) 2025.01.16