ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고및 공부자료로 만들어진내용임을 밝힙니다.)
이전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다
이전자료) https://ppatabox.tistory.com/42
진행 내용 (중요 각주 포함) - 맨 하단 글 하단이동 1
정점, 동적할당 , 생성자 호출, 버텍스 버퍼 , hlsl , states , 비트마스크
정리한번 해나갈 것
const상수 붙은 것은 카멜 표기법 말고 관례상 파스칼 표기법을 사용한다.
const UINT VertextCount = 6;
항상 new 같은 거 하면 delete해줘야 한다고 했는데
우리가 여지까지
delte vertices;
이런식으로 지워왔는데.
지금 아래를 보면 배열로 동적할당 되었다.
vertices = new Vertex[VertextCount];
저런 방식으로 그래서 delete하면 안된다.
delete [] vertices; 이런식이 되야 하는데
stdafx에서 매크로로 만들어주자
#define SAFE_DELETE_ARRAY(p) { if(p != NULL){ delete [] p; p = NULL; } }
안에 보면 NULL이 아니라면 delete [ ] 로 해줬다.
Rect::Rect()
{
vertices = new Vertex[VertextCount];
}
Rect::~Rect()
{
SAFE_DELETE_ARRAY(vertices);
}// 항상 new를 할당하고 나면 지우는 거 부터 넣어주자
항상 new를 할당하고 나면 지우는 것 부터 넣어주자
나머지는 배열 다루는 것과 똑같을 것이다.
항상 인터페이스 만들때 description이 붙는다.
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
평소에 이걸 만들때 저런식으로 자료형을 sizeof에 넣는데 (이 자료형 크기만큼 메모리를 0으로 초기화 해 달라는게
ZeroMemory의 역할이다.
그런데 가끔
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
이런식으로 변수를 넣어 놓는 경우가 있다.
똑같이 잘 되긴 한다.
이 변수의 크기랑 자료형의 크기랑 똑같으니까.
그런데
D3D11_BUFFER_DESC desc[3];//배열
ZeroMemory(&desc, sizeof(desc)); //4byte 주소니까
이게 배열이면
sizeof에 변수가 4byte가 나온다.
왜? = 주소 니까.
배열일때
desc의 배열일때는 배열의 시작주소 였는데
그러니까 sizeof(desc) 쪽은 4byte밖에 안나온다.
그래서 &desc 4byte만 필요하다고
그래서 그런 실수를 미리 방지를 위해서
자료형을 넣어주는 것이다.
그럼 배열일 경우 * 3을 해준다.
D3D11_BUFFER_DESC desc[3];//배열
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC) * 3);
이런식으로 해준다. 여기까지 예시
VertexBuffer 만들어 줘서 여기부분 필요없음(통수주의)
private:
Vertex* vertices;
VertexBuffer* vertextBuffer;
vertextBuffer = new VertexBuffer(vertices, VertexCount, sizeof(Vertex));
vertices , 갯수 (vertxCount) , sizeof( stride , 이것은 CPU right? ,GPUright? 할 필요 없음기본 값 false;
보통 쉐이더는 shader 는 맨 위에 할당 한다.
나중에 쉐이더로 응용이 많아서
Rect::Rect()
{
shader = new Shader(L"effect.hlsl"); //wstring 사용 이것도 new했으니까 지워주자
vertices = new Vertex[VertexCount];
vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0.0f));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f)); //좌상단
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f)); //우하단
vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f)); //2,3 같음
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f)); //1,4 같음
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0.0f)); //우상단
vertexBuffer = new VertexBuffer(vertices, VertexCount, sizeof(Vertex));
}
이곳 INPUT_ELEMENT를 정의 할때는 일단 배열로 만들어 준 상태에서
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION"
};
suggests
Effect.hlsl쉐이더에 있는
쉐이더에 있는 이름과 일치 해야 한다.
이걸 시멘틱이라고 한다.
뒤에 , 하고 들어가는데 0 시멘틱 번호 POSITION(시멘틱)0(시멘틱번호)
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
};
그다음 자료형
저기 어디? FLOAT3인데 여기만 FLOAT4 로 받는다 POSITION만큼 갖게
이외로 ROM RAM등등
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0(slot번호), 0(0byte부터 쓰겠음), D3D11_INPUT_PER_VERTEX_DATA(정점데이터로 들어갈꺼니까), 0
colorBuffer_PS = new ConstantBuffer(&colorBufferData/*데이터*/, sizeof(ColorBufferDesc)/*컬러버퍼크기*/, 0/*slot*/, true/*픽셀쉐이더용*/);
wvpBuffer_VS = new ConstantBuffer(&wvpBufferData, sizeof(WvpBufferDesc));
D3DXVECTOR3 eye(0, 0, -1); 5
D3DXVECTOR3 lookAt(0, 0, 0); 6
D3DXVECTOR3 up(0, 1, 0); 7
private:
struct WvpBufferDesc
{
D3DXMATRIX World;
D3DXMATRIX View;
D3DXMATRIX Projection;
WvpBufferDesc()//생성자 받아옴
{
D3DXMatrixIdentity(&World);
D3DXVECTOR3 eye(0, 0, -1); //눈의 위치 살짝 뒤로 떨어져서
D3DXVECTOR3 lookAt(0, 0, 0); //어디를 바라볼 것인가 바라볼 지점
D3DXVECTOR3 up(0, 1, 0); // 머리 회전 방향 2D는 위
D3DXMatrixLookAtLH/*LH왼손좌표계*/(&View, &eye, &lookAt, &up);
D3DXMatrixTranspose(&View, &View); //전치 해주기 열우선을 사용하기 때문
}
}wvpBufferData;
ConstantBuffer* wvpBuffer_VS;
};
전치해줘야 하는데
우리는 행우선을 쓰지만 쉐이더에선 열우선 을 쓴다.
View를 다시 전치 해주고
D3DXMATRIX World; //사용할 것
D3DXMATRIX View; //안변하게
D3DXMATRIX Projection;
이러한 값은 한번만 건들이면 못 건들일 것인데
이런 경우 private를 외부 접근 못하니까.
public:
D3DXMATRIX World;
private:
D3DXMATRIX View;
D3DXMATRIX Projection; //값이 바뀔 이유가 없음
값이 못바뀌게 못건들이게 private처리 해준다
지금까지 쓴 내용 코드 주석 참고
Rect.h
#pragma once
class Rect
{
public:
Rect();
~Rect();
void Position(float x, float y);
void Position(D3DXVECTOR2 vec);
void Scale(float x, float y);
void Scale(D3DXVECTOR2 vec);
void Color(float r, float g, float b, float a = 1.0f);
void Color(D3DXCOLOR color);
public:
void Update(); //이동 처리 Update에서 할 것임
void Render();
private:
D3DXVECTOR2 position;
D3DXVECTOR2 scale;
private:
Shader* shader;
private:
struct Vertex
{
Vertex() : Position(0, 0, 0)
{
}
Vertex(D3DXVECTOR3 position) : Position(position)
{
}
D3DXVECTOR3 Position;
};
private:
Vertex* vertices;
VertexBuffer* vertexBuffer;
const UINT VertexCount = 6; //정점 갯수는 안바뀜
//버퍼
private:
struct ColorBufferDesc
{
ColorBufferDesc() : Color(0, 0, 0, 1)
{
}
ColorBufferDesc(D3DXCOLOR color) : Color(0, 0, 0, 1)
{
}
D3DXCOLOR Color;
} colorBufferData;
ConstantBuffer* colorBuffer_PS; //픽셀쉐이더에 들어감
private:
struct WvpBufferDesc
{
public:
D3DXMATRIX World;
private:
D3DXMATRIX View;
D3DXMATRIX Projection;
public:
WvpBufferDesc()//생성자 받아옴
{
D3DXMatrixIdentity(&World);
D3DXVECTOR3 eye(0, 0, -1); //눈의 위치 살짝 뒤로 떨어져서
D3DXVECTOR3 lookAt(0, 0, 0); //어디를 바라볼 것인가 바라볼 지점
D3DXVECTOR3 up(0, 1, 0); // 머리 회전 방향 2D는 위
D3DXMatrixLookAtLH/*LH왼손좌표계*/(&View, &eye, &lookAt, &up);
D3DXMatrixTranspose(&View, &View); //한번만 만들면 되는 애들 생성자에 넣어버린것
D3DXMatrixOrthoOffCenterLH(&Projection, 0, (float)Width, 0, (float)Height, -1, +1);
D3DXMatrixTranspose(&Projection, &Projection);//한번만 만들면 되는 애들 생성자에 넣어버린것
}
}wvpBufferData;
ConstantBuffer* wvpBuffer_VS;
};
Rect.cpp
#include "stdafx.h"
#include "Rect.h"
Rect::Rect()
{
shader = new Shader(L"effect.hlsl");
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
};
shader->CreateInputLayout(layoutDesc, ARRAYSIZE(layoutDesc));
vertices = new Vertex[VertexCount];
vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0.0f));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f)); //좌상단
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f)); //우하단
vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f)); //2,3 같음
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f)); //1,4 같음
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0.0f)); //우상단
vertexBuffer = new VertexBuffer(vertices, VertexCount, sizeof(Vertex));
colorBuffer_PS = new ConstantBuffer(&colorBufferData/*데이터*/, sizeof(ColorBufferDesc)/*컬러버퍼크기*/, 0/*slot*/, true/*픽셀쉐이더용*/);
wvpBuffer_VS = new ConstantBuffer(&wvpBufferData, sizeof(WvpBufferDesc));
}
Rect::~Rect()
{
SAFE_DELETE(shader);
SAFE_DELETE_ARRAY(vertices);
SAFE_DELETE(vertexBuffer); //new로 할당해서 지워주자
SAFE_DELETE(colorBuffer_PS);
SAFE_DELETE(wvpBuffer_VS);
}
void Rect::Position(float x, float y)
{
Position(D3DXVECTOR2(x, y));
}
void Rect::Position(D3DXVECTOR2 vec)
{
position = vec;//행렬계산으로 따로 저장해둔 것
}
void Rect::Scale(float x, float y)
{
Scale(D3DXVECTOR2(x, y));
}
void Rect::Scale(D3DXVECTOR2 vec)
{
scale = vec; //행렬계산으로 따로 저장해둔 것
}
void Rect::Color(float r, float g, float b, float a)
{
Color(D3DXCOLOR(r, g, b, a)); //컬러 콜
}
void Rect::Color(D3DXCOLOR color)
{
colorBufferData.Color = color; //D3DXCOLOR Color; 이컬러에 들어갈 것
}
void Rect::Update() //월드를 만들 것이다. 월드를 만들기 위해서 크기하고 이동이 다 있다.
{
D3DXMATRIX S, T;
D3DXMatrixScaling(&S, scale.x, scale.y, 1/*Position크기*/); //아이덴티티 되기때문에 행렬곱으로
D3DXMatrixTranslation(&T, position.x, position.y, 0);
wvpBufferData.World = S * T;
D3DXMatrixTranspose(&wvpBufferData.World, &wvpBufferData.World);
}
void Rect::Render() //위가 되었으면 Rendering
{
shader->Render();
vertexBuffer->Render();
colorBuffer_PS->Render();
wvpBuffer_VS->Render();
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);//삼각형 자리 그림
DeviceContext->Draw(6, 0); //draw렌더링
}
main.cpp
#include "stdafx.h"
Rect* rect = NULL;
void InitScene()
{
rect = new Rect();
rect->Position(200, 200);
rect->Scale(100, 100);
rect->Color(0, 0, 1);
}
void DestroyScene()
{
SAFE_DELETE(rect);
}
void Update()
{
rect->Update();
}
void Render()
{
rect->Render();
}
Effect.hlsl( shader )
struct VertexInput
{
float4 Position : POSITION0;
};
struct PixelInput
{
float4 Position : SV_POSITION;
};
cbuffer VS_Wvp : register(b0)
{
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);
return output;
}
cbuffer PS_Color : register(b0)
{
float4 Color;
}
float4 PS(PixelInput input) : SV_TARGET
{
return Color;
}
이번에는 텍스쳐를 그릴 클래스를 하나 만들 것인데.
이번 네이밍을 Rect_sprite 로 이름 짓겠다.
위 Rect와 유사함
Sprite.cpp / h를 만들고 Rect.hlsl을 sprite.h와 분리해놓았다.
Rect&sprite
2D Texture를 Sprite라고 부름
Rect.cpp => Sprite.cpp(변경된 부분)
Sprite::Sprite()
{
shader = new Shader(L"Sprite.hlsl");
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,// 12바이트 부터 시작
};
shader->CreateInputLayout(layoutDesc, ARRAYSIZE(layoutDesc));
vertices = new Vertex[VertexCount];
vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0.0f), D3DXVECTOR2(0, 1));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f), D3DXVECTOR2(0, 0)); //기준 좌상단
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f), D3DXVECTOR2(1, 1)); //우하단
vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0.0f), D3DXVECTOR2(1, 1)); //2,3 같음
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0.0f), D3DXVECTOR2(0, 0)); //1,4 같음
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0.0f), D3DXVECTOR2(1, 0)); //우상단
vertexBuffer = new VertexBuffer(vertices, VertexCount, sizeof(Vertex));
colorBuffer_PS = new ConstantBuffer(&colorBufferData/*데이터*/, sizeof(ColorBufferDesc)/*컬러버퍼크기*/, 0/*slot*/, true/*픽셀쉐이더용*/);
wvpBuffer_VS = new ConstantBuffer(&wvpBufferData, sizeof(WvpBufferDesc));
}
Sprite.h(변경된 부분)
private:
struct Vertex
{
Vertex() : Position(0, 0, 0)
,Uv(0,0) //Vertex에 Uv추가됨
{
}
Vertex(D3DXVECTOR3 position, D3DXVECTOR2 uv)
: Position(position)
,Uv(uv)
{
}
D3DXVECTOR3 Position;
D3DXVECTOR2 Uv;
};
private:
Vertex* vertices;
VertexBuffer* vertexBuffer;
const UINT VertexCount = 6; //정점 갯수는 안바뀜
//버퍼
private:
struct ColorBufferDesc
{
ColorBufferDesc() : Color(1, 1, 1, 1)//Texture에 색상을 곱하는게 되서 0이 들어가면 안된다 그래서 1.
{
}
ColorBufferDesc(D3DXCOLOR color) : Color(0, 0, 0, 1)
{
}
D3DXCOLOR Color;
} colorBufferData;
ConstantBuffer* colorBuffer_PS; //픽셀쉐이더에 들어감
Sprite.h
struct VertexInput
{
float4 Position : POSITION0;
float2 Uv : UV0;
};
struct PixelInput
{
float4 Position : SV_POSITION;
float2 Uv : UV0;
};
cbuffer VS_Wvp : register(b0)
{
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);
return output;
}
cbuffer PS_Color : register(b0)
{
float4 Color;
}
float4 PS(PixelInput input) : SV_TARGET
{
return Color;
}
sampler를 하나 만들어야한다.
samplerstate가 있어야 샘플링을 할 수 있다.
샘플러도 쓰기 편하게 하기 위해 클래스를 하나 만들자
네임명 : States.cpp/h
우리가 true / false말고 여러가지 중에 하나를 선택하는 것이 있는데
열거형을 쓴다
들어가기
비트 연산자 | 설명 |
& | 대응되는 비트가 모두 1이면 1을 반환함 (비트 AND 연산) |
| (역슬래쉬) | 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산) |
^ | 대응되는 비트가 서로 다르면 1을 반환함 (비트 XOR 연산) |
~ | 비트를 1이면 0으로, 0이면 1로 반점시킴 (비트 NOT 연산) |
<< | 지정한 수만큼 비트들을 전부 왼쪽으로 이동시킴 (Left Shift 연산) |
>> | 부호를 유지하면서 지정한 비트를 전부 오른쪽으로 이동시킴 (RIght Shift 연산) |
예시
#include <stdio.h>
int main(void)
{
int num01 = 15;
int num02 = 8;
printf(" ~ 연산자에 의한 결괏값은 %d입니다.\n", ~num01); // 1의 보수
printf("<< 연산자에 의한 결괏값은 %d입니다.\n", num02 << 1); // 곱하기 2
printf(">> 연산자에 의한 결괏값은 %d입니다.\n", num02 >> 1); // 나누기 2
return 0;
}
enum
이라고 정의한다.
enum Type
{
Linear/*0*/, Point/*1*/, Mag/*2*/ // 자동으로 기본값이 처음 0, 1, 2 순으로 지정된다.
}; //이렇게 선언되어있는 변수 이름들이 전역에서 쓰인다
//////////
enum class Type //이렇게 붙여줘야 타입내에 구역이 잡힌다.
{
Linear/*0*/, Point/*1*/, Mag/*2*/
};
////////////////////////////////////////////////////////////////////
Tyep a = Type::Point //이런식으로 쓰임
저번에 Linear, Point 등 했었는데 그게 그 이름들이 전부 열거형으로 정의 되어있다.
그러면 해당하는 숫자가 들어간다
만약에 필요하면 이런식으로 정의할 수 있다.
enum class Type
{
Linear = 1, Point = 2, Mag = 4 // 이런형식으로 정의가능
};
/////////////
Tyep a = Type::Mag //이러면 4가 나온다.
이거는 AND OR 연산 조합할 때 쓴다.
______&&______(조건연산) 둘다 참이여야 참
그런데 이러한 것이 있다.
'&'
아래 예제 처럼 되면 어떤 연산이 일어 날까?
/*'&'*/
a = 10;
b = 7;
c = a & b;
예전에는 나누기 곱하기가 느렸다 (원래 느린 연산)
지금은 PC가 발전해서 안하는데
서버는 하는 경우가 있다. 나누기 연산 안하고
쉬프트로 처리하는 (나누기 곱하기를 쉬프트로 처리한다는 말)
이걸 이용해서 2의 보수 연산 이 있는데 이런 방식을 이용해서 사칙연산을 한다
(BITMASK)
이런걸 조합으로 쓰고 싶다고 할때
예를 들어
//조합을 하고 싶을때
enum class Type
{
Linear = 1, Point = 2, Mag = 4
};
/////////////
c = Linear | Point // 0001 | 0010 = 0011(3)
///////
switch(c)
{
case 1;
case 2;
case 3;
//옵션 조합일때 이런식으로 많이 쓴다.
switch 에서 이런식으로 처리한다.
색상이 실제로는 0~1까지 리니어 한 색상을 가져온다
실제로는 0~255까지 다 (이미지)
0~255까지 픽셀을 표현할 려면 RGBA가 있는데
하나가 FF(R) FF(G) FF(B) FF(A)
우리가 원한건 256값 만큼 다뤄주고 싶다.
그러면 이걸 밀어줘야 하는데
12 숫자를 빼오고 싶을때
FF 는 0~256까지의 범위
편한 단어로 바꾸면 1 바이트
1byte = 8비트 2^8
>> : 비트 밀어주는 연산자
<<
어떤 색상을 이안에 넣고 싶다.
RGBA가 전부 따로 있다.
하나의 변수에 넣고 싶다. OR연산을 이용해서 왼쪽으로 밀어주자.
예를 들어
R = 128
G = 10
B = 54
A = 255
이걸 하나의 변수에 묶고싶다
R은 맨 앞으로 가야하니까
24비트 만큼 밀어주자
128<<24 / 128 00 00 00
G를 넣으려면?
10 << 16 밀어주자 00 10 00 00
OR연산을 이용해서 | 하게되면
128 10 00 00 이다
그럼 R G 의 조합이 일어난다.
나머지 B를 섞고 싶다면 8비트 만큼 밀어주고
A는 그냥 OR 하면 된다
옆 그림처럼 원리를 보여준다.
이런식으로 사용하는 방법은 자주 사용된다.
게임프로그래밍이란 일반프로그래밍이란 다른 기법을 사용하는이유가
일반 프로그래밍은 뭐 속도면에서 그렇게 신경을 많이 쓰지 않는다. (ATM기 돈 안나오면 1~5초 정도는 기다리지 않은가?)
게임프로그래밍은 실시간을 요한다. 속도가 정말 중요하다 늘 실시간(1~2초 지연 생기면 짜증나지 않는가?)
그래서 이러한 연산 방법이 정말 중요하다.
(디바이스와 친화적일 수록 속도가 더 빨라진다.)
그외 참고링크)
다음시간)
각주)
- . [본문으로]
- 시맨틱은 시맨틱이름과 시맨틱인덱스 그외로 더 있다,
1)시맨틱 이름 : 요소의 본질 또는 목적을 설명하는 단어를 포함하는 문자열, 선택한 어떤 것이라도 될 수 있다. 예를 들어 버텍스 위치를 위한 좋은 시맨틱 이름은 POSITION이다. 시맨틱이름은 대소문자를 구분하지 않는다.
2)시맨틱인덱스 : 시맨틱 이름을 봉충한다, 버텍스는 동일 본질 속성을 여러개 가질 수 있다. 예를 들어, 2개의 텍스쳐 세트 또는 2개의 갈라가 그렇다. 시맨틱이름에 숫자를 "COLOR0", "COLOR1"처럼 추가하는 대신, 2개는 동일한 시맨틱 이름인 "COLOR"를 사용하고, 서로다른 시맨틱 인덱스 0, 1 을 가진다. [본문으로]
- 배열의 크기를 알려준다, 배열일때 사용하면 됨 ,전체 사이즈가 나온다 [본문으로]
- 배열의 시작주소 4byte 만 나온다. [본문으로]
- 눈의 위치 살짝 뒤로 떨어져서 [본문으로]
- 어디를 바라볼 것인가 바라볼 지점 [본문으로]
- 머리 회전 방향 2D는 위 [본문으로]
- 비트(bit) 단위로 논리 연산을 할때 사용하는 연산자, 비트단위로 전체 비트를 왼쪽이나 오른쪽으로 이동시킬때도 사용, RGBA색상을 조합하여 실시간으로 필요로하는 곳에서 사용되기도함 [본문으로]
- 조건부문)_표현식이 값을 평가하고, 각 Case 레이블의 값과 '같은'지 테스트, 레이블의 값과 같다면 레이블 뒤의 명령문을 실행, 같지 않다면 default뒤의 명령문을 실행 [본문으로]
'🅿🆁🅾🅶🆁🅰🅼🅼🅸🅽🅶 > DɪʀᴇᴄᴛX 2D' 카테고리의 다른 글
[C++] DirectX Rect&Sprite 2편 (0) | 2021.11.29 |
---|---|
[C++]DirectX 샘플링 / sampler (7) | 2021.11.25 |
[C++]DirectX 벡터와 배열과 범위 Array | Scale (0) | 2021.11.23 |