D3DX9 21.11.17

김주현·2021년 11월 17일
0

d3dx9 3D

목록 보기
28/30

UI

게임오브젝트에 UI클래스를 추가한다.
(몬스터 클래스를 복사해서 이름을 바꿔주자)

3D화면이라도 2D로 화면을 띄어야하는경우를 UI로 처리하자.

애초에 정점을 찍을때 윈도우상의 좌표로찍으면 이는 모든 행렬을 무시해버린다.

근데 이는 창을 마우스로 끌고 움직이는 같은 이동이 불가능하다. -> 직접 정점을 이동시켜주는것을 해야함(버텍스버퍼의 락을하고 직접움직인다). - > 이는 번거롭기도하지만 프레임드랍을 유도한다.-> 이방법은 사용하지않는다.

그래서 직교투영이라는 방식을 이용한다.

트랜스폼 사용하지 않는다 날려주자
(렌더러와 VI버퍼만 있으면된다)

직교 투영

-투영행렬
원래 SetTransform(D3DTS_PROJECTION,&Projmatrix)를통해 원근투영을 하고있었음 이를 직교투영으로 하자.

UI 객체가 만들어질때 멤버변수로 행렬을 하나 생성하자(m_ProjMatrix)이는 직교투영 행렬을 의미한다.
3차원의 점을 2차원으로 바꾸는데 원근감 없이 바로 2D로 변환한다.(정점의 위치에서 Z값을 제거한다)

//직교투영행렬을 만들어준다(네컨에서해주자)
D3DXMatrixOrthoLH(저장할곳,너비,높이,z최소값,z최대값);
-너비와 높이를 받는이유 : 로컬 영역 상에 정점등을 바로 투영스페이스로 옮긴다.(월드 변환필요없다(3차원 공간상에 배치하지않음)

-너비와 높이로 100을 준경우 :
2차원 투영 스페이스의 모든 정점을 그리는 것이 아니다.(-1,1 ~ 1,-1 사이의 정점만 그린다)
로컬 스페이스의 어떤 점들을 투영스페이스로 옮긴것인지를 물어본다.-> 원점기준으로 가로 100 세로 100영역의 모든 정점들을 투영스페이스 상으로 끌고 들어온다.

-로컬스페이스 상의 3차원 공간이기때문에 어떤 깊이를 가진애들을 투영 스페이스로 옮기지를 정해줘야한다. z의 범위를 최소 최대로 넣어준다.

-뷰행렬
SetTransform(D3DTS_VIEW,&Viewmatrix)
어차피 화면에 보이므로 뷰변환도 필요없다.
-> 항등행렬을 넘겨주자.
SetTransform(D3DTS_VIEW,D3DXMatrixIdentity(&Viewmatrix))

-월드 행렬

항등행렬로 넣어주자.

-Late_Tick 렌더그룹은 UI로주자

지금은 UI가 매우 조그맣게 그려진다. 한번 원하는 크기로 출력해보자.

멤버변수로 m_fX,m_fY, m_fSizeX,m_fSizeY를 추가해주자. 원하는 크기로 출력해주는것을 월드행렬로 진행할것이다.

-ui월드행렬은 의미가없다 여기서 로컬스페이스 기준으로 크기변환과 위치변환만 셋팅할것이다.
월드 행렬이아니라 로컬스페이스상에서 위치와 크기를 잡아주는 행렬이다 이름을 TransformMatrix로 바꾸자.

우선 Identity로 초기화 해주자.
UI가 회전하지는 않는다->대각 선 성분이 스케일을 의미한다.
._11 = m_fSizeX
._22 = m_fSizeY

이제 위치를 옮기고 싶다.

TransformMatrix._41 = m_fx - (g_Wincx >> 1) 하면 화면이 오른쪽반만 왼쪽 선에 걸치게 할수있다.

TransformMatrix.41 = -m_fY + (g_wincy>> 1)

마우스 충돌해주고싶다.

GetCursorPos로 마우스 위치 받아와서

UI의 렉트를 잡아주고

PtInRect로 UI와 충돌을 제어할수 있다.

실제 생성

-로딩클래스의 레디레벨게임플레이0에서 UI객체의 원형을 생성해주자.(UI 헤더 추가)

-레벨 게임플레이에서 레디_레이어_UI() 함수를 만들어주자(자주 참조하는애들은 레이어를 독립적으로 만들어주는게 좋다) 다음 호출해주자.

-텍스처 띄어주기위해 텍스처 컴포넌트를 추가해주자.

-AddComponent에서 텍스처 디폴트 컴포넌트를 추가해주자.

-렌더에서 조명을 꺼주자.

-렌더에서 SetTexture호출해주자.

이펙트

클라이언트의 게임 오브젝트 폴더에 이펙트 클래스 추가해주자.

로더에서 이펙트의 원형을 생성해보자.

로더에서 텍스처를 로드하자 Explosion폴더의 Explosion%d를 로드하자.

게임플레이에서 레디레이어이펙트를 만들어주고 실행해주자.

렌더에서 월드,뷰,투영을 세팅해주자.

멤버변수 m_dFrame을 선언해주자.

Tick에서 프레임을 0부터 90까지 돌려주자.

Set_Up_GraphicDevice에서 프레임은 int형으로 줘서 이펙트를 보여주자.

레이트틱에서 애드렌더그룹해주자.(알파그룹)

렌더에서 알파브렌드 켜주자.
SetRenderState(D3DRS_ALPHANLENDENABLE, TRUE);
(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

  • 소스의 컬러를 곱해라를 의미한다.
  • 그릴려는 색은 RGB를 의미하고 여기다가 A를 곱하라는것을 의미한다.

(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

  • 데스트의 RGB에 1-소스의A를 곱해서 더한다.

소스의 알파가 0이면? 소스의 RGB는 하나도 안그려지고 데스트는 1-0이되서 기존이 그대로 그려진다.

1이면 반대로 소스만 다그려진다.

0.5면 반투명하게 그려진다.

블렌드는 섞는다 최소 두개가 필요하다.

소스의 색과 데스트의 색이 필요하다.
SRCCOLR : 내가 그릴려고 하는 색상을 의미하고

DESTCOLOR : 이미 그려져있던 색상을 의미한다.

알파 테스트

//깊이테스트 이전에 수행된다.
m_pGraphic_Device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
m_pGraphic_Device->SetRenderState(D3DRS_ALPHAREF, 0~255);
m_pGraphic_Device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);

알파테스테의해서 어떤 픽셀을 그릴지 안그릴지를 결정한것이다.

알파 블렌드의 문제점

배경이 다른 이펙트를 덮음

0개의 댓글

관련 채용 정보