DOTY
DirectX11. 5) Texture 본문
이전의 Color Shader과 비슷한 Texture Shader로 코드가 거의 비슷하지만 Color관련 부분만 Texture로 바뀌었다.
Texture은 RGBA의 정보가 담겨있는 .tga(TARGA)파일을 사용하고 픽셀의 위치는 0 ~ 1 사이의 float형식으로 표현된다.
※ Texture Class가 Framework에 추가된다.
1. TextureShaderClass.h
#pragma once
#ifndef _TEXTURESHADERCLASS_H_
#define _TEXTURESHADERCLASS_H_
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
class TextureShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
public:
TextureShaderClass();
TextureShaderClass(const TextureShaderClass&);
~TextureShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
ID3D11SamplerState* m_sampleState;
};
#endif
ColorShaderClass와 큰 차이가 없지만 Render, SetShaderParameters에서 매개변수가 추가되었다.
또한 m_samplerState를 추가했는데 이는 텍스쳐 샘플링을 정의하기 위해 사용된다.
1-1. Texture.vs
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
PixelInputType TextureVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.tex = input.tex;
return output;
}
Color의 VertexShader과 큰 차이가 없다. 다만 float4 Color 대신 float2 tex가 쓰이게 된다. 이를 MVP 변환을 거치고 반환하게 된다.
1-2. Texture.ps
Texture2D shaderTexture : register(t0);
SamplerState SampleType : register(s0);
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
float4 TexturePixelShader(PixelInputType input) : SV_TARGET
{
float4 textureColor;
textureColor = shaderTexture.Sample(SampleType, input.tex);
return textureColor;
}
Color의 PixelShader과는 조금 차이가 있다.
Texture2D shaderTexture : register(t0): 변수 이름은 shaderTexture로 2D 텍스쳐를 나타내는 데이터 형식이다. GPU 레지스터의 t0(텍스쳐 슬롯의 인덱스)에 바인딩 하겠다는 의미.
SamplerState SampleType : register(s0) : 변수 이름은 SampleType으로 샘플러 상태를 나타내는 변수이다. 샘플러 레지스터의 s0(샘플러 슬롯의 인덱스)에 바인딩 하겠다는 의미.
※텍스처 샘플러 : 텍스처를 픽셀 단위로 읽어온다는 의미. 텍스처의 텍셀(픽셀의 텍스처 버전)에는 이미지의 색상 정보를 가지고 있다.
1-3. Initialize Shader
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
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_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
// Create the texture sampler state.
result = device->CreateSamplerState(&samplerDesc, &m_sampleState);
if (FAILED(result))
{
return false;
}
return true;
ColorShaderClass의 Initialize Shader과 차이가 없지만 위의 코드가 추가되었다. 샘플러가 추가됐기 때문에 텍스처 샘플러의 상태를 생성하는 코드도 추가되었다. 필터링 방법이나 주소 모드 등 설정한다.
기타 다른 변경점은 Color과 관련된 부분이 모두 Texture로 변경되었다. 또한 픽셀 셰이더에서 텍스터를 포함하도록 변경된다.
2. TextureClass.h
#pragma once
#ifndef _TEXTURECLASS_H_
#define _TEXTURECLASS_H_
#include <d3d11.h>
#include <stdio.h>
class TextureClass
{
private:
struct TargaHeader
{
unsigned char data1[12];
unsigned short width;
unsigned short height;
unsigned char bpp;
unsigned char data2;
};
public:
TextureClass();
TextureClass(const TextureClass&);
~TextureClass();
bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*);
void Shutdown();
ID3D11ShaderResourceView* GetTexture();
private:
bool LoadTarga32Bit(char*, int&, int&);
private:
unsigned char* m_targaData;
ID3D11Texture2D* m_texture;
ID3D11ShaderResourceView* m_textureView;
};
#endif
Targa파일을 더욱 읽기 쉽게 하기위해 Targe파일 구조체를 정의한다. m_targaData는 Targe파일 관련 데이터들를 가진다.
2-1. Initialize
Targa파일의 이름을 입력으로 사용한다. Targa 데이터를 배열에 로드하고 텍스쳐를 만들어 데이터를 로드한다. 단, Targa는 기본적으로 거꾸로 되어 있기 때문에 반전시켜줘야한다. 처음 CreateTexture2D함수를 사용하여 텍스쳐를 만들때는 비어있지만 UpdateSubresource를 통해 텍스쳐에 업데이트 하도록 한다.
※ MIP맵 : 텍스처의 미리 준비된 다중 해상도 버전. 텍스처의 원본 이미지를 다양한 해상도로 준비된 상태라고 보면 된다. 텍스처를 생성한 후에 deviceContext->GenerateMips를 통해 MIP맵을 생성할 수도 있다. 시각적 부드러움과 성능 향상에 도움이 되고 특히 먼 거리에 있는 객체에 유용하다. 하지만 다중 해상도 버전이기 때문에 메모리와 생성시간 등을 고려해야한다.
2-2. Shutdown
Initialize에서 사용한 텍스처 데이터들을 해제한다.
2-3. GetTexture
렌더링에 필요한 모든 셰이더의 텍스처 뷰에 쉽게 액세스할 수 있도록 하는 함수.
2-4. LoadTarga32Bit
Targa의 이미지는 거꾸로 되어있기 때문에 한번 뒤집어줘야한다. LoadTarga32Bit에서 이를 처리한다.
'DirectX' 카테고리의 다른 글
DirectX11. check 1) Back-Face culling (0) | 2023.06.14 |
---|---|
DirectX11. 6) Light (0) | 2023.06.14 |
DirectX11. 4) Buffer, Shader II (0) | 2023.06.12 |
DirectX11. 3) Buffer, Shader I (0) | 2023.06.11 |
DirectX11. 2) D3D11 Initialize (1) | 2023.06.09 |