-
Displaying a Window in Full-Screen Mode in DirectX [Language: C++]정리필요2 2008. 6. 30. 22:50
[devpia 고영준님 글]
msdn 에 있는 걸 한번 번역해 봤습니다.
directX 에서 FSWINDOW 예제와 관련된 겁니다.
Displaying a Window in Full-Screen Mode [Language: C++]
In full-screen mode, DirectDraw has exclusive control over the display. As a result, dialog boxes and other windows created through GDI are not normally visible. However, by using special techniques you can incorporate a Windows dialog box, HTML Help, or any other kind of window in your application.
풀-스크린 모드에서, DirectDraw는 디스플레이 위에 배타적으로 컨트롤을 하게됩니다. 결과적으로, GDI를 통해 생성되는 대화상자와 다른윈도우들은 보통 보이지 않습니다. 그러나, 특별한 테크닉을 사용함으로서 당신은 여러종류의 윈도우들과 협조할수 있을 것입니다.The FSWindow Sample illustrates how a dialog box can be displayed and updated in a full-screen application, and how mouse clicks and keystrokes work just as if the dialog box were being displayed by GDI.
FSWindow Sample은 풀-스크린 애플리캐이션 에서 어떻게 보여지고 업데이트 되는지를 보여주며, GDI에 의해 디스플레이되어질 때 처럼 마우스 클릭이 어떻게 클릭되는지와 키보드 눌림이 작동하는지를 보여줄것이다.In FSWindow, the dialog box is created and "shown" as an ordinary dialog window:
hWndDlg = CreateDialog(g_hInstance,
MAKEINTRESOURCE(IDD_DIALOG_SAMPLE),
hWnd, (DLGPROC) SampleDlgProc);
ShowWindow(hWndDlg, SW_SHOWNORMAL);
Of course, at this point the dialog box is shown only on the hidden GDI surface. It does not appear on the primary surface, which is controlled by DirectDraw.
물론, 이 시점에서는 대화상자가 숨겨진 GDI 표면에서만 보여질 뿐이다. DirectDraw가 컨트롤하는 주표면에는 보이지 않게 된다.If the hardware capabilities include DDCAPS2_CANRENDERWINDOWED (see DDCAPS), displaying and updating the dialog box is easy. The application simply calls the IDirectDraw7::FlipToGDISurface method, which makes the GDI surface the primary surface. From now on, all updates to the dialog box will be displayed automatically, because GDI is now rendering directly to the front buffer. The application continues rendering to the back buffer, and on each pass through the rendering loop the contents of the back buffer are blitted to the front buffer by DirectDraw. The dialog box is not overwritten because the front buffer is clipped to the application window, and the dialog box is obscuring part of that window.
만약 하드웨어가 DDCAPS2_CANRENDERWINDOWED 호환성을 가지고 있다면(DDCAPS 참조), 대화상자를 보여주고 업데이트 하는 것은 쉬운 일이다. 애플리캐이션에서 단순하게 IDirectDraw7::FlipToGDISurface 메서드를 호출하므로서 GDI 서피스를 프라이머리로 만들어준다. 이제부터, 대화상자로 업데이트되는 모든 것들이 자동적으로 보여지게 될 것이다. 왜냐하면, GDI는 이제부터 저면 버퍼로 직접 렌더링을 하기 때문이다. 응용프로그램은 후면 버퍼에 렌더링을 계속하게되고, 렌더링을 통한 후면 버퍼의 목차대로 순환하는 각 경로는 DirectDraw에 의해 전면 버퍼로 블릿된다. 대화상자는 덮여쓰여지지 않는데, 그 이유는 전면버퍼는 응용 프로그램에 대해 클립되며, 대화상자는 윈도우의 obscuring part 이기 때문이다.
The following code, from the FSWindow_Init function, creates the clipper, associates it with the application window, and brings the GDI surface to the front:
FSWindow_Init function 으로부터 나온 다음 코드는, 클리퍼를 생성하여, 응용프로그램에 연계시키고, GDI서피스를 프론트로 가져옵니다.
if (ddObject->CreateClipper(0, &ddClipper, NULL) == DD_OK)
ddClipper->SetHWnd(0, hwndAppWindow);
ddObject->FlipToGDISurface();
Then, in the FSWindow_Update function, the following code blits the rendered contents of the back buffer to the clipping region:
그리고 FSWindow_Update 함수에서 다음 코드는 백버퍼의 렌더링된 내용들을 클리핑 영역에 블리팅한다.
ddFrontBuffer->SetClipper(ddClipper);
ddFrontBuffer->Blt(NULL, ddBackBuffer, NULL, DDBLT_WAIT, NULL);
Note that because the GDI surface is the primary surface, Windows continues displaying the mouse cursor. (This would not be the case, however, if the application were using DirectInput with the mouse device at the exclusive cooperative level.)
참고:GDI 서피스는 주 표면이 아니기 때문에, 윈도우는 마우스커서를 계속 디스플레이 합니다.(만약 응용프로그램이 다이렉트 인풋을 배타적 협력수준으로 사용하고 있다면 그 경우가 아닐 수도있지만)
For hardware that does not have the DDCAPS2_CANRENDERWINDOWED capability, the process of displaying and updating a window in full-screen mode is somewhat more complicated. In this case, the application is responsible for obtaining the image of the window created by GDI and blitting it to the back buffer after the full-screen rendering has been done. The entire back buffer is then flipped to the front in the usual way.
하드웨어가 DDCAPS2_CANRENDERWINDOWED 호환성을 가지고 있지 않았다면, 디스플레이 과정과 풀-스크린 모드의 윈도우 업데이트는 다소 복잡해 집니다. 이 경우에 응용프로그램은 GDI와 풀-스크린 렌더링이 수행된 후에 후면버퍼로 블리팅 함으로서 생성되어지는 윈도우의 이미지를 포함할 책임이 있습니다. 모든 후면 버퍼는 이후에 보통 방법으로 플리핑됩니다.The FSWindow sample provides two different methods for accessing the display memory of the window, depending on whether the content is static or dynamic. The method for static content is faster because it involves blitting from a memory device context rather than a screen device context. This method should be used for windows that do not change, such as informational dialog boxes. (Remember, though, that unless you manually update the bitmap in response to events, even basic animation such as a button press will not be visible to the user.)
FSWindow sample은 컨텐트가 정적이냐 동적이냐에 의존하여 윈도우의 디스플레이 메모리를 액세스 하는 두가지 다른 방법을 제공합니다. 정적 컨텐트를 위한 방법이 더 빠른데 그 이유는 그것이 메모리 디바이스 콘텍스트로부터라기 보다는 스크린 디바이스 컨텍스트쪽에 연관되어 있기 때문입니다. 이 메서드는 바뀌지 않을 윈도우(정보만 나타내는 대화상자 같은)에 사용되어져야만 합니다.(기억해야할 것은 당신이 수동으로 이벤트에 반응하여 비트맵을 업데이트 하여도, 버튼 누르기 같은 기본 애니매이션 조차도 사용자에게는 보이지 않을 것입니다.)
If the content is static, FSWindow calls the CreateBMPFromWindow function when the window is initialized. This function creates a bitmap and blits the contents of the window into it. The bitmap handle is stored in the global variable hwndFSWindowBMP. Whenever the primary surface is about to be updated, this bitmap is blitted to the back buffer, as follows:
만약 컨텐트가 정적이라면, 윈도우가 초기화 될 때FSWindow는 CreateBMPFromWindow 함수를 호출합니다. 이 함수는 비트맵을 생성하고 윈도우의 컨텐트를 그곳으로 블리팅합니다. 그 비트맵 핸들은 hwndFSWindowBMP라는 전 역변수에 저장됩니다. 프라이머리 서피스가 업데이트 될때마다, 이 비트맵은 다음과 같이 후면 버퍼에 블릿됩니다:
if (FSWindow_IsStatic)
{
hdcMemory = CreateCompatibleDC(NULL);
SelectObject(hdcMemory, hwndFSWindowBMP);
BitBlt(hdcBackBuffer, x, y, cx, cy, hdcMemory, 0, 0, SRCCOPY);
DeleteDC(hdcMemory);
}
If, on the other hand, the content of the window is dynamic, the following code is executed. It blits the image directly from the GDI surface (represented by the hdcScreen device context) to the back buffer.
만약, 반면에, 윈도우의 컨텐트 가 동적이라면, 다음코드가 실행됩니다. 이것은 이미지를 GDI 서피스(hdcScreen device context에 의해 나타내어지는)로부터 후면버퍼로 직접 블릿합니다.
BitBlt(hdcBackBuffer, x, y, cx, cy, hdcScreen, x, y, SRCCOPY);
The coordinates represent the position and dimensions of the window on the GDI surface, as retrieved through a call to GetWindowRect.
좌표계는 GDI 서피스위의 윈도우 위치와 면적을 나타내며, GetWindowRect호출을 통해 얻어집니다.
When the FSWindow application is running on hardware that does not have the DDCAPS2_CANRENDERWINDOWED capability, it does not use the GDI surface, so Windows cannot display the mouse cursor. The application takes over this task by obtaining information about the cursor and displaying it on the back buffer just before the flip.
FSWindow application이 DDCAPS2_CANRENDERWINDOWED 호환성을 가지지 않는 하드웨어에서 작동할때에는 GDI 서피스를 사용하지 않으며, 따라서 윈도우는 마우스 커서를 출력하지 않습니다. 응용 프로그램은 이 작업을 커서에 대한 정보를 얻어내고 플립 전에 그것을 백버퍼에 출력함으로서 이 작업을 수행합니다.