ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고및 공부자료로 만들어진 내용임을 밝힙니다.)
전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다
이전 자료) https://ppatabox.tistory.com/43
목차-
1) ConstantBuffer
2) ConstantBuffer 추가 설명 (오류수정)
===========================================================
SIMD(single Instruction Mulitple Data) : 병렬컴퓨팅의 한 종류
하나의 명령어로 여러 개의 값을 동시에 계산하는 방식
c버퍼를 다뤄보자
GPU라는 것은 CPU는 자료형이 다양한데
GPU는 무조건 float하나
예를 들어 bool로 선언 했을때 false라고 넣고 int형으로 바꾸면0 인데
0.000000 int형으로 저장해도int형으로 10을 저장해도 10.0000 형태
규칙이 있는데 SIMD(single Instruction Mulitple Data) 특징은 16바이트로 묶여서 들어간다.
16 -> 32
C버퍼를 쓸때는 16바이트에 맞춰야 한다
커서 같은경우 쉐이더 쪽에서는 FLOAT 자료형이 VECTOR3 면 FLOAT3이런식으로 쓰는데
COLOR는 FLOAT이 4개 니까 FLOAT4이다 컬러는 그냥 써도 되는데
근데 VECTOR는 하나가 빈다. 그러면 거기다 임의의 FLOAT을 추가해주는 것이다
그렇게 16바이트를 맞추는 것이다.
위치를 추가하는 것을 한번 보자
RECT에서 처리를 하겠다. WORLD를 사용안함 (나중시간에 ConstantBuffer을 사용하기에)
예시0_1) 1) 구조체를 하나 만드는데 이 구조체의 크기는 반드시 16바이트 여야 한다. MATRIX는 어차피 4 X 4이다 (행렬공간) 그래서 FLOAT이 16개 이다 그래서 16바이트 단위가 맞춰진다. (64byte) 그래서 wvp부분의 구조체가 상관이 없던 것이고
새로 만들게될 구조체에서 만약에 애가 D3DVECTOR3 Location; 이라고 쓰게 할려면 Cbuffer 하나 더넣으니까 추가 해주고 Rect.h
.//
/////
struct WVP
{
D3DXMATRIX World; //MATRIX 4X4 (행렬이라 생각하면됨)
D3DXMATRIX View;
D3DXMATRIX Projection;
} wvp;
struct
{
D3DXVECTOR3 Location
}constant;
private:
D3DXVECTOR3 position;
D3DXVECTOR3 scale;
private:
Shader* shader;
Vertex vertices[6];
VertexBuffer* vertexBuffer;
ConstantBuffer* wvpBuffer;
ConstantBuffer* constantBuffer; // Cbuffer하나 더 넣을것이기에
};
Rect.cpp에서도 contantBuffer 쪽을 수정해줘야하는데
ConstantBuffer에서 F12를 누르고 들어가게 되면 Buffer.cpp 부분에서 보면
DeviceContext->VSSetConstantBuffers(슬롯번호0, 1, &buffer); 슬롯 번호를 하나 만들어줘야한다.
Buffer.h 에서 slot번호를 하나 만들어주자
Buffer.cpp
DeviceContext->VSSetConstantBuffers(0, 1, &buffer); //몇개의 버퍼를 쓸것이냐(수정)
======================================================================================
ConstantBuffer::ConstantBuffer(void * data, UINT dataSize, UINT slot) // 생성자 수정
: data(data), dataSize(dataSize), slot(slot)
{
D3D11_BUFFER_DESC desc = { 0 };
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.ByteWidth = dataSize;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
HRESULT hr = Device->CreateBuffer(&desc, NULL, &buffer);
assert(SUCCEEDED(hr));
}
ConstantBuffer::~ConstantBuffer()
{
SAFE_RELEASE(buffer);
}
void ConstantBuffer::Render()
{
D3D11_MAPPED_SUBRESOURCE subResource;
DeviceContext->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
{
memcpy(subResource.pData, data, dataSize);
}
DeviceContext->Unmap(buffer, 0);
DeviceContext->VSSetConstantBuffers(slot, 1, &buffer);
}
Rect.h
class ConstantBuffer
{
public:
ConstantBuffer(void* data, UINT dataSize, UINT slot = 0); //slot에 일단 기본값 0 하나만 쓰면 기본 0
~ConstantBuffer();
ID3D11Buffer* Buffer() { return buffer; }
void Render();
private:
ID3D11Buffer* buffer;
void* data;
UINT dataSize;
UINT slot; //slot 추가
};
그렇게 수정후에 slot번호 1을 넣어주고 DELETE 해주고 아래 Render도 밀어넣어 주자
그런데 실행하게 되면 오류가 뜨는 걸 볼 수 있다.
Rect.cpp
#include "stdafx.h"
#include "Rect.h"
Rect::Rect()
{
vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
"COLOR", 0, DXGI_FORMAT_R32G32B32A32_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));
constantBuffer = new ConstantBuffer(&constant, sizeof(Constant),1);//slot번호
// constant 가 들어가고 자료형 /크기를 입력해준다.
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);
}
Rect::~Rect()
{
SAFE_DELETE(vertexBuffer);
SAFE_DELETE(wvpBuffer);
SAFE_DELETE(constantBuffer); //삭제할 것 삭제해줘야함
SAFE_DELETE(shader);
}
void Rect::Position(float x, float y, float z)
{
Position(D3DXVECTOR3(x, y, z));
}
void Rect::Position(const D3DXVECTOR3 & position)
{
this->position = position;
//D3DXMatrixTranslation(&wvp.World, position.x, position.y, position.z);
//D3DXMatrixTranspose(&wvp.World, &wvp.World);
}
void Rect::Position(D3DXVECTOR3 * position)
{
//*position = this->position;
memcpy(position, this->position, sizeof(D3DXVECTOR3));
}
void Rect::Scale(float x, float y, float z)
{
Scale(D3DXVECTOR3(x, y, z));
}
void Rect::Scale(const D3DXVECTOR3 & scale)
{
this->scale = scale;
}
void Rect::Scale(D3DXVECTOR3 * scale)
{
memcpy(scale, this->scale, sizeof(D3DXVECTOR3));
}
void Rect::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->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
shader->Render();
vertexBuffer->Render();
wvpBuffer->Render();
constantBuffer->Render(); //constantBuffer도 데이터를 밀어넣어 주기위해
DeviceContext->Draw(6, 0);
}
실행시 볼 수 있는 오류창인데 다시시도를 누르게 되면 오류의 지점으로 가게 된다.
어디선가 실패했다
아래 hr갖다 대면 INVALID ARGUMENT 가 나오는데
이곳에 들어와야 하는 데이터 아규먼트가 잘못되서 오류가 떳다
이유는 데이터 사이즈 때문에 이다.
dataSize를 보면 12가 나오는 걸 볼 수 있다.
아까 16바이트 기준이라고 했는데
16바이트 단위를 또다른 말로
16byte Padding 패딩(한뭉터기의 단위) 이라고도
부른다.
16바이트 패딩이여야 하는데 12바이트가 들어왔기 때문에
이곳에서 실패를 한 것이다.
그럴때는 struct 구조체 만들어둔곳에 16 바이트 맞춰 주기 위해 Padding을 넣어준다(Rect.h)
일단은 문제 없이 실행되는 것을 볼 수 있다.
이번에는 Rect.h -> Location에 위치를 넣어보자
Rect.cpp/Render부분을 봐보자
(실제로는 이렇게 잘 안쓴다(예시로참고))
이번에는 World를 사용하지 않고 위치만 이동 시킬 것이다.
크기는 임의로 잡을것 이다.
void Rect::Render()
{
D3DXMATRIX S, T;
D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
D3DXMatrixTranslation(&T, position.x, position.y, position.z);
wvp.World = S; //크기만 잡아주고
D3DXMatrixTranspose(&wvp.World, &wvp.World);
constant.Location = position; //위치를 잡아주자
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
shader->Render();
vertexBuffer->Render();
wvpBuffer->Render();
constantBuffer->Render();
DeviceContext->Draw(6, 0);
}
(수정)= 실행안됨 다음시간에 다루겠음
Effect.hlsl 에들어가서 cbuffer call
VS용이라고 붙여준다
input.position = input.position(정점 위치 크기만 가져왔음) + float4(Location, 1) 결합 // float4라서 붙여줌
정점 색상 output.Color = input.Color; 인데
정점을 조작하지 않고 임의로 색을 바꾸고 싶은 경우에도
ConstatnBuffer를 사용하면 된다 (외부에서 값을 주는것 전부)
값을 밀어줄때 VSSetConstantBuffers 이것은 버텍스 쉐이더에 밖에 constant가 값을 다른곳에 못준다 는 말
그래서 pixelshader용 함수가 따로 있다.
또한 struct Constant하나 가지고 pixel vertex /shader를 다 쓸 수 있다.
그렇게 하더라도 pixelshader이든 vertextshader이든 따로 마킹을 해줘야 한다.
그래서 각 쉐이더당 하나 라고 생각해야 한다. (공용으로 쓸수 있으나 복잡해짐)
그래서 pixelShader에 값을 줄려면 전용 마킹을 해야한다.
Buffer.h로 가자
class ConstantBuffer
{
public:
ConstantBuffer(void* data, UINT dataSize, UINT slot = 0, bool bPixelShader = false);//pixelshader지정
~ConstantBuffer();
ID3D11Buffer* Buffer() { return buffer; }
void Render();
private:
ID3D11Buffer* buffer;
void* data;
UINT dataSize;
UINT slot;
bool bPixelShader;//추가
};
Buffer.cpp
ConstantBuffer::ConstantBuffer(void * data, UINT dataSize, UINT slot, bool bPixelShader)
: data(data), dataSize(dataSize), slot(slot), bPixelShader(bPixelShader)
{
D3D11_BUFFER_DESC desc = { 0 };
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.ByteWidth = dataSize;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
HRESULT hr = Device->CreateBuffer(&desc, NULL, &buffer);
assert(SUCCEEDED(hr));
}
ConstantBuffer::~ConstantBuffer()
{
SAFE_RELEASE(buffer);
}
void ConstantBuffer::Render()
{
D3D11_MAPPED_SUBRESOURCE subResource;
DeviceContext->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
{
memcpy(subResource.pData, data, dataSize);
}
DeviceContext->Unmap(buffer, 0);
if (bPixelShader)
{
DeviceContext->PSSetConstantBuffers(0, 1, &buffer); //pixel
return;
}
DeviceContext->VSSetConstantBuffers(0, 1, &buffer);
}
아래와 같이VS PS수정 하였음
Rect.h
#pragma once
class Rect
{
public:
Rect();
~Rect();
void Position(float x, float y, float z = 0);
void Position(const D3DXVECTOR3& position);
void Position(D3DXVECTOR3* position);
void Scale(float x, float y, float z = 1);
void Scale(const D3DXVECTOR3& scale);
void Scale(D3DXVECTOR3* scale);
void Render();
private:
float GetWidth(float position) { return position / (float)Width * 2.0f - 1.0f; }
float GetHeight(float position) { return -(position / (float)Height * 2.0f - 1.0f); }
private:
struct Vertex
{
D3DXVECTOR3 Location;
D3DXCOLOR Color;
Vertex()
{
Location = D3DXVECTOR3();
Color = D3DXCOLOR();
}
Vertex(D3DXVECTOR3 location, D3DXCOLOR color)
{
Location = location;
Color = color;
}
};
struct WVP
{
D3DXMATRIX World;
D3DXMATRIX View;
D3DXMATRIX Projection;
} wvp;
struct ConstantVS//구분지어둠
{
D3DXVECTOR3 Location;
float Padding;
}constantVS;
struct ConstantPS//pixel지정
{
D3DXCOLOR Color;//float 4개 그러니 padding빼도됨
}constantPS;
private:
D3DXVECTOR3 position;
D3DXVECTOR3 scale;
private:
Shader* shader;
Vertex vertices[6];
VertexBuffer* vertexBuffer;
ConstantBuffer* wvpBuffer;
ConstantBuffer* constantVSBuffer;
ConstantBuffer* constantPSBuffer;//
};
Rect.cpp
#include "stdafx.h"
#include "Rect.h"
Rect::Rect()
{
vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXCOLOR(0, 0, 1, 1));
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
"COLOR", 0, DXGI_FORMAT_R32G32B32A32_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));
constantVSBuffer = new ConstantBuffer(&constantVS, sizeof(ConstantVS), 1);
constantPSBuffer = new ConstantBuffer(&constantPS, sizeof(ConstantPS), 0, true);//pixelshader에 constantBuffer아무것도 안들어가니까 0번으로 들어가면됨
//pixelShader가 true가 되야함 pixelshader용 이라는 표시
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);
}
Rect::~Rect()
{
SAFE_DELETE(vertexBuffer);
SAFE_DELETE(wvpBuffer);
SAFE_DELETE(constantVSBuffer);
SAFE_DELETE(constantPSBuffer);
SAFE_DELETE(shader);
}
void Rect::Position(float x, float y, float z)
{
Position(D3DXVECTOR3(x, y, z));
}
void Rect::Position(const D3DXVECTOR3 & position)
{
this->position = position;
//D3DXMatrixTranslation(&wvp.World, position.x, position.y, position.z);
//D3DXMatrixTranspose(&wvp.World, &wvp.World);
}
void Rect::Position(D3DXVECTOR3 * position)
{
//*position = this->position;
memcpy(position, this->position, sizeof(D3DXVECTOR3));
}
void Rect::Scale(float x, float y, float z)
{
Scale(D3DXVECTOR3(x, y, z));
}
void Rect::Scale(const D3DXVECTOR3 & scale)
{
this->scale = scale;
}
void Rect::Scale(D3DXVECTOR3 * scale)
{
memcpy(scale, this->scale, sizeof(D3DXVECTOR3));
}
void Rect::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);
constantVS.Location = position;
constantPS.Color = Math::RandomColor();
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
shader->Render();
vertexBuffer->Render();
wvpBuffer->Render();
constantVSBuffer->Render();
constantPSBuffer->Render();
DeviceContext->Draw(6, 0);
}
이제 색상을 지정해줘야 하는데 Color에다가
이제 Math로 가자
Utilities / Math.h
#pragma once
class Math
{
public:
static int RandomInt(int r1, int r2);
static float RandomFloat(float r1, float r2);
static D3DXCOLOR RandomColor(); //랜덤으로 잡아줄것
};
color는 0~1까지의 범위이다
Utilities / Math.cpp
#include "stdafx.h"
#include "Math.h"
int Math::RandomInt(int r1, int r2)
{
return rand() % (r2 - r1 + 1) + r1;
}
float Math::RandomFloat(float r1, float r2)
{
float random = ((float)rand()) / (float)RAND_MAX;
float diff = r2 - r1;
float val = random * diff;
return r1 + val;
}
D3DXCOLOR Math::RandomColor()
{
float r = RandomFloat(0, 1); //color는 0~1까지의 범위
float g = RandomFloat(0, 1);
float b = RandomFloat(0, 1);
return D3DXCOLOR(r, g, b, 1);
}
PS_Constant를 넣어주고 color니까 float4 맨 밑에 pixelshader에서 color값 들어오니까 input제거
Effect.hlsl
cbuffer VS_Wvp : register(b0)
{
matrix World;
matrix View;
matrix Projection;
}
/*이런식으로 외부에서 변수를주는방식*/
cbuffer VS_Constant : register(b1) //slot번호
{
float3 Location; //cbuffer는 여기에 쓰면 전역변수가 된다
float VS_Constant_Padding; //이름이 헷갈릴 수 있어서 이름 중복 안되기위해
}
cbuffer PS_Constant : register(b0) //일회용이 아니라 명시해준다
{
float4 Color;
}
PixelInput VS(VertexInput input)
{
PixelInput output;
//input.Position = input.Position + float4(Location, 1);
output.Position = mul(input.Position, World);
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
output.Color = input.Color;
return output;
}
float4 PS(PixelInput input) : SV_TARGET
{
return Color; //pixelshader에서 값들어오니까
}
이렇게 상자의 색이 랜덤하게 계속 바뀌는 것을
볼 수 있다.
지금까지 이러한 방법은 정점을 건드리지 않고
외부에서 변수를 주는 방법이다.
그래서 기본적으로 정점자체의 데이터를 수정하는 경우는 거의 없다.
위치를 쓸때 location이 float4에 들어가야 하다 보니까
Float4 (Location, 1) //벡터라는 것은 두가지 중에 한가지 값을 갖는다
벡타라는 것은 두가지 중에 한가지 값을 갖는데
//1) 위치 2) 방향 이있다 사람은 알지만 컴퓨터는 모른다.
그래서 명시를 해주는 것인데
저기 있는 1이 위치 이다.
예를 들어 행렬을 보면
4X4행렬에서
위치가 있으려면 4X4가 다 있어야 한다
그런데 4X4행렬을 다 안써도 행렬을 표시 할 수 있는데
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 |
그런데 3X3만 사용할 수 있는데
X1 | 0 | 0 |
Y0 | 1 | 0 |
Z0 | 0 | 1 |
위치가 필요없이 공간의 회전만 필요할때 방향만 표시할때 저기 4X4의 부분이 필요없을때가 있다
그래서 3X3(방향)만 표시할때가 있다 4X4로 하면 위치까지 표시하는 것이고
그런데 여기서 보면
만약에 Float4 = (0, 0, 0 , 0 )인데 뒤에 0 이라고 쓰면 방향을 의미한다 (이 애의 Vector를 방향으로 쓰겠다)
벡터가 행렬곱을 할려면 원소 갯수가 같아야 하는데
그래서 (0, 0, 0, 0) 맨뒤에 0이라고 되어있으면 4X4가 아니라 사라지고 3X3이 된다.
또한 Float4 = (0, 0, 0, 1) 뒤에가 1이면 4X4로 해서 전부 표시된다. 위치로 마킹을 해준다는 것
그래서 Input position에서 마킹을 안했는데 float4 position : POSITION0;이 시스템에서 받아올때
자동으로 1이 마킹된다 그래서 이것을 위치로 간주한다.
그래서 만약 input. position을 꺼내서 보면 자동으로 1이 들어가 있는 것을 볼 수 있다.
그리고 ConstantBuffer는
렌더링 파이프에서 어느 쉐이더이든 각각 용도로 다 넣을 수 있다.
EffectFrameWork 사용하는 방법도 있다
나중에 텍스쳐나 이런것을 넣으려고 할때 여러가지 값을 사용하는데
이미 키워드 들이 텍스쳐는 정해져 있다.
그래서 임의의 값을 잘 넣지 않는다.
다음으로는 이미지를 다룰 것인데. 리소스 라는 곳으로 들어간다.
이미지를 받으려면 이해해야 하는 개념이 있는데
게임프로그래밍에서는 3D : Texture 2D : sprite라고 명칭을 부른다
이미지의 종류에서는
JPG : 게임에서 않씀 (압축을해서 용량을 줄여서 손실이 일어남 줄였다가 키우면 복원이 안됨)
GIF ; 손실압축
PNG : 무손실 압축 압축도 잘되고 지원되는 기능도 많은 32채널~ 128채널 고해상도 (요즘엔 PNG만 거의 씀)
TGA : 옛날에 쓰던 (무손실압축방식) 채널을 12채널 밖에 지원이 안됨 RGBA일때 알파 값이 없다A 투명처리가 없는데
투명처리를 할때 1 0 1(컬러키) 이런 특징적인 색상 핑크색이 비슷한 마제타색이라고 하는데 이걸 투명으로 쓴다.
BMP : 압축이 없고 텍스쳐 구조 연습할때 씀 압축이 안되니까 용량이 엄청큼
등등
2) ConstantBuffer 추가 설명 (오류수정)
오류사항 안되던 부분 수정
Effect.hlsl에서
output.Position += float4(Location, 1);
이것의 위치를 얘기 할때 이전에 오류가 좀 있었는데
아래 main으로 가보면
void InitScene()
{
for (int i = 0; i < 10; i++)
{
rects.push_back(new Rect());
rects[i]->Position((float)i * 100.0f, 300.0f); //지금이게 반정도 들어가고 있다.
rects[i]->Scale(50, 50); //크기는 25 반절 들어감
}
}
위치가 한 300쯤 보이나?
대략 적인 너비 높이가
150정도 된다.
이 100
wvp.World = S * T; //만약 이렇게 곱하면 얘는 공간 전체의 변환
공간 전체 변환한데에 위치를 변환 시킨것
output.Position = mul(input.Position, World);//스케일은 무시가 되고
output.Position += float4(Location, 1); //이게 들어감
PixelInput VS(VertexInput input)
{
PixelInput output;
//input.Position = input.Position + float4(Location, 1);
output.Position = mul(input.Position, World);
//output.Position += float4(Location, 1);
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
output.Color = input.Color;
return output;
}
원래였다면
이렇게 출력이 되어야 한다.
output.Position += float4(Location, 1); //다시 이걸 틀어도 스케일이 무시하고 들어가진다.
위치는 똑같음
높이는 같고 스케일은 안먹힘
월드 변환상태에서 위치를 먹이면 기존 월드(크기)는 무시된다
이 얘가 다시 크기를 갖기 때문에
전에 는 안나왔는데.
위에 서는
//input.Position = input.Position + float4(Location, 1); //스케일이 적용되지 않은 상태의 포지션
//원래 포지션 위치로 감 위치를 옮겼는데.
output.Position = mul(input.Position, World);
//output.Position += float4(Location, 1);
//input.Position = input.Position + float4(Location, 1)
원래 포지션 위치로 간것이고 float4로 위치를 옮겼는데 포지션을
이상태에서 공간변환의 크기가 있다.
위치는 상관없다 더해진 값이니까.
T는 없다고 했을때
//input.Position = input.Position + float4(Location, 1) 하고 S 크기를 먹인게 된다.
위치를 이동시키고 크기를 먹인것
이동한 상태에서 크기 50을 먹인것이다. 이동이 한 50만큼 됬다하면
그럼 크기 50을 먹인것인데
크기 50까지 늘어나는데
이것은 문제가 아니라
이 간격도 크기에 들어가서 화면 밖으로 넘어가서 안보인것
S빼고 T만 보자
월드(크기)는 실제로 늘어났고
그런데 올때 작아졌다.
그이유가 이 크기를 무시한 것이다.
왜 무시가 될까?
output.Position = mul(input.Position, World); //이 위치가
//output.Position += float4(Location, 1);
위치가 처음에 (-0.5, +0.5) 라고 할때 이상태에서 크기를 늘렸다
100배라고 칠때
-50 , 50 이 됬는데.
그다음 내려와서 보면 이곳에 Location을 더한 것
100 이였는데 100을 더해준것 각각
그러면 생각하기에 50 50 이니까 먹은게 되야 하는데
실제로 안먹힌다.
왜냐면 포지션 변경한 값이 비율이였기 때문에 그렇다.
스케일이 100배였어
위치가 50이라고 치고
이곳에 100배 만큼 크기를 늘린게 됬는데
이해를 위해 한번더 설명하겠음
scale (100, 100)
position(50, 50)
input.position에 들어온 값은 정점의 값 x= -0.5 y= 0.5
첫번째 했을때
1)input.position에(-0.5, 0.5) + position(50, 50) 을 더한 상태
= (-49.5, 50.5) 크기 차이는 1 크기는 어차피 1이였음 자기원본값
50만큼 이동하였음 그런데 온만큼 50배가 늘어나서 더 멀리감
//input.Position = input.Position + float4(Location, 1);
output.Position = mul(input.Position, World);
2)스케일을 먹여봐야 (-0.5, 0.5) 에 scale을 곱한다고 생각하는 착각을 하는데
scale은 비율이라고 얘기 했었는데 예를들어 서
이것을 똑같이 아까처럼 99.5 100.5 스케일을 저기에 먹여도 어차피 이 차이 라서
의미 없음 (첫번째 도 크기는 1 스케일도 크기는 1) 이건 공간변환 아님 스케일만
이상태에서 Location을 더한게 되는건데
더해봐야 크기는 1 그래서 (실제로는 1은아님)
그래서 더 작게 나온건데
이 배열만큼 늘렸다가 줄이는 개념 (동차때문에 줄어드는 비율이 있는데 그냥 알아두고 있으면됨)
output.Position = mul(input.Position, World);
output.Position += float4(Location, 1);
예제가 잘못 나온 개념인데 이런식으로 이뤄졌다 라고 생각하면됨
위치를 옮길때는 공간을 옮겨야 한다
정점을 직접 옮기는게 아니라
원하는 결과가 나오지 않음 (되긴되지만 결과)
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);
constantVS.Location = position;
constantPS.Color = Math::RandomColor();
그래서 직접적으로 정점을 건드리진 않고
공간을 이용해서 같이 움직이는 걸로 생각하면됨
DirectX 11 기초 (Tutorial) - 상수 버퍼, 셰이더 스테이지 오브젝트(Constant Buffer, Shader Stage Object)
셰이더에서 실행하는 코드는 Dx9와 마찬가지로 HLSL 코드를 사용한다 지난 포스팅에도 했지만 이번 포...
blog.naver.com
이미지의 종류
◎ PSD 어도비사의 포토샵에서 기본적으로 사용하는 파일 포맷으로 단순히 이미지만을 저장하는 것이 아...
blog.naver.com
TGA (소프트웨어) - 위키백과, 우리 모두의 백과사전
TGA는 트루비전사의 타가보드를 위하여 개발된 래스터 그래픽 파일 포맷이다. 정식 명칭은 트루비전 TGA(Truevision TGA)이며, 단순히 "TGA 파일 포맷", "타가 파일 포맷"으로 부르기도 한다. TGA 파일의
ko.wikipedia.org
다음내용 )
[C++] DirectX Texture _ Uv
ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다. 본 내용은 똑같이 사용할 수 없음을 알립니다. (참고및 공부자료로 만들어진 내용임을 밝힙니다.) 전 과정에 대해 이해를 해야 다음 이
ppatabox.tistory.com
'🅿🆁🅾🅶🆁🅰🅼🅼🅸🅽🅶 > DɪʀᴇᴄᴛX 2D' 카테고리의 다른 글
[C++] DirectX Texture _ Uv (0) | 2021.11.19 |
---|---|
[C++] DirectX 쉐이더 와 삼각형과 사각형의 이용 Shader Class 및 World /Rectangle/Triangle (0) | 2021.11.12 |
[C++] DirectX 색상과 쉐이더 / Color with Shader (0) | 2021.11.11 |