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

📄 renderd3dwnd.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage0[i].dwDesiredValue != SavedTextureStage0[i].dwValue)
			m_pD3DDev->SetTextureStageState(0, SavedTextureStage0[i].Type, SavedTextureStage0[i].dwDesiredValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage1[i].dwDesiredValue != SavedTextureStage1[i].dwValue)
			m_pD3DDev->SetTextureStageState(1, SavedTextureStage1[i].Type, SavedTextureStage1[i].dwDesiredValue);
	}

	// Draw the Logo
	m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 );

	// Restore state
	m_pD3DDev->SetVertexShader(dwVertexShader);
	m_pD3DDev->SetStreamSource(0, pVB, VBStride);
	m_pD3DDev->SetTexture(0, pTexture0);
	m_pD3DDev->SetPixelShader(dwPixelShader);

	SAFE_RELEASE(pTexture0);
	SAFE_RELEASE(pVB);

	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		if (SavedRender[i].dwDesiredValue != SavedRender[i].dwValue)
			m_pD3DDev->SetRenderState(SavedRender[i].Type, SavedRender[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage0[i].dwDesiredValue != SavedTextureStage0[i].dwValue)
			m_pD3DDev->SetTextureStageState(0, SavedTextureStage0[i].Type, SavedTextureStage0[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage1[i].dwDesiredValue != SavedTextureStage1[i].dwValue)
			m_pD3DDev->SetTextureStageState(1, SavedTextureStage1[i].Type, SavedTextureStage1[i].dwValue);
	}

	return S_OK;
}

HRESULT CRenderD3DWnd::ResizeLogo()
{
	IDirect3DSurface8* pBackBuffer;
	m_pD3DDev->GetRenderTarget(&pBackBuffer);
	D3DSURFACE_DESC ddsd;

	pBackBuffer->GetDesc(&ddsd);

	SAFE_RELEASE(pBackBuffer);

	// Create a quad for the final pass
    TLVertex* v;
    FLOAT sx = (FLOAT)ddsd.Width;
    FLOAT sy = (FLOAT)ddsd.Height;

	// Make logo full size at 800x600
	float fScale = sx * sy / (800 * 600.0f);
	if (fScale > 1.0f)
		fScale = 1.0f;

	HRESULT hr;
	hr = m_pLogoVB->Lock( 0, 0, (BYTE**)&v, 0 );
	if (SUCCEEDED(hr))
	{
		v[0].Position = D3DXVECTOR4(0, sy, 0, 1);
		v[0].Diffuse = 0xffffffff;
		v[0].Specular = 0;
		v[0].Texture = D3DXVECTOR2(0, 1);

		v[1].Position = D3DXVECTOR4(0, sy - (64.0f * fScale), 0, 1);
		v[1].Diffuse = 0xffffffff;
		v[1].Specular = 0;
		v[1].Texture = D3DXVECTOR2(0, 0);
    
		v[2].Position = D3DXVECTOR4((512.0f * fScale), sy, 0, 1);
		v[2].Diffuse = 0xffffffff;
		v[2].Specular = 0;
		v[2].Texture = D3DXVECTOR2(1, 1);

		v[3].Position = D3DXVECTOR4((512.0f * fScale), sy - (64.0f * fScale), 0, 1);
		v[3].Diffuse = 0xffffffff;
		v[3].Specular = 0;
		v[3].Texture = D3DXVECTOR2(1, 0);

		m_pLogoVB->Unlock();
	}
	else
	{
		return E_FAIL;
	}

	return S_OK;
}

HRESULT CRenderD3DWnd::SetupTextBuffer()
{
    // Create vertex buffer for the characters
    HRESULT hr = m_pD3DDev->CreateVertexBuffer( MAX_FONT_VERTICES*sizeof(FONT2DVERTEX), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
                                                       D3DPOOL_DEFAULT, &m_pFontVB);
	return hr;
}

HRESULT CRenderD3DWnd::FreeTextBuffer()
{
	SAFE_RELEASE(m_pFontVB);
	return S_OK;
}

HRESULT CRenderD3DWnd::SetupTextImage()
{
	HRESULT hr;


    // Establish the font and texture size
    m_fFontTextScale  = 1.0f; // Draw fonts into texture without scaling

    // Large fonts need larger textures
    if( m_dwFontHeight > 40 )
        m_dwFontTexWidth = m_dwFontTexHeight = 1024;
    else if( m_dwFontHeight > 20 )
        m_dwFontTexWidth = m_dwFontTexHeight = 512;
    else
        m_dwFontTexWidth  = m_dwFontTexHeight = 256;

    // If requested texture is too big, use a smaller texture and smaller font,
    // and scale up when rendering.
    D3DCAPS8 d3dCaps;
    m_pD3DDev->GetDeviceCaps( &d3dCaps );

    if( m_dwFontTexWidth > d3dCaps.MaxTextureWidth )
    {
        m_fFontTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwFontTexWidth;
        m_dwFontTexWidth = m_dwFontTexHeight = d3dCaps.MaxTextureWidth;
    }

    // Create a new texture for the font
    hr = m_pD3DDev->CreateTexture( m_dwFontTexWidth, m_dwFontTexHeight, 1,
                                      0, D3DFMT_A4R4G4B4,
                                      D3DPOOL_MANAGED, &m_pFontTexture );
    if( FAILED(hr) )
        return hr;

    // Prepare to create a bitmap
    DWORD*      pBitmapBits;
    BITMAPINFO bmi;
    ZeroMemory( &bmi.bmiHeader,  sizeof(BITMAPINFOHEADER) );
    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth       =  (int)m_dwFontTexWidth;
    bmi.bmiHeader.biHeight      = -(int)m_dwFontTexHeight;
    bmi.bmiHeader.biPlanes      = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biBitCount    = 32;

    // Create a DC and a bitmap for the font
    HDC     hDC       = CreateCompatibleDC( NULL );
    HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
                                          (VOID**)&pBitmapBits, NULL, 0 );
    SetMapMode( hDC, MM_TEXT );

    // Create a font.  By specifying ANTIALIASED_QUALITY, we might get an
    // antialiased font, but this is not guaranteed.
    INT nHeight    = -MulDiv( m_dwFontHeight, 
        (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fFontTextScale), 72 );
    DWORD dwBold   = (m_dwFontFlags & D3DFONT_BOLD)   ? FW_BOLD : FW_NORMAL;
    DWORD dwItalic = (m_dwFontFlags & D3DFONT_ITALIC) ? TRUE    : FALSE;
    HFONT hFont    = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic,
                          FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
                          CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
                          VARIABLE_PITCH, m_strFontName );
    if( NULL==hFont )
        return E_FAIL;

    SelectObject( hDC, hbmBitmap );
    SelectObject( hDC, hFont );

    // Set text properties
    SetTextColor( hDC, RGB(255,255,255) );
    SetBkColor(   hDC, 0x00000000 );
    SetTextAlign( hDC, TA_TOP );

    // Loop through all printable character and output them to the bitmap..
    // Meanwhile, keep track of the corresponding tex coords for each character.
    DWORD x = 0;
    DWORD y = 0;
    TCHAR str[2] = _T("x");
    SIZE size;

    for( TCHAR c=32; c<127; c++ )
    {
        str[0] = c;
        GetTextExtentPoint32( hDC, str, 1, &size );

        if( (DWORD)(x+size.cx+1) > m_dwFontTexWidth )
        {
            x  = 0;
            y += size.cy+1;
        }

        ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );

        m_fFontTexCoords[c-32][0] = ((FLOAT)(x+0))/m_dwFontTexWidth;
        m_fFontTexCoords[c-32][1] = ((FLOAT)(y+0))/m_dwFontTexHeight;
        m_fFontTexCoords[c-32][2] = ((FLOAT)(x+0+size.cx))/m_dwFontTexWidth;
        m_fFontTexCoords[c-32][3] = ((FLOAT)(y+0+size.cy))/m_dwFontTexHeight;

        x += size.cx+1;
    }

    // Lock the surface and write the alpha values for the set pixels
    D3DLOCKED_RECT d3dlr;
    m_pFontTexture->LockRect( 0, &d3dlr, 0, 0 );
    WORD* pDst16 = (WORD*)d3dlr.pBits;
    BYTE bAlpha; // 4-bit measure of pixel intensity

    for( y=0; y < m_dwFontTexHeight; y++ )
    {
        for( x=0; x < m_dwFontTexWidth; x++ )
        {
            bAlpha = (BYTE)((pBitmapBits[m_dwFontTexWidth*y + x] & 0xff) >> 4);
            if (bAlpha > 0)
            {
                *pDst16++ = (bAlpha << 12) | 0x0fff;
            }
            else
            {
                *pDst16++ = 0x0000;
            }
        }
    }

    // Done updating texture, so clean up used objects
    m_pFontTexture->UnlockRect(0);
    DeleteObject( hbmBitmap );
    DeleteDC( hDC );
    DeleteObject( hFont );

    return S_OK;
}

HRESULT CRenderD3DWnd::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor, TCHAR* strText, DWORD dwFlags)
{
	if (!m_bValid)
		return NVEFF_ERR_NOTINITIALIZED;

    DWORD dwVertexShader;
	DWORD dwPixelShader;
	UINT VBStride;
	LPDIRECT3DVERTEXBUFFER8 pVB;
	LPDIRECT3DBASETEXTURE8 pTexture0;
	DWORD i;

	typedef struct tagRenderStates
	{
		D3DRENDERSTATETYPE Type;
		DWORD dwValue;
		DWORD dwDesiredValue;
	} tRenderStates;

	typedef struct tagTextureStageStates
	{
		D3DTEXTURESTAGESTATETYPE Type;
		DWORD dwValue;
		DWORD dwDesiredValue;
	} tTextureStates;


	tRenderStates SavedRender[] = 
	{
		{ D3DRS_ZENABLE, 0, FALSE}, 
		{ D3DRS_ALPHATESTENABLE, 0, TRUE },
		{ D3DRS_ALPHAREF, 0, 0x80 },
		{ D3DRS_ALPHAFUNC, 0, D3DCMP_GREATER},
		{ D3DRS_ALPHABLENDENABLE, 0, TRUE},
		{ D3DRS_SRCBLEND, 0, D3DBLEND_SRCALPHA },
		{ D3DRS_DESTBLEND, 0, D3DBLEND_INVSRCALPHA },
		{ D3DRS_FOGENABLE, 0, FALSE },
		{ D3DRS_CULLMODE, 0, D3DCULL_NONE },
		{ D3DRS_FILLMODE, 0, D3DFILL_SOLID},
		{ D3DRS_WRAP0, 0, 0}
	};

	// Set filter states
	D3DTEXTUREFILTERTYPE FilterType;
    if(dwFlags & D3DFONT_FILTERED)
    {
		FilterType = D3DTEXF_LINEAR; 
    }
	else
	{
		FilterType = D3DTEXF_POINT;
	}

	tTextureStates SavedTextureStage0[] = 
	{
		{ D3DTSS_COLOROP, 0, D3DTOP_SELECTARG1 }, 
		{ D3DTSS_COLORARG1, 0, D3DTA_TEXTURE },
		{ D3DTSS_ALPHAOP, 0, D3DTOP_SELECTARG1 },
		{ D3DTSS_ALPHAARG1, 0, D3DTA_TEXTURE },
		{ D3DTSS_TEXCOORDINDEX, 0, 0 },
		{ D3DTSS_MINFILTER, 0, FilterType},
		{ D3DTSS_MAGFILTER, 0, FilterType},
	};

	tTextureStates SavedTextureStage1[] = 
	{
		{ D3DTSS_COLOROP, 0, D3DTOP_DISABLE }, 
		{ D3DTSS_ALPHAOP, 0, D3DTOP_DISABLE },
		{ D3DTSS_TEXCOORDINDEX, 0, 1 }
	};



	// Save state.
	// Note that a 'real' app should never do this.  The effects browser has to contend with all the seperate 
	// plugins which may have their own state management code.  To stop everyone having to coexist with the 
	// same state manager, we do gets and sets.  This means that the EBrowser can't run on the pure device because
	// of the logo.
	m_pD3DDev->GetVertexShader(&dwVertexShader);
	m_pD3DDev->GetPixelShader(&dwPixelShader);
	m_pD3DDev->GetStreamSource(0, &pVB, &VBStride);
	m_pD3DDev->GetTexture(0, &pTexture0);
	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		m_pD3DDev->GetRenderState(SavedRender[i].Type, &SavedRender[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		m_pD3DDev->GetTextureStageState(0, SavedTextureStage0[i].Type, &SavedTextureStage0[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		m_pD3DDev->GetTextureStageState(1, SavedTextureStage1[i].Type, &SavedTextureStage1[i].dwValue);
	}
	
	// Set state
	if (dwVertexShader != D3DFVF_FONT2DVERTEX)
		m_pD3DDev->SetVertexShader(D3DFVF_FONT2DVERTEX);

	if (dwPixelShader != 0)
		m_pD3DDev->SetPixelShader(0);

	if (pVB != m_pFontVB)
		m_pD3DDev->SetStreamSource(0, m_pFontVB, sizeof(FONT2DVERTEX));

	if (pTexture0 != m_pFontTexture)
		m_pD3DDev->SetTexture(0, m_pFontTexture);

	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		if (SavedRender[i].dwDesiredValue != SavedRender[i].dwValue)
			m_pD3DDev->SetRenderState(SavedRender[i].Type, SavedRender[i].dwDesiredValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage0[i].dwDesiredValue != SavedTextureStage0[i].dwValue)
			m_pD3DDev->SetTextureStageState(0, SavedTextureStage0[i].Type, SavedTextureStage0[i].dwDesiredValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage1[i].dwDesiredValue != SavedTextureStage1[i].dwValue)
			m_pD3DDev->SetTextureStageState(1, SavedTextureStage1[i].Type, SavedTextureStage1[i].dwDesiredValue);
	}

    FLOAT fStartX = sx;

    // Fill vertex buffer
    FONT2DVERTEX* pVertices = NULL;
    DWORD         dwNumTriangles = 0;
    m_pFontVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );

    while( *strText )
    {
        TCHAR c = *strText++;

        if( c == _T('\n') )
        {
            sx = fStartX;
            sy += (m_fFontTexCoords[0][3]-m_fFontTexCoords[0][1])*m_dwFontTexHeight;
        }
        if( c < _T(' ') )
            continue;

        FLOAT tx1 = m_fFontTexCoords[c-32][0];
        FLOAT ty1 = m_fFontTexCoords[c-32][1];
        FLOAT tx2 = m_fFontTexCoords[c-32][2];
        FLOAT ty2 = m_fFontTexCoords[c-32][3];

        FLOAT w = (tx2-tx1) *  m_dwFontTexWidth / m_fFontTextScale;
        FLOAT h = (ty2-ty1) * m_dwFontTexHeight / m_fFontTextScale;

        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
        *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
        dwNumTriangles += 2;

        if( dwNumTriangles*3 > (MAX_FONT_VERTICES-6) )
        {
            // Unlock, render, and relock the vertex buffer
            m_pFontVB->Unlock();
            m_pD3DDev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
            pVertices = NULL;
            m_pFontVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
            dwNumTriangles = 0L;
        }

        sx += w;
    }

    // Unlock and render the vertex buffer
    m_pFontVB->Unlock();
    if( dwNumTriangles > 0 )
        m_pD3DDev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );

	// Restore state
	m_pD3DDev->SetVertexShader(dwVertexShader);
	m_pD3DDev->SetStreamSource(0, pVB, VBStride);
	m_pD3DDev->SetTexture(0, pTexture0);
	m_pD3DDev->SetPixelShader(dwPixelShader);

	SAFE_RELEASE(pTexture0);
	SAFE_RELEASE(pVB);

	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		if (SavedRender[i].dwDesiredValue != SavedRender[i].dwValue)
			m_pD3DDev->SetRenderState(SavedRender[i].Type, SavedRender[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage0[i].dwDesiredValue != SavedTextureStage0[i].dwValue)
			m_pD3DDev->SetTextureStageState(0, SavedTextureStage0[i].Type, SavedTextureStage0[i].dwValue);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		if (SavedTextureStage1[i].dwDesiredValue != SavedTextureStage1[i].dwValue)
			m_pD3DDev->SetTextureStageState(1, SavedTextureStage1[i].Type, SavedTextureStage1[i].dwValue);
	}


    return S_OK;
}


void CRenderD3DWnd::InterpretError(HRESULT hr)
{
	char Error[256];
	D3DXGetErrorString(hr, Error, 256);

    ostringstream strError;
	strError << "COM Error: 0x" << hex << (DWORD)hr << " : " << Error;

	DISPDBG(0, strError.str().c_str());
}

⌨️ 快捷键说明

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