📄 renderd3dwnd.cpp
字号:
}
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 + -