Рендеринг в текстуру для мини-карты, dirextX - PullRequest
2 голосов
/ 09 декабря 2010

alt text

Я пытаюсь визуализировать трехмерное окружение с высоты птичьего полета на текстуру и нарисовать эту текстуру в виде HUD, чтобы представить мини-карту, как если бы это была камера, смотрящая вниз наигра сверху.Я довольно новичок в 3D-программировании и API DirextX, поэтому мне нужна помощь в этом.Работая с некоторыми примерами и уроками, это то, что у меня есть, но все еще безуспешно.

Практически я не знаю, как правильно рисовать текстуру на экране как HUD.Происходит следующее: движок запускает методы beginProjectScene () и endProjectScene (), за которыми следует метод beginSuperImpose ().

beginProjectScene () создает текстуру для рисования, создает соответствующие матрицы вида и проекции и обратный буфер в видену новый видовой экран и устанавливает их после резервного копирования текущих.Он также устанавливает соответствующие цели рендеринга.

endProjectScene () восстанавливает резервные матрицы, область просмотра, задний буфер.

beginSuperImpose () должен рисовать текстуру (texH) на экране.

Есть несколько других методов, вызываемых через устройство отображения (d3dd) для методов API D3D, чтобы это произошло.Но это, похоже, не работает, на самом деле ничего не происходит, и я не уверен, почему.Ранее перед восстановлением цели рендеринга в резервный буфер в endProjectScene () экран просто потемнел (по понятным причинам).Я полагаю, что большая часть моей проблемы заключается в работе с несколькими областями просмотра, и многие концепции относительно новы, и я все еще пытаюсь полностью понять.

Также, когда после восстановления обратного буфера выполняется вызов SetTexture (0, texH)белые сферы становятся синими.

Я немного упомянул об этом: http://www.two -kings.de / tutorials / dxgraphics / dxgraphics16.html

Цикл основного двигателя:

int Engine::run() { 

  ....

  // update the model components
  design->update(rightNow);
  Viewing->update(rightNow);
  audio->update(rightNow);
  lighting->update();
  hud->update(rightNow);

  //NEW CODE FOR HUD BEGIN
  // create the projection here - this part is new

  display->beginProjectScene();

  // draw the opaque scene objects
  scene->draw(true);
  // then the translucent/transparent objects
  display->alphaBlendOn();
  scene->draw(false);
  display->alphaBlendOff();
  display->endProjectScene();

  //NEW CODE FOR HUD END

  // draw the scene
  display->beginDraw();
  // draw the opaque scene objects
  scene->draw(true);
  // then the translucent/transparent objects
  display->alphaBlendOn();
  scene->draw(false);
  display->alphaBlendOff();

  // draw the HUD
  display->beginSuperimpose();
  hud->draw();
  display->endDraw();

  ....
}

Дисплей:

void Display::beginProjectScene() {

    // create the texture COM object on which to draw
    // if the texture COM object does not yet exist
    //
    if (!texH && FAILED(D3DXCreateTexture(d3dd, TEXTURE_WIDTH,
     TEXTURE_HEIGHT, 0, D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP,
  D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &texH)))
        error(L"Projection::11 Failed to create projection texture");

    // get the interface to the surface for the texture - GetSurfaceLevel
    // increases the reference count by 1 so we will have
    // to Release the interface when done
    //

    if (texH && SUCCEEDED(texH->GetSurfaceLevel(0, &textureSurface))) {

    // build the view matrix
    //
    // define position, heading, and up direction of camera and
    // create a view matrix and set the view transformationf
    //TEMPORTY VALUES
    Vector up(0,1,0);
    Vector heading(0,0,0); 
    Vector position(0.5,1,0.5);
    Vector view(1,0,0);

    // the look at point from the virtual camera
    Vector lookAt = position + heading;
    Matrix viewH = 
       ::view(view, position+heading, up);


   // build the projection matrix
   // ...TEST VALUES
   Matrix projectionProjection =
      ::projection(FIELD_OF_VIEW, aspect, NEAR_CLIPPING, 
         FAR_CLIPPING);


  // back up the projection matrix and the viewport, and back buffer
  d3dd->GetTransform(D3DTS_PROJECTION, &projBak);
  d3dd->GetViewport(&viewportBak);
  d3dd->GetRenderTarget(0, &pBackBuffer);

  // associate the backbuffer with the texture surface
  d3dd->SetRenderTarget(0, textureSurface);

  // project the scene onto the texture
  d3dd->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
   D3DCOLOR_ARGB(100, 100, 100, alpha), 1.0f, 0);

  d3dd->BeginScene();

  //d3dd->SetTexture(0, texH);

  d3dd->SetTransform(D3DTS_VIEW, (D3DXMATRIX*)&viewH);
  d3dd->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&projectionProjection);

  // define the viewport for the texture
  D3DVIEWPORT9 viewport;
  viewport.X = 0;
  viewport.Y = 0;
  viewport.Width  = TEXTURE_WIDTH;
  viewport.Height = TEXTURE_HEIGHT;
  viewport.MinZ = 0.0f;
  viewport.MaxZ = 1.0f;
  d3dd->SetViewport(&viewport);

  //d3dd->EndScene();

 }
}

void Display::endProjectScene() {

  d3dd->SetRenderTarget(0, pBackBuffer);
  d3dd->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
   D3DCOLOR_ARGB(100, 100, 100, alpha), 1.0f, 0);


  //d3dd->BeginScene();

  //d3dd->SetTexture(0, texH);

  // restore the projection and viewport
  d3dd->SetTransform(D3DTS_PROJECTION, &projBak);
  d3dd->SetViewport(&viewportBak);

  d3dd->EndScene();


  // release the backbuffer associated with the texture
  textureSurface->Release();
  pBackBuffer->Release();
  //texH->Release();

} 

void Display::beginSuperimpose() {

   // prepare to draw the hud
   //
   if (spriteManager_){
     // start the sprite manager
     spriteManager_->Begin(D3DXSPRITE_ALPHABLEND);


     //NEW CODE FOR HUD
     Vector topRight(width() * 0.01f, height() * 0.01f, 0);

     spriteManager_->Draw(texH, NULL, NULL, (D3DXVECTOR3*)&topRight,
     D3DCOLOR_RGBA(SPRITEH_R, SPRITEH_G, SPRITEH_B,  1));
 }
}

Ответы [ 3 ]

0 голосов
/ 09 декабря 2010

Измените

Vector topRight(width() * 0.01f, height() * 0.01f, 0);

на:

Vector topRight(0.5f, 0.5f, 0);

и посмотрите, будет ли он отображаться.Это должно отобразить спрайт с верхним левым углом, начинающимся с 3/4 стрелки по экрану и 1/4 от него вниз.

Я подозреваю, что ваш расчет ширины выводит его за пределы экрана.Область визуализации DirectX изменяется от -1 до 1 в x и y.Таким образом, если ваша ширина равна 1024, то умножение на 0,01f приведет к значению 1,024, которое находится с правой стороны экрана.

0 голосов
/ 21 мая 2013

Вы должны нарисовать свой HUD ПОСЛЕ того, как вы нарисовали сцену, иначе сцена будет перекрывать HUD.

0 голосов
/ 09 декабря 2010

Попробуйте изменить значение от 1 до 255 в вызове Draw. D3DCOLOR_RGBA принимает значения в диапазоне от 0 до 255. Значение 1 для альфа прозрачно, почти.

...