04. marts 2002 - 12:49
#3
Jo, DirectDraw eksisterer ikke længere (8.0+)
Jeg bruger selv denne klasse, prøv at se om den ikke har hvad du skal bruge...
#include <D3dx8tex.h>
// Some D3DCOLOR shortcut macros:
#define DRGBA(r,g,b,a) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
#define DRGB(r,g,b) ((D3DCOLOR)(((0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
#define GetB(rgb) ((BYTE)(rgb))
#define GetG(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetR(rgb) ((BYTE)((rgb)>>16))
#define GetA(rgb) ((BYTE)((rgb)>>24))
// Flags Used by DrawRect()
#define DR3DLOOK 0x01
#define DR3DLOOK2 0x02
class CSprite
{
public:
CSprite::CSprite();
HRESULT Create(LPDIRECT3DDEVICE8 pd3dDevice, char* pFilename);
HRESULT InvalidateDeviceObjects();
HRESULT RestoreDeviceObjects(LPDIRECT3DDEVICE8 pd3dDevice);
HRESULT DeleteDeviceObjects();
HRESULT LoadTexture(char *filename);
HRESULT BltSprite(RECT *pDestRect, RECT *pSrcRect, DWORD dwFlags);
HRESULT BltSpriteEx(RECT *pDestRect, RECT *pSrcRect, DWORD dwFlags,
D3DCOLOR modulate = 0xFFFFFFFF, float rotation = 0, POINT *prcenter = NULL);
HRESULT DrawRect(RECT rc, DWORD fillstyle, D3DCOLOR fillcolor, int bordersize,
D3DCOLOR bordercolor, DWORD drflags);
LPDIRECT3DDEVICE8 m_pd3dDevice; // A D3DDevice used for rendering
LPDIRECT3DTEXTURE8 m_pd3dTexture;
LPD3DXSPRITE m_pd3dxSprite;
};
#include "Sprite.h"
#include <ddraw.h>
#include "DXUtil.h"
CSprite::CSprite()
{
m_pd3dDevice = NULL;
m_pd3dTexture = NULL;
m_pd3dxSprite = NULL;
}
HRESULT CSprite::Create(LPDIRECT3DDEVICE8 pd3dDevice, char* pFilename)
{
m_pd3dDevice = pd3dDevice;
LoadTexture(pFilename);
if(FAILED(D3DXCreateSprite(m_pd3dDevice, &m_pd3dxSprite)))
return E_FAIL;
return S_OK;
}
HRESULT CSprite::InvalidateDeviceObjects()
{
SAFE_RELEASE(m_pd3dxSprite);
return S_OK;
}
HRESULT CSprite::RestoreDeviceObjects(LPDIRECT3DDEVICE8 pd3dDevice)
{
m_pd3dDevice = pd3dDevice;
if(FAILED(D3DXCreateSprite(m_pd3dDevice, &m_pd3dxSprite)))
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Destroys all device-dependent objects
//-----------------------------------------------------------------------------
HRESULT CSprite::DeleteDeviceObjects()
{
SAFE_RELEASE(m_pd3dTexture);
SAFE_RELEASE(m_pd3dxSprite);
m_pd3dDevice = NULL;
return S_OK;
}
//----------------------------------------------------------------------------
// LoadTexture() : Load a texture from a file, returns ptr to texture.
// D3DX8 supports BMP, PPM, DDS, JPG, PNG, TGA & DIB.
//----------------------------------------------------------------------------
HRESULT CSprite::LoadTexture(char* pFilename)
{
// Set black as our source color key. Use 0xFFFF00FF for magenta instead.
// Use 0x00000000 for no 'color key' substitution
D3DCOLOR colorkey = 0xFF000000;
// The D3DX function will fill in the following image info for us
D3DXIMAGE_INFO SrcInfo; // Optional
// Load image from file - maintain size of original file.
// It is also possible to specify a new height/width and ask D3DX to filter
// the image to the new size (stretch/shrink). See SDK docs for details.
return D3DXCreateTextureFromFileEx(m_pd3dDevice, pFilename, 0, 0, 1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,
colorkey, &SrcInfo , NULL, &m_pd3dTexture);
}
//----------------------------------------------------------------------------
// BltSprite() : A replacement of the DirectDraw Blt() function for Direct3D8
// Supports DDBLTFX_MIRRORLEFTRIGHT and DDBLTFX_MIRRORUPDOWN
// If pDestRect is NULL, copies it to the same co-ord as src
// If pSrcRect is NULL, copies the entire texture
//----------------------------------------------------------------------------
HRESULT CSprite::BltSprite(RECT *pDestRect, RECT *pSrcRect, DWORD dwFlags)
{
D3DXVECTOR2 scaling(1,1), rcenter(0,0), trans(0,0);
// Set the parameters - translation (screen location)
if (pDestRect)
{
trans.x = (float) pDestRect->left;
trans.y = (float) pDestRect->top;
}
// Scaling - If Source & Destination are different size rects, then scale
if (pDestRect && pSrcRect)
{
scaling.x = ((float) (pDestRect->right - pDestRect->left)) /
((float) (pSrcRect->right - pSrcRect->left));
scaling.y = ((float) (pDestRect->bottom - pDestRect->top)) /
((float) (pSrcRect->bottom - pSrcRect->top));
}
// Handle the flags - need to change scaling & adjust translation
if (pSrcRect && dwFlags)
{
if (dwFlags&DDBLTFX_MIRRORLEFTRIGHT)
{
scaling.x = -scaling.x;
trans.x += (float) (pDestRect->right - pDestRect->left);
}
if (dwFlags&DDBLTFX_MIRRORUPDOWN)
{
scaling.y = -scaling.y;
trans.y += (float) (pDestRect->bottom - pDestRect->top);
}
}
// And here we go:
return m_pd3dxSprite->Draw(m_pd3dTexture, pSrcRect, &scaling,
&rcenter, 0, &trans, 0xFFFFFFFF);
}
//----------------------------------------------------------------------------
// BltSpriteEx() : A replacement of the DirectDraw Blt() function for Direct3D8
// Supports DDBLTFX_MIRRORLEFTRIGHT and DDBLTFX_MIRRORUPDOWN,
// modulate is color/alpha modifier
// rotation is value of rotation in RADIANS, counter-clockwise
// prcenter is the rotation centre point of the obj, or NULL
// If pDestRect is NULL, copies it to the same co-ord as src
// If pSrcRect is NULL, copies the entire texture
//----------------------------------------------------------------------------
HRESULT CSprite::BltSpriteEx(RECT *pDestRect, RECT *pSrcRect, DWORD dwFlags,
D3DCOLOR modulate, float rotation, POINT *prcenter)
{
D3DXVECTOR2 scaling(1,1), rcenter(0,0), trans(0,0);
// Set the parameters - translation (screen location)
if (pDestRect) {
trans.x = (float) pDestRect->left;
trans.y = (float) pDestRect->top;
}
// Rotation Center
if (prcenter) {
rcenter.x = (float) prcenter->x;
rcenter.y = (float) prcenter->y;
} else if (pSrcRect) {
// Set Rotation Center to be object center if none provided
rcenter.x = (float) (pSrcRect->right - pSrcRect->left) / 2;
rcenter.y = (float) (pSrcRect->bottom - pSrcRect->top) / 2;
}
// Scaling - If Source & Destination are different size rects, then scale
if (pDestRect && pSrcRect) {
scaling.x = ((float) (pDestRect->right - pDestRect->left)) /
((float) (pSrcRect->right - pSrcRect->left));
scaling.y = ((float) (pDestRect->bottom - pDestRect->top)) /
((float) (pSrcRect->bottom - pSrcRect->top));
}
// Handle the flags - need to change scaling & adjust translation
if (pSrcRect && dwFlags) {
if (dwFlags&DDBLTFX_MIRRORLEFTRIGHT) {
scaling.x = -scaling.x;
trans.x += (float) (pDestRect->right - pDestRect->left);
}
if (dwFlags&DDBLTFX_MIRRORUPDOWN) {
scaling.y = -scaling.y;
trans.y += (float) (pDestRect->bottom - pDestRect->top);
}
}
// And here we go:
return m_pd3dxSprite->Draw(m_pd3dTexture, pSrcRect, &scaling,
&rcenter, rotation, &trans, modulate);
}
//-----------------------------------------------------------------------------
// DrawRect() : Draws a rect on 'the viewport' using Clear, with some options
// This is not a Microsoft-endorsed use of the Clear command!
// Note that the Alpha values of colors are significant - 0xFF for opaque
// fillstyle: GDI values of BS_SOLID or BS_NULL (hollow)
// bordersize is -ve for internal to rectangle
// drflags are DR3DLOOK or DR3DLOOK2 for embossed shadow button effects
//-----------------------------------------------------------------------------
HRESULT CSprite::DrawRect(RECT rc, DWORD fillstyle, D3DCOLOR fillcolor, int bordersize,
D3DCOLOR bordercolor, DWORD drflags)
{
// Error if not a normal rectangle
if (rc.bottom-rc.top < 1) return DDERR_INVALIDPARAMS;
if (rc.right-rc.left < 1) return DDERR_INVALIDPARAMS;
// First, we do the inside (fill) part
switch (fillstyle) {
case BS_SOLID:
// Fill area is full size of rectangle
m_pd3dDevice->Clear( 1, (D3DRECT *)&rc, D3DCLEAR_TARGET,
fillcolor, 1.0f, 0);
break;
case BS_NULL:
default:
// No fill or unknown, no action
break;
}
// This handles drawing the borders (four sides)
if (bordersize != 0) {
D3DCOLOR topbord=bordercolor, botbord=bordercolor;
RECT brc;
// Adjust for border outside of rect if +ve border size:
if (bordersize > 0) {
rc.left -= bordersize;
rc.right += bordersize;
rc.top -= bordersize;
rc.bottom += bordersize;
bordersize = -bordersize;
}
// Embossed effect flags:
if (drflags & DR3DLOOK) {
topbord = DRGB( (GetR(bordercolor)+255)/2,
(GetG(bordercolor)+255)/2, (GetB(bordercolor)+255)/2 );
botbord = DRGB( (GetR(bordercolor))/2,
(GetG(bordercolor))/2, (GetB(bordercolor))/2 );
} else if (drflags & DR3DLOOK2) {
// Reversed shadow, for 'selected' look
topbord = DRGB( (GetR(bordercolor))/2,
(GetG(bordercolor))/2, (GetB(bordercolor))/2 );
botbord = DRGB( (GetR(bordercolor)+255)/2,
(GetG(bordercolor)+255)/2, (GetB(bordercolor)+255)/2 );
}
// Draw top and left
SetRect(&brc, rc.left, rc.top, rc.right, rc.top - bordersize);
m_pd3dDevice->Clear( 1, (D3DRECT *)&brc, D3DCLEAR_TARGET,
topbord, 1.0f, 0);
SetRect(&brc, rc.left, rc.top, rc.left-bordersize, rc.bottom);
m_pd3dDevice->Clear( 1, (D3DRECT *)&brc, D3DCLEAR_TARGET,
topbord, 1.0f, 0);
// Draw bottom and right
SetRect(&brc, rc.left, rc.bottom+bordersize, rc.right, rc.bottom);
m_pd3dDevice->Clear( 1, (D3DRECT *)&brc, D3DCLEAR_TARGET,
botbord, 1.0f, 0);
SetRect(&brc, rc.right+bordersize, rc.top, rc.right, rc.bottom);
m_pd3dDevice->Clear( 1, (D3DRECT *)&brc, D3DCLEAR_TARGET,
botbord, 1.0f, 0);
}
return S_OK;
}