⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 direct.html

📁 非常好的在win32下用c++sdk开发的工具书
💻 HTML
📖 第 1 页 / 共 2 页
字号:
        }
        void SetCoopNormal (HWND h)
        {
            HRESULT res = _pDraw->SetCooperativeLevel(h, 
                                                      DDSCL_NORMAL);
            if(res != DD_OK) 
                throw "Cannot set normal cooperative level";
        }
        IDirectDraw * operator-> () { return _pDraw; }
    private:
        IDirectDraw * _pDraw;
    };
}

// implementation file

using namespace Direct;

Draw::Draw ()
{
    HRESULT res = ::DirectDrawCreate (0, &_pDraw, 0);
    if(res != DD_OK) 
        throw "Cannot create Direct Draw object";
}</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->

<hr>
<p>DirectDraw is based on COM interfaces, so it makes sense to encapsulate the "interface magic" in a handy template. The Direct::IFace class takes care of reference counting, pointer dereferencing and assignment (see the assignment of surfaces above).

<!--Yellow background-->       <table cellpadding=10 cellspacing=0 width=100%>
                <tr>
                      <td width=20>&nbsp;</td>
                      <td bgcolor="#e0e080"><font color="black">
<pre>template&lt;class I&gt;
class IFace
{
public:
    IFace (IFace&lt;I&gt; &amp; i)
    {
        i-&gt;AddRef ();
        _i = i._i;
    }
    ~IFace ()
    {
        if (_i)
            _i-&gt;Release ();
    }
    void operator = (IFace&lt;I&gt; &amp; i)
    {
        if (i._i)
            i._i-&gt;AddRef ();
        if (_i)
            _i-&gt;Release ();
        _i = i._i;
    }
    I * operator-&gt; () { return _i; }
    operator I * () { return _i; }

protected:

    IFace () : _i (0) {}
protected:

    I * _i;
};</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->
<hr>
<p>A drawing surface is an example of an interface. First we define a generic surface, then we'll specialize it to primary and off-screen surfaces.

<!--Yellow background-->       <table cellpadding=10 cellspacing=0 width=100%>
                <tr>
                      <td width=20>&nbsp;</td>
                      <td bgcolor="#e0e080"><font color="black">
<pre>class Surface: public IFace&lt;IDirectDrawSurface&gt;
{
    friend class SurfaceBuf;
protected:
    // Locking and unlocking the whole surface
    void Lock (SurfaceDesc &amp; desc)
    {
        assert (_i != 0);
        HRESULT res;
        do
            res = _i-&gt;Lock (0, &amp;desc, 0, 0);
        while (res == DDERR_WASSTILLDRAWING);

        if(res != DD_OK) 
            throw "Cannot lock surface";
    }
    void Unlock ()
    {
        assert (_i != 0);
        _i-&gt;Unlock (0);
    }
public:
    Surface () {}

    void GetDescription (SurfaceDesc &amp; desc)
    {
        HRESULT res = _i-&gt;GetSurfaceDesc (&desc);
        if(res != DD_OK) 
            throw "Cannot get surface description";
    }

    void SetClipper (Clipper & clipper)
    {
        assert (_i != 0);
        HRESULT res = _i-&gt;SetClipper (clipper);
        if(res != DD_OK) 
            throw "Cannot set clipper";
    }
    void BltFrom (Surface &amp; src, RECT * dstRect = 0, RECT * srcRect = 0)
    {
        assert (_i != 0);
        HRESULT res = _i-&gt;Blt (dstRect, src._i, srcRect, 0, 0);
        if(res != DD_OK) 
            throw "Cannot perform a blt";
    }
    void Fill (COLORREF color);
};</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->

<p>When you create a surface, it has to be one of the derived ones. The primary surface lets you draw directly on your screen, the off-screen surface lets you prepare a picture off-screen in a format that can be very quickly transferred to the screen.

<!--Yellow background-->       <table cellpadding=10 cellspacing=0 width=100%>
                <tr>
                      <td width=20>&nbsp;</td>
                      <td bgcolor="#e0e080"><font color="black">
<pre>class PrimarySurface: public Surface
{
public:
    PrimarySurface () {}
    PrimarySurface (Draw &amp; draw) { Init (draw); }
    void Init (Draw &amp; draw)
    {
        SurfaceDesc desc;
        desc.SetCapabilities (DDSCAPS_PRIMARYSURFACE);
        HRESULT res = draw->CreateSurface (&amp;desc, &amp;_i, 0);
        if(res != DD_OK) 
            throw "Cannot create primary surface";
    }
};

class OffScreenSurface: public Surface
{
public:
    OffScreenSurface () {}
    OffScreenSurface (Draw &amp; draw, int width, int height) 
    { Init (draw, width, height); }
    void Init (Draw &amp; draw, int width, int height)
    {
        SurfaceDesc desc;
        desc.SetCapabilities (DDSCAPS_OFFSCREENPLAIN);
        desc.SetDimensions (width, height);
        HRESULT res = draw->CreateSurface (&amp;desc, &amp;_i, 0);
        if(res != DD_OK) 
            throw "Cannot create off-screen surface";
    }
};</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->

<hr>
<p>In order to directly access pixels in a surface, you have to lock it. The class, SurfaceBuf, encapsulates locking and unlocking in its constructor and destructor, so that you don't have to worry about it. It also provides direct access to the buffer through its SetPixel method. Notice the low-level address calculations and color formatting.

<!--Yellow background-->       <table cellpadding=10 cellspacing=0 width=100%>
                <tr>
                      <td width=20>&nbsp;</td>
                      <td bgcolor="#e0e080"><font color="black">
<pre>class SurfaceBuf
{
public:
    SurfaceBuf (Surface &amp; surface)
        : _surface (surface)
    {
        SurfaceDesc desc;
        surface.Lock (desc);
        _pitch = desc.Pitch ();
        _buf = static_cast&lt;unsigned char *&gt; (desc.Buffer ());
        _format.Init (desc);
        int bpp = _format.BitsPp ();
        if (bpp != 16 &amp;&amp; bpp != 24 &amp;&amp; bpp != 32)
        {
            surface.Unlock ();
            throw "Only high color and true color supported";
        }
    }
    ~SurfaceBuf ()
    {
        _surface.Unlock ();
    }
    void SetPixel (int x, int y, COLORREF color)
    {
        switch (_format.BitsPp ())
        {
        case 16:
            {
                int offset = y * _pitch + x * 2;
                unsigned short * p = reinterpret_cast&lt;unsigned short *&gt; (
                                     _buf + offset);
                *p &amp;= _format.Mask ();
                *p |= static_cast&lt;unsigned short> (
                      _format.ColorValue16 (color));
            }
            break;
        case 24:
            {
                int offset = y * _pitch + x * 3;
                unsigned long * p = reinterpret_cast&lt;unsigned long *&gt; (
                                    _buf + offset);
                *p &amp;= _format.Mask ();
                *p |= _format.ColorValue24 (color);
            }
            break;
        case 32:
            {
                int offset = y * _pitch + x * 4;
                unsigned long * p = reinterpret_cast&lt;unsigned long *&gt; (
                                    _buf + offset);
                *p &amp;= _format.Mask ();
                *p |= _format.ColorValue32 (color);
            }
            break;
        }
    }
private:
    Surface   &amp; _surface;
    unsigned char  * _buf;
    int            _pitch;
    PixelFormat    _format;
};</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->

<p>There is a separate class to deal with the formatting of color values. As you can see, depending on the bits-per-pixel setting of the video card, different color encodings are used. The surface descriptor contains bit masks that are used in this encoding. These masks vary not only between bpp settings, but also between video cards. The most complex is the encoding of the color for 1the 6-bit setting. In 32-bit mode the card can actually support more colors that can be packed into the standard Windows COLORREF. Here, we're not making use of it, but it would be an interesting area to experiment.

<!--Yellow background-->       <table cellpadding=10 cellspacing=0 width=100%>
                <tr>
                      <td width=20>&nbsp;</td>
            	      <td bgcolor="#e0e080"><font color="black">
<pre>class PixelFormat
{
public:
    PixelFormat () {}
    PixelFormat (SurfaceDesc &amp; desc)
    {
        Init (desc);
    }
    void Init (SurfaceDesc &amp; desc);
    int BitsPp () const { return _bpp; }
    unsigned long Mask () const { return _mask; }
    unsigned long ColorValue16 (COLORREF color)
    {
        return (
              (GetRValue (color) &lt;&lt; _redShift) &amp; (_redMask &lt;&lt; 16)
            | (GetGValue (color) &lt;&lt; _greenShift) &amp; (_greenMask &lt;&lt; 16)
            | (GetBValue (color) &lt;&lt; _blueShift) &amp; (_blueMask &lt;&lt; 16))
            &gt;&gt; 16;
    }
    unsigned long ColorValue24 (COLORREF color)
    {
        return
              (GetRValue (color) &lt;&lt; 16) &amp; _redMask
            | (GetGValue (color) &lt;&lt; 8) &amp; _greenMask
            | GetBValue (color) &amp; _blueMask;
    }
    unsigned long ColorValue32 (COLORREF color)
    {
        return
              (GetRValue (color) &lt;&lt; 16) &amp; _redMask
            | (GetGValue (color) &lt;&lt; 8) &amp; _greenMask
            | GetBValue (color) &amp; _blueMask;
    }
    unsigned long ColorValue (COLORREF color)
    {
        switch (_bpp)
        {
        case 16:
            return ColorValue16 (color);
        case 24:
            return ColorValue24 (color);
        case 32:
            return ColorValue32 (color);
        default:
            throw "PixelFormat: only 16, 24 and 32 bits supported";
        }
    }

private:
    int              _bpp; // bits per pixel 4, 8, 16, 24, or 32
    unsigned long    _redMask;
    unsigned long    _greenMask;
    unsigned long    _blueMask;
    unsigned         _redShift;
    unsigned         _greenShift;
    unsigned         _blueShift;
    unsigned long    _mask;
};

unsigned HiBitShift (unsigned val)
{
    unsigned i = 0;
    while (val != 0)
    {
        val &gt;&gt;= 1;
        ++i;
    }
    return i;
}

void PixelFormat::Init (SurfaceDesc &amp; desc)
{
    DDPIXELFORMAT &amp; format = desc.PixelFormat ();
    if (format.dwFlags != DDPF_RGB)
        throw "Direct Draw: Non-RGB formats not supported";
    _bpp = format.dwRGBBitCount;
    _redMask = format.dwRBitMask;
    _greenMask = format.dwGBitMask;
    _blueMask = format.dwBBitMask;
    _mask = ~(_redMask | _greenMask | _blueMask);
    switch (_bpp)
    {
    case 16:
        _redShift   = HiBitShift (_redMask) + 8;
        _greenShift = HiBitShift (_greenMask) + 8;
        _blueShift  = HiBitShift (_blueMask) + 8;
        break;
    case 24:
        break;
    case 32:
        break;
    default:
        throw "Only 16, 24 and 32 bit graphics supported";
    }
}</pre><!--End Code--></font>
                       </td>
                       <td width=20>&nbsp;</td>
        </tr>
        </table>
<!--End of yellow background-->
<hr>
<p>Notice that this tutorial only scratches the surface of DirectX. There are several versions of DirectDraw. There is Direct3D for three-dimensional graphics (although it seems like Open GL might be a better platform). Sound can be dealt with using DirectSound and input devices have their DirectInput. All these subsystems can be encapsulated using similar techniques.
<hr>
   </font>
   <!-- end main box -->
   </td></tr>
   </table>
   </td>
   <td width=10><!-- Right margin -->&nbsp;</td>
   </tr>
</table> <!-- End main table -->

<layer src="http://www.spidersoft.com/ads/bwz468_60.htm" visibility=hidden id=a1 width=600 onload="moveToAbsolute(ad1.pageX,ad1.pageY); a1.clip.height=60;visibility='show';"></layer>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -