2013-02-20 3 views
1

У меня есть некоторый код, вокруг которого я давно загрузил из Интернета, и я хотел поиграть с ним.Как нарисовать текст в сцене?

Итак, я извлек интересные части, создал прокси 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 тексты» существует, но программа является закрытым исходным кодом): enter image description here enter image description here

Вы можете увидеть положение т ext в красном поле изменилось на экране, но не в игре. Я тоже хочу это сделать. (вы можете видеть красные и синие # тоже)

Код DrawLine уже создает линию в игре, но это только строка, а не текст, так как, наконец, происходит то, что другое есть, а другое нет?

+0

Как насчет ** краткого ** примера вашей проблемы? Ваш вопрос и код слишком длинны, чтобы кто-либо читал, не говоря уже о том, чтобы сформулировать ответ. –

+0

@TonyTheLion добавлено – 2013-02-20 15:57:00

ответ

1

Я могу только догадываться, что делает остальная часть вашего кода. Похоже, что метод Print вызывается в среде, где матрицы преобразования были установлены для формирования орфографического представления, тогда как метод DrawLine использует матрицы игры.

Однако вы не хотите нарисовать текст в сцене. Это приведет к несоосности и неправильному масштабированию текста. То, что вы просто хотите сделать, это получить позицию на экране, где будет место сцены, и нарисовать там текст. Для этого вы можете использовать функцию D3DXVec3Project. Обязательно укажите правильные матрицы преобразования. Не обновленные для 2D-рендеринга.

+0

hm Я изучу его – 2013-02-20 16:30:20