Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Cutting Edge Direct 3D Programming
(Publisher: The Coriolis Group)
Author(s): Stan Trujillo
ISBN: 1576100502
Publication Date: 11/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


The OnPaint() Function

Direct3D also expects to be notified when an application receives a WM_PAINT message. The Direct3DRMWinDevice interface supports a HandlePaint() member function for this purpose, so the OnPaint() function looks similar to the OnActivate() function. The major difference is that we use the OnPaint() function to invoke the CreateDevice() function the first time that OnPaint() is called. The OnPaint() function appears like this:

void RMWin::OnPaint()
{
    static BOOL first = TRUE;
    if (first)
    {
        first = FALSE;
        BOOL ok=CreateDevice();
        if (!ok)
            PostQuitMessage(0);
    }

    if (GetUpdateRect(NULL, FALSE)==FALSE)
        return;

    if (device)
    {
        LPDIRECT3DRMWINDEVICE windev;
        PAINTSTRUCT ps;
        BeginPaint(&ps);
        if (device->QueryInterface(IID_IDirect3DRMWinDevice,
          (void**)&windev)==0)
        {
            if (windev->HandlePaint(ps.hdc)!=0)
                AfxMessageBox("windev->HandlePaint() failure");
            windev->Release();
        }
        else
            AfxMessageBox("Failed to create Windows device to handle
              WM_PAINT");
        EndPaint(&ps);
    }
}

A static flag is used to determine when the OnPaint() function is first called. If the CreateDevice() function returns FALSE, the program is terminated. The flag is set to TRUE so that the CreateDevice() function is only called once.

The GetUpdateRect() function is used to determine if a repaint is necessary. If the GetUpdateRect() function returns FALSE, then no portion of the window needs redrawing, and the function returns.

The remainder of the function is similar to the OnActivate() function. The QueryInterface() function is used to retrieve the Direct3DRMWinDevice interface pointer, and the pointer is used to call the HandlePaint() function.

The OnSize() Function

The OnSize() function is called by MFC whenever a WM_SIZE message is received. The message indicates that the user has resized the window. The RMWin class provides an OnSize() function to reconfigure the device and the viewport to reflect the window’s new dimensions.

Direct3D devices cannot be resized. This means that when a window is re-sized, the existing device must be destroyed and replaced with a new device. If it is necessary to destroy the existing device, the OnSize() function stores the current device settings and uses them to configure the new device. The OnSize() function looks like this:

void RMWin::OnSize(UINT type, int cx, int cy)
{
    CFrameWnd::OnSize(type, cx, cy);
    if (!device)
        return;

    int width = cx;
    int height = cy;
    if (width && height)
    {
        int view_width = viewport->GetWidth();
        int view_height = viewport->GetHeight();
        int dev_width = device->GetWidth();
        int dev_height = device->GetHeight();

        if (view_width == width && view_height == height)
            return;
        int old_dither = device->GetDither();
        D3DRMRENDERQUALITY old_quality = device->GetQuality();
        int old_shades = device->GetShades();

        viewport->Release();
        device->Release();
        d3drm->CreateDeviceFromClipper( clipper, GetGUID(), width,
          height, &device );

        device->SetDither(old_dither);
        device->SetQuality(old_quality);
        device->SetShades(old_shades);

        width = device->GetWidth();
        height = device->GetHeight();
        d3drm->CreateViewport(device, camera, 0, 0, width, height,
          &viewport);
    }
}

The function minimizes the number of cases in which the existing device must be destroyed. This is done by checking to make sure that the new window dimensions are valid and that the window size has, in fact, changed.

If a new device must be created, the CreateDeviceFromClipper() function is used just as it was in the CreateDevice() function. After the new device has been created and configured, a new viewport is created as well.

The OnEraseBkgnd() Function

Direct3D allows you to specify background colors with the Direct3DRMFrame SetSceneBackground() function, but when a window is resized, Windows erases the contents of the client area without regard for the Direct3D background color. By default, Windows uses white to erase the client area.

MFC provides the CWnd::OnEraseBkgnd() function to override the default Windows behavior. The RMWin class provides a version of OnEraseBkgnd() that uses the current Direct3D background color to erase the client area. The code looks like this:

BOOL RMWin::OnEraseBkgnd( CDC* pDC )
{
    COLORREF bgcolor;
    if (scene)
    {
        D3DCOLOR scenecolor=scene->GetSceneBackground();
        bgcolor=D3DCOLOR_2_COLORREF(scenecolor);
    }
    else
        bgcolor=RGB(0,0,0);

    CBrush br( bgcolor );
    CRect rc;
    GetClientRect(&rc);
    pDC->FillRect(&rc, &br);
    return TRUE;
}

The function declares an instance of the COLORREF type and assigns it to the current Direct3D background color. The D3DCOLOR_2_COLORREF() function converts the D3DCOLOR type to the COLORREF type. We’ll look at this function later. If the scene frame has not yet been created, black is used.

The COLORREF instance is then used to create a CBrush object, and the dimensions of the client area are retrieved. The CDC::FillRect() function is used to color the client area of the window, and the function returns TRUE to notify MFC that the function was successful.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited.