중간고사 담당교수 : 단국대학교멀티미디어공학전공박경신 답은반드시답안지에기술할것. 공간이부족할경우반드시답안지몇쪽의뒤에있다고명기한후기술할것. 그외의경우의답안지뒤쪽이나연습지에기술한내용은답안으로인정안함. 답에는반드시네모를쳐서확실히표시할것. 답안지에학과, 학번, 이름외에본인의암호를기입하면성적공고시학번대신암호를사용할것임. 1. 비디오게임의역사에대한질문입니다. 다음문제의답을아래의보기에서찾으시오 ( 보너스 extra 10점 ). Pong, Pac-Man, DOOM, DeathRace, Atari, Mortal Kombat, SONY, Wii, Spacewar, Ultima Online, Defender, Lineage, Computer Space, VCS 1) Ed Rottberg가개발한최초의 1인칭시점게임은 이다. 2) ID Software 사가개발한중독성높은 FPS (1인칭슈팅 ) 게임은 이다. 3) 전세계적으로 300,000 이상이판매된남녀모두에게인기있었던최초의비디오게임은 Namco사의 이다. 4) 모션센서기술이들어있는콘트롤러를사용하는게임기는 이다. 5) 1961년 MIT의 Steve Russell이최초의상호작용적인컴퓨터게임 을개발하였다. 6) 1972년 Nolan Bushnell이 Atari사를만들고간단한비디오테니스게임인 을개발하여큰성공을거둔다. 이게임최초의성공적인상업용게임이었다. 7) 1976년최초로비디어게임의폭력성에대한미디어의주목을받았으며결국은시장에서사라지게된이게임은 이다. 8) 1982년 VCS 판매가부진함을공고하여 Warner 주식이하루만에 32% 폭락한현상을두고 쇼크라부른다. 9) 1997년 Richard Garriott 과 Ralph Koster 가개발한일인용 RPG 게임은 이다. 10) 1998년한국에서온라인게임의산업화와사회적문제에영향을미친게임은 이다. 2. 다음은광선 (Ray: p(t) = p 0 + tu) 과평면 (Plane: ax + by + cz + d = 0) 의교차점을구하는 Direct3D 코드의일부이다. 빈칸을완성하시오. (10점) typedef struct _RAY { D3DXVECTOR3 p; D3DXVECTOR3 u; RAY; 1/10
BOOL RayPlaneIntersection (D3DXPLANE* plane, RAY line, D3DXVECTOR3* out) { FLOAT denom = if (denom == 0) float t = if (t < 0) *out = line.p + t*line.u; return true; void main() { D3DXPLANE plane(1, 0, 0, 1); RAY ray1, ray2; ray1.p = D3DXVECTOR3(1, 0, 0); ray1.u = D3DXVECTOR3(-1, -1, 0); ray2.p = D3DXVECTOR3(0, 0, -2); ray2.u = D3DXVECTOR3(1, 1, 1); ray3.p = D3DXVECTOR3(1, 1, 0); ray3.u = D3DXVECTOR3(1, 1, 1); D3DXVECTOR3 out1, out2; if (RayPlaneIntersection(&plane, ray1, &out1)) cout << "out1 = " << out1 << endl; // _ 출력결과 : if (RayPlaneIntersection(&plane, ray2, &out2)) cout << "out2 = " << out2 << endl; // _ 출력결과 : if (RayPlaneIntersection(&plane, ray3, &out3)) cout << "out3 = " << out3 << endl; // _ 출력결과 : 3. 다음은 d3dutility.cpp 프로그램의 InitD3D 함수를보여주고있다. 빈칸에설명을넣으시오 (10점). bool d3d::initd3d(hinstance hinstance,int width, int height, bool windowed, D3DDEVTYPE devicetype,idirect3ddevice9** device) { // Create the main application window. WNDCLASS wc; wc.style = CS_HREDRAW CS_VREDRAW; wc.lpfnwndproc = (WNDPROC)d3d::WndProc; wc.cbclsextra = 0; wc.cbwndextra = 0; wc.hinstance = hinstance; wc.hicon = LoadIcon(0, IDI_APPLICATION); wc.hcursor = LoadCursor(0, IDC_ARROW); wc.hbrbackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszmenuname = 0; wc.lpszclassname = "Direct3D9App"; if(!registerclass(&wc) ) { ::MessageBox(0, "RegisterClass() - FAILED", 0, 0); HWND hwnd = 0; 2/10
hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", WS_EX_TOPMOST, 0, 0, width, height, 0 /*parent hwnd*/, 0 /* menu */, hinstance, 0 /*extra*/); if(!hwnd ) { ::MessageBox(0, "CreateWindow() - FAILED", 0, 0); ::ShowWindow(hwnd, SW_SHOW); ::UpdateWindow(hwnd); // Init D3D HRESULT hr = 0; // Step 1: IDirect3D9* d3d9 = 0; d3d9 = Direct3DCreate9(D3D_SDK_VERSION); if(!d3d9 ) { ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0); // Step 2: D3DCAPS9 caps; d3d9->getdevicecaps(d3dadapter_default, devicetype, &caps); int vp = 0; if( caps.devcaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Step 3: D3DPRESENT_PARAMETERS d3dpp; d3dpp.backbufferwidth = width; d3dpp.backbufferheight = height; d3dpp.backbufferformat = D3DFMT_A8R8G8B8; d3dpp.backbuffercount = 1; d3dpp.multisampletype = D3DMULTISAMPLE_NONE; d3dpp.multisamplequality = 0; d3dpp.swapeffect = D3DSWAPEFFECT_DISCARD; d3dpp.hdevicewindow = hwnd; d3dpp.windowed = windowed; d3dpp.enableautodepthstencil = true; d3dpp.autodepthstencilformat = D3DFMT_D24S8; d3dpp.flags = 0; d3dpp.fullscreen_refreshrateinhz = D3DPRESENT_RATE_DEFAULT; d3dpp.presentationinterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Step 4: hr = d3d9->createdevice( D3DADAPTER_DEFAULT, // primary adapter devicetype, // device type hwnd, // window associated with device 3/10
vp, &d3dpp, device); // vertex processing // present parameters // return created device // Step 5: if( FAILED(hr) ) { d3dpp.autodepthstencilformat = D3DFMT_D16; hr = d3d9->createdevice( D3DADAPTER_DEFAULT, devicetype, hwnd, vp, &d3dpp, device); if( FAILED(hr) ) { d3d9->release(); // done with d3d9 object ::MessageBox(0, "CreateDevice() - FAILED", 0, 0); d3d9->release(); // done with d3d9 object return true; 4. 깊이버퍼링 (Depth buffering) 에대해설명하고, Direct3D에서사용할수있는깊이버퍼 (Depth buffer) 의 format을하나이상예로들어라 (10점). 4/10
5. 단위벡터회전축에 θ만큼회전 (rotate) 하는행렬 (matrix) 는아래의공식과같이간단히정의될수있다. 이공식을이용하여회전축 (1, 1, 0) 에 45도회전 (rotate) 하는 3x3 행렬 (matrix) R을유도하라. (10점) R = Icosθ + Symmetric (1 cosθ ) + Skew sinθ 2 ax Symmetric = axay axaz 0 az Skew = az 0 ay ax cos45 = sin 45 = 2 2 a a x y 2 ay a y a z a y a 0 x a xaz ayaz 2 a z 6. 다음은두픽셀값을여러가지방법으로블렌딩하는것을보여주고있다. 각블렌딩방식의최종값을식으로나타내라. 이때 srcpixel은 C s 로, destpixel은 C d 로표현한다 (20점). 먼저, 알파블렌딩으로나타나는최종색 (outputpixel) 을식으로표현하라. // 블렌딩을활성화한다. d3ddev->setrenderstate(d3drs_alphablendenable, TRUE); // 블렌딩설정방법 (Blending Operation) 을지정한다. // 즉, outputpixel = srcpixel*srcblendfactor + destpixel*dstblendfactor d3ddev->setrenderstate(d3drs_blendop, D3DBLENDOP_ADD); // 알파블렌딩팩터 (Source와 Destination Factor) 를지정한다. Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); outputpixel = 5/10
그리고, 덧셈블렌딩은 Source와 Destination Factor를다음과같이지정한다. 이블렌딩의최종색 (outputpixel) 을식으로표현하라. // 덧셈블렌딩팩터 (Source와 Destination Factor) 를지정한다. Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); outputpixel = 그리고, 곱셈블렌딩은 Source와 Destination Factor를다음과같이지정한다. 이블렌딩의최종색 (outputpixel) 을식으로표현하라. // 곱셈블렌딩팩터 (Source와 Destination Factor) 를지정한다. Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); outputpixel = 그리고, 원래이미지의보색 (inverted color) 블렌딩은 Source와 Destination Factor를다음과같이지정한다. 이블렌딩의최종색 (outputpixel) 을식으로표현하라. // 반전색블렌딩팩터 (Source와 Destination Factor) 를지정한다. Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); outputpixel = 그리고, 알파블렌딩을설정한채로불투명한것을그리고싶을때 Source와 Destination Factor를다음과같이지정한다. 이블렌딩의최종색 (outputpixel) 을식으로표현하라. // 곱셈블렌딩팩터 (Source와 Destination Factor) 를지정한다. Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); outputpixel = 7. 다음은 litpyramid 예제프로그램의일부를보여주고있다. 다음프로그램의함수들이렌더링파이프라인상에어느곳에관련있는지아래빈칸에찾아넣어라. (20점) 6/10
--litpyramid.cpp IDirect3DDevice9* Device = 0; const int Width = 640; const int Height = 480; IDirect3DVertexBuffer9* Pyramid = 0; 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; 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); // front, left, right, back face 중간생략 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); 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); 7/10
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); Device->SetTransform(D3DTS_PROJECTION, &proj); return true; bool Display(float timedelta) { if( Device ) { D3DXMATRIX yrot; static float y = 0.0f; D3DXMatrixRotationY(&yRot, y); y += timedelta; 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; 버텍스 / 인덱스버퍼 (Vertex/Index Buffer) 드로잉 (Drawing) 함수 DrawPrimitive 조명 (Lighting) & 재질 (Material) 함수 Device->SetRenderState(D3DRS_LIGHTING, true); 모델링변환 (world transformation) 8/10
뷰잉변환 (view transformation) 투영변환 (projection transformation) 8. D3DXMatrixReflect(D3DXMATRIX *pout, CONST D3DXPLANE *pplane) 함수는반사행렬을만들어내는함수이다. 점 P(x,y,z) 가표준좌표평면인 xy-plane, xz-plane, yz-plane에반사되어진점 P 을각각그림으로나타내고그값을계산하라. (10점). 9. 다음아래의그림과같은텍스쳐매핑을하기위해텍스쳐좌표를계산하라. 빈칸을채우시오. (10점). bool Setup() { Device->CreateVertexBuffer(3*sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &Tri, 0); Vertex* v; Tri->Lock(0, 0, (void**)&v, 0); v[0] = Vertex(-1,-1, 1, 0, 0, -1,, ); v[1] = Vertex( 0, 1, 1, 0, 0, -1,, ); v[2] = Vertex( 1,-1, 1, 0, 0, -1,, ); Tri->Unlock(); D3DXCreateTextureFromFile(Device, dx5_logo.bmp, & Tex); Device->SetTexture(0, Tex); Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); 9/10
. 10/10