평생 공부하는 빠타박스 블로그 : Learning is Happiness
article thumbnail
SMALL

ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고및 공부자료로 만들어진 내용임을 밝힙니다.)
전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다

이전 자료) https://ppatabox.tistory.com/31

 

 

목차-

1) Texture

 

 




이미지는 Pixel 단위 인데. 그래서 pixelshader 에서 다룬다.

정점 4개를 이용해서 사각형을 그린 후 생각해보자 

 

VS = 정점 4개를 채우고

RS = 그 사이를 채운다 

 

이 사이의 간격이 100이라 치고 

그럼 텍스쳐 스크린은 얼마인지 모른다

비율에 대한 또하나의 좌표가 필요하다.

기준이 좌하단이라고 할때

 

일반적인 2D 는 텍스쳐를 뛰운 좌표 좌상단 (0, 0) 그대로 아래로 (0, 1)

(두 좌표간의 사이의 100을 한장으로 치겠다는 의미의 좌표 2면 2장 0.5면 반장 ) 

 

우리가 시스템을 처리하고 100인지 아닌지 모른다.  우상단은 (1, 0) 우 하단이 (1, 1) 

 

 

ex_wstring textureFile = L"

CreateFile A / W 붙어 있는게 있는데 

A = ANSI 1바이트 권 (아스키 코드 생각하면 됨)(영어권)

2바이트 이상권 Wide char는 (UNICODE)유니코드 라고 부른다. (비영어권) 

전세계의 문자를 다 담을 수 있도록 제공 하고 있음  

각 나라마다 다르다 (동남아, 인도, 아랍권, 태국, 중국 등등) 

근데 문자조합이 제일 많은 나라가 우리나라다(표현자체가 너무 많아서 그럴 수 있음) 

 

전부다 2바이트로 처리하기가 용량이크다 

데이터를 주고 받아야 하는 상황에서 인터넷이 빠르면 상관없는데 

글로벌 작업을 할때 다른나라의 인터넷 속도가 느린것을 판단해서 작업을 해야함

 

2바이트 표시 방법 두가지

1) MBCS : 영문이나 아스키코드 그건 1바이트 처리 하고 나머지 문자열은 2바이트 

2) UNICODE : 무조건 2바이트로 처리하겠다 

 

==

표기법 

Ansi : " " 

MBCS  : L""

UNICODE : TEXT(" ")

 

NULL =  0 으로 표기 되어있고 조금 남아있는 개념 ()공간 있음)

nullptr = 댕글리 포인트 까지 체크 할려면 완전 없는 개념  (공간 자체가 없는것) 

 

 


 

ANSI 문자와 유니코드 문자

  • ANSIchar c = 'A'char szBuffer[100] = "A String"
  • // 99개의 8비트 문자와 8비트 문자열 종결 문자(0)
  • // 8비트 문자
  •  
  • 유니코드wchar_t c = L'A'Wchar_t szBuffer[100] = L"A String
  • // 99개의 16비트 문자와 16비트 문자열 종결 문자(0)
  • // 16비트 문자

컴파일 시 ANSI 문자나 유니코드 문자를 사용하도록 변경 가능하게 소스코드를 작성하는 것도 가능하다.

윈도우 내에서 제공해주는 유니코드 함수와 ANSI함수가 있긴 한데 다루진 않겠음 

그외로 따로 표가 있음 

 

문자 인코딩과 유니코드(ASCII, ANSI, EUC-KR, CP949, UTF-8)

웹 개발에 대한 원론을 다시금 공부하다보니 가장 기초적인 부분에서 꼭 짚고 넘어가야 하는 주제가 나타났다. 여느 때와 다름없이 구글링 신공을 펼쳤으나 오히려 너무 많은 정보로 인해 혼란

daniiieee.tistory.com


 

Textrue에띄울 이미지 

Texture.cpp / h 를 프로젝트 폴더에 넣어주자 wstring textureFile = L"../_Textures/" + file; 자신의 폴더 상대 경로 설정  현재 폴더안에 한칸 위에 _Textures폴더를 만들어주자 이미지를 이곳에 넣어주자  

치다보면 나오는데 뒤에 A W

A : ANSIW : unicode아무것도 안치면 현재 프로젝트 설정에 따른것에 잡힘(현재는 unicode / D3DX11 임) 

 

wstring textureFile = L"../_Textures/" + file;


HRESULT hr = D3DX11CreateShaderResourceViewFromFile(디바이스 , 소스파일정의(LPCW long point char배열로 넘겨줌)  , NULL이미지(모름), NULL(쓰레드펌프:DX11특징을 나누는 것 멀티쓰레드 렌더링을 다루는 부분(실무가도 5년차 까지 안건드림어려워서), &srv(ID3D11Resource 2차포인터로 주셈) , NULL(Hresult 주소로) );
assert(SUCCEEDED(hr)); 

 

RELEASE / DELETE 매크로 

 

Texture.cpp

#include "stdafx.h"
#include "Texture.h"

Texture::Texture(wstring file)
{
	vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXVECTOR2(0, 1));
	vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
	vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(1, 1));

	vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(1, 1));
	vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
	vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXVECTOR2(1, 0));


	D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
	{
		"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
		"UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0
	};
	UINT elementCount = ARRAYSIZE(layoutDesc);


	shader = new Shader(L"effect.hlsl");
	shader->CreateInputLayout(layoutDesc, elementCount);

	vertexBuffer = new VertexBuffer(vertices, 6, sizeof(Vertex));
	wvpBuffer = new ConstantBuffer(&wvp, sizeof(WVP));


	D3DXMatrixIdentity(&wvp.World);
	D3DXMatrixIdentity(&wvp.View);
	D3DXMatrixIdentity(&wvp.Projection);


	D3DXVECTOR3 eye(0, 0, -1);
	D3DXVECTOR3 lookAt(0, 0, 0);
	D3DXVECTOR3 up(0, 1, 0);

	D3DXMatrixLookAtLH(&wvp.View, &eye, &lookAt, &up);
	D3DXMatrixTranspose(&wvp.View, &wvp.View);

	D3DXMatrixOrthoOffCenterLH(&wvp.Projection, 0, (float)Width, 0, (float)Height, -1, +1);
	D3DXMatrixTranspose(&wvp.Projection, &wvp.Projection);


	wstring textureFile = L"../_Textures/" + file; 
	HRESULT hr = D3DX11CreateShaderResourceViewFromFile(Device, textureFile.c_str(), NULL, NULL, &srv, NULL);
	assert(SUCCEEDED(hr)); 
}

Texture::~Texture()
{
	SAFE_RELEASE(srv);//new로 할당하는게 아니니까 Release 

	SAFE_DELETE(vertexBuffer);
	SAFE_DELETE(wvpBuffer);

	SAFE_DELETE(shader);
}

void Texture::Position(float x, float y, float z)
{
	Position(D3DXVECTOR3(x, y, z));
}

void Texture::Position(const D3DXVECTOR3 & position)
{
	this->position = position;
}

void Texture::Position(D3DXVECTOR3 * position)
{
	memcpy(position, this->position, sizeof(D3DXVECTOR3));
}

void Texture::Scale(float x, float y, float z)
{
	Scale(D3DXVECTOR3(x, y, z));
}

void Texture::Scale(const D3DXVECTOR3 & scale)
{
	this->scale = scale;
}

void Texture::Scale(D3DXVECTOR3 * scale)
{
	memcpy(scale, this->scale, sizeof(D3DXVECTOR3));
}

void Texture::Render()
{
	D3DXMATRIX S, T;

	D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
	D3DXMatrixTranslation(&T, position.x, position.y, position.z);

	wvp.World = S * T;
	D3DXMatrixTranspose(&wvp.World, &wvp.World);

	
	DeviceContext->PSSetShaderResources(0, 1, &srv); //(Device)GPU를 다루는것 이미지는 픽셀쉐이더
	DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	shader->Render();
	vertexBuffer->Render();
	
	wvpBuffer->Render();

	DeviceContext->Draw(6, 0);
}

 

Uv를 받을 수 있도록 쉐이더를 수정하자. Effect.hlsl로 들어가서 

 

이번에는 정점 구조가 2개 들어오고 

원래 텍스쳐를 처리하기 위해서 samplerstate가 필요함 (2편에서 다루겠음) 

 

Effect.hlsl

struct VertexInput
{
    float4 Position : POSITION0;
    float2 Uv : UV0;//레이아웃에 있는 것과 동일(Texture.h) 
};

struct PixelInput
{
    float4 Position : SV_POSITION;
    float2 Uv : UV0; //Uv그대로 넘겨주기 위함 pixelshader로 
};

cbuffer VS_Wvp : register(b0) //뒤에 b0 : buffer | 0 slot번호 
{
    matrix World;
    matrix View;
    matrix Projection;
}

PixelInput VS(VertexInput input)
{
    PixelInput output;
    
    output.Position = mul(input.Position, World);
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);
    output.Uv = input.Uv; //받은 Uv를 pixelshader로 넘겨주기 ]]

    return output;
}


SamplerState Sampler : register(s0); //텍스쳐를 처리하기 위한2편에서 다루겠음 s0 : sampler | 0 slot번호 의미
Texture2D Texture : register(t0);

float4 PS(PixelInput input) : SV_TARGET
{
    return Texture.Sample(Sampler, input.Uv); //우리가 넣어준 2D좌표 
}

 

 

Main.cpp

#include "stdafx.h"
#include "System/Device.h"
#include "Utilities/Math.h"
#include "Text.h"
#include "Rect.h"
#include "Texture.h" //텍스쳐 만든거 추가 

Texture* texture = NULL; // 초기화 원래 nullptr써야 됨 
void InitScene()
{
	texture = new Texture(L"SingleMario.png"); // 마리오 png 파일 
	texture->Position(200, 200); //위치 포지션
	texture->Scale(100, 100); // 크기 지정 
}

void DestroyScene()
{
	SAFE_DELETE(texture); 
}

void Update()
{
	
}

void Render()
{	
	texture->Render(); //텍스쳐 렌더
}

 

 

 

 

잘나오는 것을 볼 수 있다.

 

잘보면 반투명 처리 된거 같은데 그게아니라

마리오PNG바탕이 흰색이라서 그런다.

 

 

 

 

 

 

Device.cpp 로 넘어가서

Ctrl + G키를 눌러서 해당 번호로 이동할 수 있다)

보이는 바탕화면 색깔 조정 

D3DXCOLOR background 부분이 바탕화면인데 

색상을 검은색으로 바꾸고 보니 

 

 

마리오가 정확히 어떻게 띄어져 있는지 볼 수 있다.

 

 

 

 

 

 

다음시간에 sampler에 대해 알아보겠다.

 

 

2) Texture 추가 설명

https://kblog.popekim.com/2011/12/03-part-1.html

 

 

 

D3D와 OpenGL에서 다르게 처리 된다고 말하고 어떤 사람은 동일 하다고 얘기

또는 텍스쳐가 로드 될때 수직으로 뒤집을 필요가 있다고 말한다.

 

고려해야 할 2가지 사항 

1. 텍스쳐가 메모리에 저장되는 방식

2. UV좌표를 어디에 두었는지

 

D3D


  1. 텍스쳐는 메모리에서 하향식 이다. 텍스처 메모리의 첫번째 바이트는 이미지의 왼쪽 상단
  2. UV좌표는 하향식이다. (0, 0) 은 텍스쳐의 왼쪽 상단 

 

OpenGL

 


  1. 텍스쳐는 메모리의 상향식 이다, 따라서 텍스쳐 메모리의 첫번째 바이트는 이미지 왼쪽 상단
  2. UV좌표는 상향식 , (0 , 0) 은 텍스쳐 왼쪽 하단 

glTexImage2D 에 대한 것을 참조해라 

https://heinleinsgame.tistory.com/9

 

만약 데이터가 D3D와 OpenGL에서 다르게 처리된 것이 사실 이라면

데이터가 실제 하드웨어에 도달하기 전에 어딘가에서 텍스쳐 데이터나 UV좌표를 뒤집어야 하므로

이것은 .. 미친얘기이다. 따라서 운전자는 항상 데이터를 동일한 방식으로 처리해야 한다. 

 

모든 텍스쳐와 UV좌표가 OpenGl규칙에 따라 거꾸로 되어 있다는 것

대안은 업로드 될때 모든 텍스쳐를 뒤집고(실제 OpenGL방식) 로드 될때 모든 UV좌표도 뒤집는 것

 

 

 

 

 

 

 

 

 

DirectX 버텍스 버퍼 맵핑, 인덱스 버퍼 맵핑

1. 버텍스버퍼 맵핑 - 폴리곤을 이루는 정점과 텍스쳐위의 픽셀과 대응 시켜 맵핑 하는 방식 - 텍스쳐의 U...

blog.naver.com

 

 

10. DirectX : Texture mapping(텍스쳐 맵핑) 과 투명처리

텍스쳐 매핑이미지를 3D 공간 영역으로 매핑 •uv 좌표 구조 텍스쳐를 위한 버텍스 구조 •버텍...

blog.naver.com

 

 

 

다음시간)

 

[C++]DirectX 샘플링 / sampler

ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다. 본 내용은 똑같이 사용할 수 없음을 알립니다. (참고 및 공부자료로 만들어진 내용임을 밝힙니다.) 전 과정에 대해 이해를 해야 다음 이

ppatabox.tistory.com

 

728x90
728x90
LIST
profile

평생 공부하는 빠타박스 블로그 : Learning is Happiness

@공부하는 PPATABOX

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!