渲染至迷你地图纹理,dirextX

发布于 2024-10-06 21:30:21 字数 5170 浏览 0 评论 0原文

alt text

我正在尝试将 3D 环境的鸟瞰图渲染为纹理,并将该纹理绘制为 HUD表示一个迷你地图,就好像它是一个从上方俯视游戏的摄像机。我对 3D 编程和 DirextX API 还很陌生,所以我需要这方面的帮助。通过使用一些示例和教程,这就是我所拥有的,但仍然没有成功。

我几乎不知道如何将纹理作为 HUD 正确绘制到屏幕上。发生的情况是引擎运行 beginProjectScene() 和 endProjectScene() 方法,然后运行 ​​beginSuperImpose() 方法。

beginProjectScene() 创建要绘制的纹理,创建适当的视图和投影矩阵以及后台缓冲区以及新视口,并在备份当前视口后设置它们。它还设置适当的渲染目标。

endProjectScene() 恢复备份的矩阵、视口、后台缓冲区。

beginSuperImpose() 应该将纹理 (texH) 绘制到屏幕上。

还有一些其他方法通过显示设备 (d3dd) 调用 D3D API 方法来实现此目的。但它似乎不起作用,事实上什么也不会发生,我不知道为什么。以前,在将渲染目标恢复到 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));
 }
}

alt text

I am trying to render a birds eye view of a 3d environment to a texture and draw that texture as a HUD to represent a mini map as if it was a camera looking down at the game from above. I am pretty new at 3D programming and the DirextX API so I need help with this. From working with some examples and tutorials this is what I have but still no success.

Pretty much I don't know how to properly draw the texture onto the screen as a HUD. What happens is the engine runs the beginProjectScene() and endProjectScene() methods followed by the beginSuperImpose() method.

beginProjectScene() creates a texture to draw on, creates the appropriate view and projection matrices and back buffer as well a a new viewport and sets them after backing up the current ones. It also sets the appropriate render targets.

endProjectScene() restores the backed up matrices, viewport, back buffer.

beginSuperImpose() is supposed to draw the texture (texH) to screen.

There are some other methods called through the display device (d3dd) to D3D API methods to make this happen. But it doesn't seem to work, in fact nothing happens likely and I am not sure why. Previously before restoring the render target to the backed up back buffer in endProjectScene() the screen just went black (for obvious reasons). I believe much of my problem is working with multiple viewports and much of the concepts are relatively new and I am still trying to fully grasp.

Also when SetTexture(0, texH) call is made after restoring back buffer my white spheres turn blue.

I referred to this a bit: http://www.two-kings.de/tutorials/dxgraphics/dxgraphics16.html

Main engine loop:

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();

  ....
}

Display:

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));
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森林很绿却致人迷途 2024-10-13 21:30:21

尝试在 Draw 调用中将 1 更改为 255。 D3DCOLOR_RGBA 的值范围为 0 到 255。alpha 值为 1 时几乎是透明的。

Try changing , 1 to , 255 in the call to Draw. D3DCOLOR_RGBA takes values in the range 0 to 255. A value of 1 for alpha is transparent, nearly.

两人的回忆 2024-10-13 21:30:21

更改

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

为:

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

并查看它是否呈现。这应该显示精灵的左上角从屏幕上 3/4 处开始,向下 1/4 处开始。

我怀疑你的宽度计算将其从屏幕上移开。 DirectX 渲染空间的 x 和 y 范围从 -1 到 1。因此,如果宽度为 1024,则乘以 0.01f 将得到值 1.024,该值超出了屏幕的右侧。

Change

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

to:

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

And see if it renders. This ought to display the sprite with the upper left corner starting 3/4 of the ay across the screen and 1/4 of the way down it.

I suspect that your width calculation is putting it off screen. The DirectX render space goes from -1 to 1 in x and y. So if your width is 1024 then multiplying by 0.01f will result in a value of 1.024 which is off the right hand side of the screen.

吻安 2024-10-13 21:30:21

您应该在绘制场景之后绘制 HUD,否则场景将覆盖 HUD。

You should draw your HUD AFTER you drawed the scene, otherwise the scene will overlay the HUD.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文