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

📄 water.cpp

📁 如果你想学习3D编程
💻 CPP
📖 第 1 页 / 共 4 页
字号:

//-----------------------------------------------------------------------------
// Name: MsgProc
// Desc:
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, 
                                    LPARAM lParam )
{
    switch( uMsg )
    {
        case WM_KEYDOWN:
            m_bKey[wParam] = TRUE;
            break;

        case WM_KEYUP:
            m_bKey[wParam] = FALSE;
            break;

        case WM_COMMAND:
        {
            switch( LOWORD(wParam) )
            {
            case IDM_ADDDROP:
                m_Water.Drop();
                break;

            case IDM_NEXT_TECHNIQUE:
                GetNextTechnique(1, FALSE);
                break;

            case IDM_NEXT_TECHNIQUE_NOVALIDATE:
                GetNextTechnique(1, TRUE);
                break;

            case IDM_PREV_TECHNIQUE:
                GetNextTechnique(-1, FALSE);
                break;

            case IDM_PREV_TECHNIQUE_NOVALIDATE:
                GetNextTechnique(-1, TRUE);
                break;

            case IDM_TOGGLEHELP:
                m_bShowHelp = !m_bShowHelp;
                break;
            }
        }
    }

    return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}


//////////////////////////////////////////////////////////////////////////////
// Types /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#pragma pack(4)
struct ENV_VERTEX
{
    D3DXVECTOR3 m_vecPos;
    D3DXVECTOR2 m_vecTex;

    static const DWORD FVF;
};

const DWORD ENV_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);




//////////////////////////////////////////////////////////////////////////////
// CEnvironment implementation ///////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

CEnvironment::CEnvironment()
{
    m_fSize = 1.0f;
    m_pDevice = NULL;

    memset(m_pSurf, 0x00, sizeof(m_pSurf));
}


CEnvironment::~CEnvironment()
{
}


HRESULT CEnvironment::Initialize(float fSize)
{
    m_fSize = fSize;
    return S_OK;
}


HRESULT CEnvironment::OnCreateDevice(IDirect3DDevice9* pDevice)
{
    m_pDevice = pDevice;
    return S_OK;
}


HRESULT CEnvironment::OnResetDevice()
{
    return S_OK;
}


HRESULT CEnvironment::OnLostDevice()
{
    return S_OK;
}


HRESULT CEnvironment::OnDestroyDevice()
{
    return S_OK;
}


HRESULT CEnvironment::SetSurfaces(
    IDirect3DTexture9* pXNeg, IDirect3DTexture9* pXPos, 
    IDirect3DTexture9* pYNeg, IDirect3DTexture9* pYPos,
    IDirect3DTexture9* pZNeg, IDirect3DTexture9* pZPos)
{
    m_pSurf[0] = pXNeg;
    m_pSurf[1] = pXPos;
    m_pSurf[2] = pYNeg;
    m_pSurf[3] = pYPos;
    m_pSurf[4] = pZNeg;
    m_pSurf[5] = pZPos;

    return S_OK;
}


HRESULT CEnvironment::Draw()
{
    float f;
    ENV_VERTEX vert[4];

    f = 0.5f / 512.0f;

    vert[0].m_vecTex = D3DXVECTOR2(0.0f + f, 0.0f + f);
    vert[1].m_vecTex = D3DXVECTOR2(0.0f + f, 1.0f - f);
    vert[2].m_vecTex = D3DXVECTOR2(1.0f - f, 0.0f + f);
    vert[3].m_vecTex = D3DXVECTOR2(1.0f - f, 1.0f - f);

    m_pDevice->SetFVF(ENV_VERTEX::FVF);
    f = m_fSize * 0.5f;

    // XNeg
    vert[0].m_vecPos = D3DXVECTOR3(-f,  f,  f);
    vert[1].m_vecPos = D3DXVECTOR3(-f, -f,  f);
    vert[2].m_vecPos = D3DXVECTOR3(-f,  f, -f);
    vert[3].m_vecPos = D3DXVECTOR3(-f, -f, -f);

    m_pDevice->SetTexture(0, m_pSurf[0]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));

    // XPos
    vert[0].m_vecPos = D3DXVECTOR3( f,  f, -f);
    vert[1].m_vecPos = D3DXVECTOR3( f, -f, -f);
    vert[2].m_vecPos = D3DXVECTOR3( f,  f,  f);
    vert[3].m_vecPos = D3DXVECTOR3( f, -f,  f);

    m_pDevice->SetTexture(0, m_pSurf[1]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));

    // YNeg
    vert[0].m_vecPos = D3DXVECTOR3(-f, -f, -f);
    vert[1].m_vecPos = D3DXVECTOR3(-f, -f,  f);
    vert[2].m_vecPos = D3DXVECTOR3( f, -f, -f);
    vert[3].m_vecPos = D3DXVECTOR3( f, -f,  f);

    m_pDevice->SetTexture(0, m_pSurf[2]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
    
    // YPos
    vert[0].m_vecPos = D3DXVECTOR3(-f,  f,  f);
    vert[1].m_vecPos = D3DXVECTOR3(-f,  f, -f);
    vert[2].m_vecPos = D3DXVECTOR3( f,  f,  f);
    vert[3].m_vecPos = D3DXVECTOR3( f,  f, -f);

    m_pDevice->SetTexture(0, m_pSurf[3]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));

    // ZNeg
    vert[0].m_vecPos = D3DXVECTOR3(-f,  f, -f);
    vert[1].m_vecPos = D3DXVECTOR3(-f, -f, -f);
    vert[2].m_vecPos = D3DXVECTOR3( f,  f, -f);
    vert[3].m_vecPos = D3DXVECTOR3( f, -f, -f);

    m_pDevice->SetTexture(0, m_pSurf[4]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));

    // ZPos
    vert[0].m_vecPos = D3DXVECTOR3( f,  f,  f);
    vert[1].m_vecPos = D3DXVECTOR3( f, -f,  f);
    vert[2].m_vecPos = D3DXVECTOR3(-f,  f,  f);
    vert[3].m_vecPos = D3DXVECTOR3(-f, -f,  f);

    m_pDevice->SetTexture(0, m_pSurf[5]);
    m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));

    return S_OK;
}


#define WATER_SHIFT 6
#define WATER_SIZE  (1 << WATER_SHIFT)
#define WATER_AREA  (WATER_SIZE * WATER_SIZE)
#define WATER_MASK  (WATER_SIZE - 1)

#define WATER_SPHERE_HEIGHT   20.0f
#define WATER_SPHERE_RADIUS2  (35.0f * 35.0f)

#define WATER_INDEX(x, y) \
    ((x) | ((y) << WATER_SHIFT))

#define WATER_INDEX_WRAP(x, y) \
    (((x) & WATER_MASK) | (((y) & WATER_MASK) << WATER_SHIFT))


#if defined(_X86) && !defined(_WIN64)
inline int f2i(float flt) 
{
	volatile int n; 

	__asm 
	{
		fld flt
		fistp n
	}

	return n;
}
#else
inline int f2i(float flt) 
{
	return (int) flt;
}
#endif



//////////////////////////////////////////////////////////////////////////////
// Types /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#pragma pack(1)
struct WATER_VERTEX
{
    D3DXVECTOR3 m_vecPos;
    D3DXVECTOR3 m_vecNormal;
    D3DCOLOR    m_dwDiffuse;
    D3DXVECTOR2 m_vecTex;

    static const DWORD FVF;

};
const DWORD WATER_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE 
        | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);


struct CAUSTICS_VERTEX
{
    D3DXVECTOR3 m_vecPos;
    D3DCOLOR    m_dwDiffuse;

    static const DWORD FVF;

};
const DWORD CAUSTICS_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

#pragma pack()


//////////////////////////////////////////////////////////////////////////////
// CWater implementation /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

CWater::CWater()
{
    m_fDepth    = 0.0f;
    m_fScaleTex = 1.0f;

    m_uIndices  = 0;
    m_uVertices = 0;

    m_pRefract     = NULL;
    m_pSurface     = NULL;

    m_pDevice      = NULL;
    m_pibIndices   = NULL;
    m_pvbVertices  = NULL;
    m_pvbCaustics  = NULL;
}


CWater::~CWater()
{
    if(m_pSurface)
        delete [] m_pSurface;
}


HRESULT CWater::Initialize(float fSize, float fDepth)
{
    m_fSize = fSize;
    m_fDepth = fDepth;
    m_fScaleTex = 1.0f / fSize;

    // Calculate number of vertices and indices
    m_uVertices = WATER_AREA;
    m_uIndices  = m_uVertices * 2;

    // Create refraction table
    static WATER_REFRACT Refract[512];

    if(!m_pRefract)
    {
        m_pRefract = &Refract[256];

        for(UINT u = 0; u < 256; u++)
        {        
            float fCos0 = (float) u / (float) 256.0f;
            float f0 = acosf(fCos0);
            float fSin0 = sinf(f0);

            float fSin1 = fSin0 / 1.333f; // water
            float f1 = asinf(fSin1);
            float fCos1 = cosf(f1);
        
            m_pRefract[u].fRefract = fSin0 / fSin1 * fCos1 - fCos0;
            m_pRefract[u].fRefractNorm = - fSin1 / fSin0;
            m_pRefract[u].dwDiffuse = ((((0xff - u)*(0xff - u)*(0xff - u)) << 8) & 0xff000000);

            Refract[u] = Refract[256];
        }
    }

    // Create maps
    if(!m_pSurface)
    {
        if( ( m_pSurface = new WATER_SURFACE[WATER_AREA] ) == NULL )
            return E_OUTOFMEMORY;

        memset(m_pSurface, 0x00, WATER_AREA * sizeof(WATER_SURFACE));
    }

    return S_OK;
}




HRESULT CWater::OnCreateDevice(IDirect3DDevice9 *pDevice)
{
    m_pDevice = pDevice;
    return S_OK;
}




HRESULT CWater::OnResetDevice()
{
    HRESULT hr;

    // Create indices
    if(!m_pibIndices)
    {
        WORD *pwIndices;

        if(FAILED(hr = m_pDevice->CreateIndexBuffer(m_uIndices * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
            D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibIndices, NULL)))
        {
            return hr;
        }

        if(FAILED(hr = m_pibIndices->Lock(0, m_uIndices * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD)))
            return hr;

        // Fill in indicies
        UINT uX = 0, uZ = 0;
        WORD *pwIndex = pwIndices;

        for(UINT uSize = WATER_SIZE; uSize != 0; uSize -= 2)
        {
            UINT u;

            // Top
            for(u = 0; u < uSize; u++)
            {
                *pwIndex++ = uX + uZ * WATER_SIZE;
                *pwIndex++ = uX + uZ * WATER_SIZE + WATER_SIZE;
                uX++;
            }

            uX--;
            uZ++;

            // Right
            for(u = 1; u < uSize; u++)

⌨️ 快捷键说明

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