제5장 조명 2010-1학기 컴퓨터게임(DIrectX)
조명의 요소 환경광(Ambient Light) 다른 표면에 반사되어 전반적인 장면을 밝게 하는 빛을 모델링 함. Direct3D의 조명 모델에서 광원이 만들어 내는 빛은 다음과 같은 세 가지 요소로 구성되어 있다 환경광(Ambient Light) 다른 표면에 반사되어 전반적인 장면을 밝게 하는 빛을 모델링 함. 난반사광(Diffuse Light) 특정한 방향으로 진행하며, 표면에 닿으면 모든 방향으로 동일하게 반사됨. 모든 방향으로 동일하게 반사되므로 위치와는 관계없이 관찰자의 눈에 빛이 도달하고 관찰자의 위치를 고려할 필요가 없다. 정반사광(Specular Light) 특정한 방향으로 진행하며, 표면에 닿으면 한 방향으로 강하게 반사하여 특정한 각도에서만 관찰. 한 방향으로만 빛을 반사하므로 빛의 방향과 표면의 형태, 관찰자의 시점을 모두 고려 2010-1학기 컴퓨터게임(DIrectX)
Device->SetRenderState(D3DRS_SPECULARENABLE, true) 정반사광은 다른 타입의 빛에 비해 좀더 많은 계산을 필요로 하기 때문에 Direct3는 이를 끌 수 있는 옵션을 제공. 이 옵션은 디폴트로 꺼져 있으며, 정반사광을 활성화하기 위해서는 D3DRS_ SPECULARENABLE 렌더 상태를 설정해야 함 Device->SetRenderState(D3DRS_SPECULARENABLE, true) 각각의 빛의 형은 빛의 컬러를 표현하는 D3DXCOLOR나 D3DCOLORVALUE 구조체로 나타낼 수 있으며, 다음은 몇 가지 빛의 컬러 예 D3DXCOLOR redAmbient(1.0f, 0.0f, 0.0f, 1.0f); D3DXCOLOR blueDiffuse(0.0f, 0.0f, 1.0f, 1.0f); D3DXCOLOR whiteSpecular(1.0f, 1.0f, 1.0f, 1.0f); 2010-1학기 컴퓨터게임(DIrectX)
재질 우리가 현실에서 보는 물체의 컬러는 물체가 반사하는 빛의 컬러에 의해 결정됨. 예를 들어, 빨간 공은 빨간빛 이외의 다른 모든 빛을 흡수하므로 빨간색으로 보인다. 공의 표면은 빨간빛만을 반사하며, 이것이 우리의 눈에 도달하면 공을 빨간색으로 인식 DirectX는 물체의 재질을 정의할 수 있도록 이 현상을 모델링 재질은 물체의 표면에서 반사할 빛의 퍼센테이지를 지정할 수 있도록 해준다. 다음 구조체로 재질을 나타냄. typedef struct _D3DMATERIAL9 { D3DCOLORVALUE Diffuse, Ambient, Specular, Emissive; float Power; } D3DMATERIAL9; 2010-1학기 컴퓨터게임(DIrectX)
Diffuse – 표면이 반사하는 난반사광의 양을 지정 Ambient – 표면이 반사하는 환경광의 양을 지정 Specular – 표면이 반사하는 정반사광의 양을 지정 Emissive – 이 성분은 전반적인 표면의 컬러를 더하는데 사용되며, 물체 자체가 빛을 발하는 것처럼 좀더 밝은 물체 효과를 만들어냄 Power – 정반사광의 날카로운 정도(sharpness)를 지정하며, 값이 높아질수록 하이라이트가 강조 2010-1학기 컴퓨터게임(DIrectX)
::ZeroMemory(&red, sizeof(red)); 예를 들어 빨간 공을 원한다고 가정하면, 빨간빛만을 반사하고 다른 모든 빛을 흡수하도록 설정하면 됨 D3DMATERIAL9 red; ::ZeroMemory(&red, sizeof(red)); red.Diffuse=D3DXCOLOR(1.0f,0.0f,0.0f,1.0f);//빨간색 red.Ambient=D3DXCOLOR(1.0f,0.0f,0.0f,1.0f);//빨간색 red.Specular=D3DXCOLOR(1.0f,0.0f,0.0f,1.0f);//빨간색 red.Emissive=D3DXCOLOR(0.0f,0.0f,0.0f,1.0f);//빛을 발산하지 않음 red.Power=5.0f 예에서는 녹색과 청색 성분을 0으로 지정하여 재질이 두 가지 빛을 0%반사하도록 지정하고 적색 빛은 100%반사하도록 함. 2010-1학기 컴퓨터게임(DIrectX)
재질 구조체를 채우기 위한 유틸리티 함수 및 전역 재질 상수 제공(d3dUtility.h, d3dUtility.cpp 에) D3DMATERIAL9::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p); { D3DMATERIAL9 mtrl; mtrl.Ambient = a; mtrl.Diffuse = d; mtrl.Specular = s; mtrl.Emissive = e; mtrl.Power = p; return mtrl; } namespace d3d … 2010-1학기 컴퓨터게임(DIrectX)
const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 8.0f); D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p); const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 8.0f); const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 8.0f); const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 8.0f); const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 8.0f); const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 8.0f); 2010-1학기 컴퓨터게임(DIrectX)
D3DMATERIAL9 blueMaterial, redMaterial; … // 재질 구조체를 구성한다. 서로 다른 재질을 이용하는 몇 개의 물체를 렌더링할 때는 다음과 같이 IDirect3DDevice::SetMaterial(CONST D3DMATERIAL9* pMaterial) 메서드 이용 D3DMATERIAL9 blueMaterial, redMaterial; … // 재질 구조체를 구성한다. Device->SetMaterial(&blueMaterial); drawSphere(); // 파란색 구체 Device->SetMaterial(&redMaterial); drawSphere(); // 빨간색 구체 2010-1학기 컴퓨터게임(DIrectX)
버텍스 법선 버텍스 법선은 폴리곤을 구성하는 벡터에 대한 법선을 정의 (그림) 표면의 버텍스 법선 2010-1학기 컴퓨터게임(DIrectX)
Direct3D는 표면에 닿는 빛의 각도를 계산하기 위해 버텍스 법선을 필요로 함. 빛의 계산은 버텍스 단위로 수행되므로 각 버텍스의 표면 각도(법선)가 필요함. 주의할 점은 버텍스 법선과 면 법선이 동일한 것은 아님 버텍스의 버텍스 법선을 표기하기 위해서는 버텍스 구조체를 갱신해야 함 struct Vertex { float _x, _y, _z; float _nx, _ny, _nz; static const DWORD FVF; 2010-1학기 컴퓨터게임(DIrectX)
const DWORD Vertex::FVF=D3DFVF_XYZ|D3DFVF_NORMAL; } const DWORD Vertex::FVF=D3DFVF_XYZ|D3DFVF_NORMAL; 앞서 단원에서 이용하던 컬러 멤버가 제거됨: 버텍스의 컬러를 계산하는데 조명을 이용하기 위함. 단순한 물체의 경우에는 눈으로도 버텍스 법선을 볼 수 있지만, 복잡한 메쉬의 경우에 버텍스 법선을 보기 위해서는 기계적인 방법이 필요함. 버텍스 p0,p1,p2로 이루어진 삼각형이 있고, 버텍스 n0,n1,n2의 법선을 계산해야 한다고 가정해보자. 가장 간단한 방법은 세 개의 버텍스로 구성한 삼각형의 면 법선을 찾고, 이 면 법선을 버텍스 법선에 이용하는 것. 2010-1학기 컴퓨터게임(DIrectX)
void ComputeNormal(D3DXVECTOR3* p0, D3DXVECTOR3* p1, D3DXVECTOR3* p2, 먼저 삼각형에 있는 두 개의 벡터를 계산 p1-p0=u p2-p0=v 다음은 면 법선임 n=u×v 각각의 버텍스 법선은 면 법선과 같으므로, n0=n1=n2=n 다음의 C 함수는 삼각형의 세 버텍스 포인트에서 삼각형의 면 벡터를 계산해내는데, 이 함수는 버텍스가 시계 방향 두르기 순서를 이용하고 있다고 가정 void ComputeNormal(D3DXVECTOR3* p0, D3DXVECTOR3* p1, D3DXVECTOR3* p2, D3DXVECTOR3* out) { 2010-1학기 컴퓨터게임(DIrectX)
D3DXVec3Cross(out, &u, &v); D3DXVec3Normalize(out, out); } D3DXVECTOR3 u=*p1-*p0; D3DXVECTOR3 v=*p2-*p0; D3DXVec3Cross(out, &u, &v); D3DXVec3Normalize(out, out); } 삼각형으로 부드러운 표면을 표현할 때는 법선 평균을 수행함 예를 들어 면 법선 n0, n1, n2 를 가지면 버텍스 v 를 공유하는 세 개의 삼각형이 있을 때 vn = 1/3 * (n0 + n1 + n2); 변환 단계에서 버텍스 법선이 왜곡되는 현상이 발생할 수 있으므로, D3DRS_NORMALIZENORMALS 렌더 상태를 활성화하여 변환 단계 이후에 Direct3D가 모든 법선을 다시 정리하도록 하는 것이 안전 Device→SetRenderState(D3DRS_NORMALIZENORMALS, true); 2010-1학기 컴퓨터게임(DIrectX)
광원 세 가지 타입의 광원을 지원 점광원(point light) – 점 광원은 월드 스페이스 내에 위치를 가지며 모든 방향으로 빛을 발산함 방향성 광원(directional light) – 방향성 광원은 위치는 가지지 않지만 지정된 방향으로 평행하게 빛을 발산 스포트 광원(spot light) – 스포트 광원은 손전등 빛과 비슷하다. 광원은 위치를 가지며 특정한 방향으로 원뿔 형태의 빛을 발산 2010-1학기 컴퓨터게임(DIrectX)
광원을 지정하는 방법 typedef struct _D3DLIGHT9 { D3DLIGHTTYPE Type; D3DCOLORVALUE Diffuse; D3DCOLORVALUE Specular; D3DCOLORVALUE Ambient; D3DVECTOR Position; D3DVECTOR Direction; float Range; float Falloff; float Attenuation0; float Attenuation1; float Attenuation2; float Theta; float phi; } D3DLIGHT9; 2010-1학기 컴퓨터게임(DIrectX)
Diffuse – 광원이 발산하는 난반사광의 컬러 Specular – 광원이 발산하는 정반사광의 컬러 Type – 우리가 만들고자 하는 광원의 타입을 지정. D3DLIGHT_POINT, D3DLIGHT_SPOT, D3DLIGHT_DIRECTIONAL 중에 하나가 될 수 있음 Diffuse – 광원이 발산하는 난반사광의 컬러 Specular – 광원이 발산하는 정반사광의 컬러 Ambient – 광원이 발산하는 환경광의 컬러 Position – 광원의 위치를 정의하는 벡터. 방향성 광원의 경우에 이 값은 의미가 없음 Direction – 빛이 향하는 방향을 정의하는 벡터. 점 광원에서는 이 값을 이용하지 않음 Range- 빛이 완전히 소멸할 때까지 진행할 수 있는 최대 거리 Falloff – 이 값은 스포트 광원에서만 이용되며, 안쪽의 원뿔과 바깥쪽의 원뿔 간 빛의 세기 차이를 정의. 보통 1.0 지정 2010-1학기 컴퓨터게임(DIrectX)
Theta – 스포트 광원에서만 이용되며 안쪽 원뿔의 각도를 라디안으로 지정 Attenuation0, Attenuation1, Attenuation2 – 감쇠 변수는 거리에 따라 빛의 세기가 약해지는 정도를 정의하며 점 광원과 스포트 광원에서만 이용. Attenuation0은 상수 감소를, Attenuation1은 선형 감소를, Attenuation2는 이차 감소를 정의. 광원에서의 거리를 D로 하고, 각 Attenuation 값을 A0, A1, A2라고 할 때, 1 Attenuation = A0 + A1 * D + A2 * D2 Theta – 스포트 광원에서만 이용되며 안쪽 원뿔의 각도를 라디안으로 지정 Phi – 스포트 광원에서만 이용되며 바깥쪽 원뿔의 각도를 라디안으로 지정 2010-1학기 컴퓨터게임(DIrectX)
D3DMATERIAL9 구조체를 초기화하는 함수 정의: d3dUtility.h/cpp 파일에 간단한 광원의 초기화를 위한 다음과 같은 함수를 추가 namespace d3d { . D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color); D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DVECTOR3* direction, D3DXCOLOR* color); } 2010-1학기 컴퓨터게임(DIrectX)
InitDirectionalLight 구현 D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = *color * 0.4f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Direction = *direction; return light; } 2010-1학기 컴퓨터게임(DIrectX)
X 축의 양의 방향으로 평행하고 흰색 빛을 발산하는 방향성 광원을 만들고자 한다면 다음과 같이 코드 작성 D3DXVECTOR3 dir(1.0f,0.0f,0.0f); D3DXCOLOR c=d3d::WHITE; D3DLIGHT9 dirLight = d3d::InitDirectionalLight(&dir,&c); D3DLIGHT9 인스턴스를 초기화한 다음에는 Direct3D가 관리하는 내부 리스트에 이를 등록해야 함. 이 과정에서 다음과 같은 코드 형식을 이용 Device->SetLight( 0, //지원할 광원리스트 내의 요소, 범위는 0 – 최대광원 &light); //설정하려는 D3DLIGHT9 구조체의 주소 2010-1학기 컴퓨터게임(DIrectX)
Device->LightEnable( 0, // 활성화/비활성화하려는 광원 리스트 내의 요소 광원을 등록한 다음에는 다음과 같은 코드로 광원을 켜거나 끌 수 있음 Device->LightEnable( 0, // 활성화/비활성화하려는 광원 리스트 내의 요소 true); //true = 활성화, false = 비활성화 2010-1학기 컴퓨터게임(DIrectX)
예제 애플리케이션 조명을 활성화 각 물체의 재질을 만들고 해당 물체를 렌더링하기 전에 재질을 지정 장면에 광원을 추가하는 단계는 다음과 같음 조명을 활성화 각 물체의 재질을 만들고 해당 물체를 렌더링하기 전에 재질을 지정 한 개 이상의 광원을 만들고 광원을 지정한 후 이를 활성화 정반사광과 같은 부가적인 조명 상태를 활성화 먼저 피라미드의 버텍스를 보관할 전역 버텍스 버퍼 인스턴스를 만드는데, 코드는 다음과 같음 IDirect3DVertexBuffer9* Pyramid = 0; 2010-1학기 컴퓨터게임(DIrectX)
조명은 디폴트로 활성화 되어 있어 반드시 필요한 과정은 아니지만 활성화한다고 해서 손해가 있는 것이 아니니 활성화를 하자 Device->SetRenderState(D3DRS_LIGHTING,true); 다음은 버텍스 버퍼를 만들고 이를 잠근 다음, 피라미드의 삼각형을 구성하는 버텍스들을 지정. 삼각형들은 버텍스를 공유하기는 하지만 법선을 공유하지는 않는다는 점을 주의 이 물체의 인덱스 리스트를 이용하면 상당한 이익을 얻을 수 있는데, 예를 들어 모든 삼각형들은 정점 포인트(0, 1, 0)를 공유하지만, 정점 버텍스 법선은 다른 방향을 가리킴 2010-1학기 컴퓨터게임(DIrectX)
Device->CreateVertexBuffer( 12 * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &Pyramid, 0); // 피라미드 데이터로 버텍스 버퍼를 채운다 Vertex* v; Pyramid->Lock(0, 0, (void**)&v, 0); // 전면 v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f); v[1] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, -0.707f); v[2] = Vertex( 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f); 2010-1학기 컴퓨터게임(DIrectX)
v[3] = Vertex(-1.0f, 0.0f, 1.0f, -0.707f, 0.707f, 0.0f); // 왼쪽 측면 v[3] = Vertex(-1.0f, 0.0f, 1.0f, -0.707f, 0.707f, 0.0f); v[4] = Vertex( 0.0f, 1.0f, 0.0f, -0.707f, 0.707f, 0.0f); v[5] = Vertex(-1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f); // 오른쪽 측면 v[6] = Vertex( 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f); v[7] = Vertex( 0.0f, 1.0f, 0.0f, 0.707f, 0.707f, 0.0f); v[8] = Vertex( 1.0f, 0.0f, 1.0f, 0.707f, 0.707f, 0.0f); // 후면 v[9] = Vertex( 1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f); v[10] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, 0.707f); v[11] = Vertex(-1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f); Pyramid->Unlock(); 2010-1학기 컴퓨터게임(DIrectX)
mtrl.Ambient = d3d::WHITE; mtrl.Diffuse = d3d::WHITE; 물체의 버텍스 데이터를 생성한 다음에는 물체의 재질을 정의하여 물체와 조명이 상호작용하는 방법을 지정. 이 예제에서 피라미드는 흰색 빛을 반사하며, 빛을 발산하지 않고 약간의 반사광을 만들어 냄 D3DMATERIAL9 mtrl; mtrl.Ambient = d3d::WHITE; mtrl.Diffuse = d3d::WHITE; mtrl.Specular = d3d::WHITE; mtrl.Emissive = d3d::BLACK; mtrl.Power = 5.0f; Device->SetMaterial(&mtrl); 2010-1학기 컴퓨터게임(DIrectX)
::ZeroMemory(&dir, sizeof(dir)); dir.Type = D3DLIGHT_DIRECTIONAL; 다음은 하나의 방향성 광원을 만들고 이를 활성화하였고, 이 광원은 x축의 양의 방향으로 평행하게 빛을 발산하며, 광원은 강한 흰색 난반사광(dir.Diffuse = WHITE)과 약간 흰색 정반사광(dir.Specular = WHITE * 0.3f), 그리고 중간 정도의 환경광(dir.Ambient = WHITE * 0.6f)을 발산 D3DLIGHT9 dir; ::ZeroMemory(&dir, sizeof(dir)); dir.Type = D3DLIGHT_DIRECTIONAL; dir.Diffuse = d3d::WHITE; dir.Specular = d3d::WHITE * 0.3f; dir.Ambient = d3d::WHITE * 0.6f; dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f); // Set and Enable the light. Device->SetLight(0, &dir); Device->LightEnable(0, true); 2010-1학기 컴퓨터게임(DIrectX)
마지막으로 법선을 정리하도록 렌더 상태를 지정하고 정반사광을 활성화 Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); Device->SetRenderState(D3DRS_SPECULARENABLE, true); 2010-1학기 컴퓨터게임(DIrectX)
실행 결과 2010-1학기 컴퓨터게임(DIrectX)
IDirect3DDevice9* Device = 0; const int Width = 640; #include "d3dUtility.h" IDirect3DDevice9* Device = 0; const int Width = 640; const int Height = 480; IDirect3DVertexBuffer9* Pyramid = 0; // Classes and Structures struct Vertex { Vertex(){} Vertex(float x, float y, float z, float nx, float ny, float nz) _x = x; _y = y; _z = z; _nx = nx; _ny = ny; _nz = nz; } float _x, _y, _z; float _nx, _ny, _nz; 2010-1학기 컴퓨터게임(DIrectX)
static const DWORD FVF; }; const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL; bool Setup() { Device->SetRenderState(D3DRS_LIGHTING, true); Device->CreateVertexBuffer( 12 * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &Pyramid, 0); Vertex* v; Pyramid->Lock(0, 0, (void**)&v, 0); 2010-1학기 컴퓨터게임(DIrectX)
v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f); // front face v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f); v[1] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, -0.707f); v[2] = Vertex( 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f); // left face v[3] = Vertex(-1.0f, 0.0f, 1.0f, -0.707f, 0.707f, 0.0f); v[4] = Vertex( 0.0f, 1.0f, 0.0f, -0.707f, 0.707f, 0.0f); v[5] = Vertex(-1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f); // right face v[6] = Vertex( 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f); v[7] = Vertex( 0.0f, 1.0f, 0.0f, 0.707f, 0.707f, 0.0f); v[8] = Vertex( 1.0f, 0.0f, 1.0f, 0.707f, 0.707f, 0.0f); // back face v[9] = Vertex( 1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f); v[10] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, 0.707f); v[11] = Vertex(-1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f); 2010-1학기 컴퓨터게임(DIrectX)
Pyramid->Unlock(); D3DMATERIAL9 mtrl; mtrl.Ambient = d3d::WHITE; mtrl.Diffuse = d3d::WHITE; mtrl.Specular = d3d::WHITE; mtrl.Emissive = d3d::BLACK; mtrl.Power = 5.0f; Device->SetMaterial(&mtrl); D3DLIGHT9 dir; ::ZeroMemory(&dir, sizeof(dir)); dir.Type = D3DLIGHT_DIRECTIONAL; dir.Diffuse = d3d::WHITE; dir.Specular = d3d::WHITE * 0.3f; dir.Ambient = d3d::WHITE * 0.6f; dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f); 2010-1학기 컴퓨터게임(DIrectX)
Device->SetLight(0, &dir); Device->LightEnable(0, true); Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); Device->SetRenderState(D3DRS_SPECULARENABLE, true); D3DXVECTOR3 pos(0.0f, 1.0f, -3.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH(&V, &pos, &target, &up); Device->SetTransform(D3DTS_VIEW, &V); D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, // 90 - degree (float)Width / (float)Height, 1.0f, 1000.0f); 2010-1학기 컴퓨터게임(DIrectX)
Device->SetTransform(D3DTS_PROJECTION, &proj); return true; } void Cleanup() { d3d::Release<IDirect3DVertexBuffer9*>(Pyramid); bool Display(float timeDelta) if( Device ) D3DXMATRIX yRot; static float y = 0.0f; D3DXMatrixRotationY(&yRot, y); y += timeDelta; 2010-1학기 컴퓨터게임(DIrectX)
Device->SetTransform(D3DTS_WORLD, &yRot); if( y >= 6.28f ) y = 0.0f; Device->SetTransform(D3DTS_WORLD, &yRot); Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); Device->BeginScene(); Device->SetStreamSource(0, Pyramid, 0, sizeof(Vertex)); Device->SetFVF(Vertex::FVF); Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4); Device->EndScene(); Device->Present(0, 0, 0, 0); } return true; 2010-1학기 컴퓨터게임(DIrectX)
::PostQuitMessage(0); break; case WM_KEYDOWN: LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); } return ::DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, 2010-1학기 컴퓨터게임(DIrectX)
if(!d3d::InitD3D(hinstance, PSTR cmdLine, int showCmd) { if(!d3d::InitD3D(hinstance, Width, Height, true, D3DDEVTYPE_HAL, &Device)) ::MessageBox(0, "InitD3D() - FAILED", 0, 0); return 0; } if(!Setup()) ::MessageBox(0, "Setup() - FAILED", 0, 0); d3d::EnterMsgLoop( Display ); Cleanup(); 2010-1학기 컴퓨터게임(DIrectX)
Device->Release(); return 0; } 2010-1학기 컴퓨터게임(DIrectX)
2010-1학기 컴퓨터게임(DIrectX)