У меня есть некоторый код, вокруг которого я давно загрузил из Интернета, и я хотел поиграть с ним.Как нарисовать текст в сцене?
Итак, я извлек интересные части, создал прокси d3d9.dll и подключился к игре.
Теперь у меня есть вопрос, потому что я не могу найти разницу на чертеже между этими двумя частями кода, которые определяют, если Vertice должен быть нарисован на экране или в игровой сцене
(я имею в виду, как - HUD находится на экране, и вы всегда его видите, и автомобиль находится в игровой сцене, когда вы поворачиваете, вы его не видите).
Первая часть - это код, который я хочу изменить, я хочу, чтобы он отображал текст в игровой сцене, а не на экране, как статический текст.
Код, который используется в DLL заключается в следующем:
float m_fTexCoords[224][4];
float CD3DFont::DrawLength (const char *szText) const
{
float len = 0.0f;
float sub = (m_dwCreateFlags & FCR_BORDER) ? 2.0f : 0.0f;
for (const char *p = szText; *p; p++)
{
int c = *(unsigned char *)p - 32;
if (c >= 0 && c < 224)
len += ((m_fTexCoords[c][2] - m_fTexCoords[c][0]) * m_texWidth - sub) - m_chrSpacing * 2;
}
return len;
}
HRESULT CD3DFont::Print (float x, float y, DWORD color, const char *szText)
{
if (!m_isReady)
return E_FAIL;
float strWidth = DrawLength(szText);
x -= (float)m_chrSpacing;
if (FAILED(this->BeginRender()))
return E_FAIL;
DWORD fvf;
m_pD3Ddev->GetFVF(&fvf);
m_pD3Ddev->SetFVF(D3DFVF_BITMAPFONT);
m_pD3Ddev->SetTexture(0, m_pD3Dtex);
m_pD3Ddev->SetStreamSource(0, m_pD3Dbuf, 0, sizeof(d3dvertex_s));
while (*szText)
{
UINT usedTriangles = 0;
d3dvertex_s *pVertex;
if (FAILED(m_pD3Dbuf->Lock(0, 0, (void **) &pVertex, D3DLOCK_DISCARD)))
{
m_pD3Ddev->SetFVF(fvf);
this->EndRender();
return E_FAIL;
}
for (; *szText; szText++)
{
int c = *(unsigned char *)szText - 32;
if (!(c >= 0 && c < 224))
continue;
float tx1 = m_fTexCoords[c][0];
float tx2 = m_fTexCoords[c][2];
float ty1 = m_fTexCoords[c][1];
float ty2 = m_fTexCoords[c][3];
float w = (tx2 - tx1) * m_texWidth;
float h = (ty2 - ty1) * m_texHeight;
*pVertex++ = Init2DVertex(x - 0.5f, y - 0.5f, color, tx1, ty1); //topleft
*pVertex++ = Init2DVertex(x + w - 0.5f, y - 0.5f, color, tx2, ty1); //topright
*pVertex++ = Init2DVertex(x - 0.5f, y + h - 0.5f, color, tx1, ty2); //bottomleft
*pVertex++ = Init2DVertex(x + w - 0.5f, y - 0.5f, color, tx2, ty1); //topright
*pVertex++ = Init2DVertex(x + w - 0.5f, y + h - 0.5f, color, tx2, ty2); //bottomright
*pVertex++ = Init2DVertex(x - 0.5f, y + h - 0.5f, color, tx1, ty2); //bottomleft
if (m_dwCreateFlags & FCR_BORDER)
w -= 2.0f;
x += w - (m_chrSpacing * 2);
usedTriangles += 2;
if (usedTriangles >= m_maxTriangles)
break;
}
if (usedTriangles > 0)
{
m_pD3Dbuf->Unlock();
m_pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, usedTriangles);
}
}
m_pD3Ddev->SetFVF(fvf);
this->EndRender();
return S_OK;
}
Затем я увидел функцию под названием «DrawLine», поэтому я решил проверить его и посмотреть, что он делает, и он рисует линию в игровом мире, а не статическая строка на экране, так что, когда я оборачиваюсь и не видят конкретные позиции - я не вижу линию:
bool CD3DRender::DrawLine (const D3DXVECTOR3 &a, const D3DXVECTOR3 &b, DWORD dwColor)
{
if (FAILED(CD3DBaseRender::BeginRender()))
return false;
////////////////////////////////////////////////////
// Make sure we have a valid vertex buffer.
if (m_pD3Dbuf == NULL)
{
return false;
}
m_pD3Ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pD3Ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
//m_pD3Ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
//m_pD3Ddev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pD3Ddev->SetRenderState(D3DRS_CLIPPING, false);
m_pD3Ddev->SetRenderState (D3DRS_ZENABLE, false);
//m_pD3Ddev->SetRenderState (D3DRS_LIGHTING, false);
D3DLVERTEX lineList[2];
//////////////////////////////////////////////////
// Lock the vertex buffer and copy in the verts.
m_pD3Dbuf->Lock(0, 0, (void **) &lineList, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); // flogs: D3DLOCK_NOSYSLOCK, D3DLOCK_DISCARD
{
lineList[0].x = a.x;
lineList[0].y = a.y;
lineList[0].z = a.z;
lineList[0].color = dwColor;
lineList[0].specular = dwColor;
lineList[1].x = b.x;
lineList[1].y = b.y;
lineList[1].z = b.z;
lineList[1].color = dwColor;
lineList[1].specular = dwColor;
}
m_pD3Dbuf->Unlock();
// store FVF to restore original at the end of this function
DWORD fvf;
m_pD3Ddev->GetFVF(&fvf);
m_pD3Ddev->SetFVF(D3DFVF_LVERTEX);
//m_pD3Ddev->SetFVF(D3DFVF_PRIMITIVES);
////////////////////////////////////////////////////
// Draw!
m_pD3Ddev->DrawPrimitiveUP(D3DPT_LINESTRIP, 1, lineList, sizeof(lineList)/2);
// reset states
m_pD3Ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pD3Ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pD3Ddev->SetRenderState (D3DRS_ZENABLE, true);
m_pD3Ddev->SetRenderState(D3DRS_CLIPPING, true);
// restore FVF
m_pD3Ddev->SetFVF(fvf);
CD3DBaseRender::EndRender();
return true;
}
Теперь вопрос: где разница? Где этот код говорит:
«Эй, нарисуйте текст на экране плеера и оставите его там»?
и
«Эй сделать это в игровом мире, рисовать только часть игрок может видеть»?
Может ли кто-нибудь указать мне правильное направление? Или, может быть, как отредактировать функцию печати, чтобы показать текст в игровом мире?
благодарит заранее.
кратким пример того, что я хочу добиться:
Что печати теперь делает (зеленый ящик) и то, что я хочу, чтобы это сделать (красный квадрат)
(экраны взяты из другого игра, где такие «3d тексты» существует, но программа является закрытым исходным кодом):
Вы можете увидеть положение т ext в красном поле изменилось на экране, но не в игре. Я тоже хочу это сделать. (вы можете видеть красные и синие # тоже)
Код DrawLine уже создает линию в игре, но это только строка, а не текст, так как, наконец, происходит то, что другое есть, а другое нет?
Как насчет ** краткого ** примера вашей проблемы? Ваш вопрос и код слишком длинны, чтобы кто-либо читал, не говоря уже о том, чтобы сформулировать ответ. –
@TonyTheLion добавлено – 2013-02-20 15:57:00