Código de renderizado directo Unity3D

El código de representación directa de Unity3D
suele ser un motor de desarrollo como Unity3D que utiliza programación visual. Gestiona los nodos del mundo tridimensional a través de una estructura de árbol, vincula el modelo de entidad al nodo, organiza la relación espacial del modelo tridimensional a través de las coordenadas del nodo, y realiza cálculos de proyección en perspectiva a través del nodo de la cámara. Renderiza el contenido visual al espacio de pantalla 2D. Al mismo tiempo, la cámara también proporciona el método RenderToTexture para convertir una parte del mundo tridimensional en una textura, y luego usar esta textura intermedia para renderizar en el espacio de destino, como implementar un espejo retrovisor de automóvil.

Debido a necesidades de trabajo, es necesario migrar un proyecto VC6 anterior a la nueva versión * (VC6 no admite programación de 64 bits, lo que resulta en memoria de programa insuficiente. La solución de emergencia actual es editar el archivo pe a través de editbin / LARGEADDRESSAWARE xxx .exe, rompiendo la memoria 2G del programa win32 Limitaciones, este método usa como máximo la memoria múltiple 3G) *, y VC6 para cualquier versión de los intentos de portabilidad VS, es necesario lidiar con muchos errores de compilación e incompatibilidad de sintaxis problemas, no es tan bueno como portar directamente a Unity3D, también puede disfrutar del tratamiento de la programación visual.

Si desea utilizar Unity3D para implementar la función de código de canalización de procesamiento de C ++ DirectX, los modos de nodo y cámara proporcionados por el motor son demasiado engorrosos y requieren un método de procesamiento de menor nivel.

El código de representación central implementado por C ++:

Void CRenderToTextureWindow::OnUpdateSurface()
{
    
    
  OnUpdateSurfaceBegin();
  OnUpdateSurfaceDrawing();
  OnUpdateSurfaceEnd(m_bDownloadToVideoTexture ? m_pDataTexture : Null);
  CWindow::OnUpdateSurface();
}

OnUpdateSurfaceBegin realiza la preparación de la canalización de renderizado

Void CRenderToTextureWindow::OnUpdateSurfaceBegin(CTexture *pRenderTarget/* = Null*/, COLORREF color/* = 0x00*/,  IDirect3DSurface9 *pD3DDepthStencilSurface/* =Null*/)
{
    
    
  HRESULT hr = S_OK;
  // Render video to texture
  if (Null == pRenderTarget) {
    
    
    pRenderTarget = m_pRenderTarget;
  }
  if (Null == pD3DDepthStencilSurface) {
    
    
    pD3DDepthStencilSurface = m_pD3DDepthStencilSurface;
  }
  ASSERT(Null != pRenderTarget->GetSafeTexture());
  m_pD3DTexture = pRenderTarget->GetSafeTexture();
  m_pD3DTarget = Null;
  m_pD3DBackSurface = Null;
  m_pD3DBackDepthStencilSurface = Null;
  D3D::GetD3DDevice()->GetRenderTarget(0, &m_pD3DBackSurface);
  D3D::GetD3DDevice()->GetDepthStencilSurface(&m_pD3DBackDepthStencilSurface);
  m_pD3DTexture->GetSurfaceLevel(0, &m_pD3DTarget);
  D3D::GetD3DDevice()->SetRenderTarget(0, m_pD3DTarget);
  D3D::GetD3DDevice()->SetDepthStencilSurface(pD3DDepthStencilSurface);
  D3D::GetD3DDevice()->Clear(0, NULL, D3DCLEAR_TARGET/*|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL*/, color, 1.0f, 0);
  D3D::GetD3DDevice()->BeginScene();
}

OnUpdateSurfaceEnd realiza el trabajo de acabado después del final del proceso de renderizado

Void CRenderToTextureWindow::OnUpdateSurfaceEnd(CTexture *pDataTexture/* = Null*/)
{
    
    
  HRESULT hr = S_OK;
  D3D::GetD3DDevice()->EndScene();
  D3D::GetD3DDevice()->SetDepthStencilSurface(m_pD3DBackDepthStencilSurface);
  D3D::GetD3DDevice()->SetRenderTarget(0, m_pD3DBackSurface);

  // download data target's data
  if (Null != pDataTexture) {
    
    
    LPDIRECT3DSURFACE pD3DDataSurface = Null;
    pDataTexture->GetSafeTexture()->GetSurfaceLevel(0, &pD3DDataSurface);
    if (FAILED(hr = D3D::GetD3DDevice()->GetRenderTargetData(m_pD3DTarget, pD3DDataSurface))) {
    
    
      TRACE(DXGetErrorString(hr));
    }
    SAFE_RELEASE(pD3DDataSurface);
  }

  SAFE_RELEASE(m_pD3DTarget);
  SAFE_RELEASE(m_pD3DBackSurface);
  SAFE_RELEASE(m_pD3DBackDepthStencilSurface);
}

OnUpdateSurfaceDrawing implementa el cruce y la representación de subventanas

Void CRenderToTextureWindow::OnUpdateSurfaceDrawing()
{
    
    
  // RENDER CODE
  this->SetRoot(True);
  CWindow *pChild = FirstChild();
  while (Null != pChild) {
    
    
    if (pChild->IsVisibled() && pChild->GetRenderLevel() == GetRenderLevel()+1) {
    
    
      GetApplication()->GetWindowsManager()->UpdateWindow(pChild);
    }
    pChild = NextChild(pChild);
  }
  this->SetRoot(False);
}

Función UpdateWindow para el recorrido y la representación de la ventana

Void CWindowsManager::UpdateWindow( CWindow *pWindow )
{
    
    
  ...
  pWindow->OnEraseBkgnd() ;
  pWindow->OnUpdate() ;
  // update child
  CWindow * pChild = pWindow->FirstChild() ;
  while ( Null != pChild ) {
    
    
    CWindow *pNext = pWindow->NextChild( pChild ) ;
    if ( pChild->IsVisibled()) {
    
    
        UpdateWindow( pChild ) ;
    }
    pChild = pNext ;
  }
  pWindow->OnUpdateFrgnd() ;
  pWindow->OnUpdateNcFrgnd() ;
}

CWindow :: Código de representación de la ventana OnUpdate

Void CWindow::OnUpdate()
{
    
    
    CRender *pRender = GetBkgndRender() ;
    if ( Null != pRender ) {
    
    
      pRender->SetAlpha( GetEnvironmentAlpha() ) ;
      pRender->SetRenderOrigin( C2D(CPoint(0,0)) ) ;
      pRender->Render() ;
    }
}

C2DGridRender :: Render renderiza entidades de malla

Void C2DGridRender::Render()
{
    
    
  if ( !IsVisibled() ) return; // donnot render if unvisibled
  if (Null == m_pD3DVertexBuffer) {
    
    
    return;
  }
  if (Null == m_pD3DIndexBuffer) {
    
    
    return;
  }

  LPCUSTOMVERTEX pVertices;
  if (SUCCEEDED(m_pD3DVertexBuffer->Lock(0, sizeof(CUSTOMVERTEX)*GetNumVertices(), (void **)&pVertices, 0))) {
    
    
    memcpy(pVertices, &m_Vertices[0], sizeof(CUSTOMVERTEX)*GetNumVertices());
    CMatrix4 mat = m_matRenderRect * m_matTransform;
    // transform each vertices
    for ( int i = 0 ; i < GetNumVertices() ; ++ i ) {
    
    
      D3DXVec4Transform((LPD3DXVECTOR4)&pVertices[i].vector, 
                        (LPD3DXVECTOR4)&pVertices[i].vector, mat);
      pVertices[i].x += (float)m_ptOrigin.x;
      pVertices[i].y += (float)m_ptOrigin.y;
    }
    m_pD3DVertexBuffer->Unlock() ;
  }

  CClipper *pClipper = GetApplication()->GetWindowsManager()->GetClipper();

  OnBeginRender();
  LPDIRECT3DDEVICE pD3DDevice = GetD3DDevice();
  pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
  pD3DDevice->SetTexture(0, m_pTexture1->GetSafeTexture());
  pD3DDevice->SetStreamSource(0, m_pD3DVertexBuffer, 0, sizeof(CUSTOMVERTEX));
  if (Null != m_pTexture2) {
    
    
    pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE)  ;
    pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT)  ;
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE)  ;
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT)  ;
    pD3DDevice->SetTexture(1, m_pTexture2->GetSafeTexture());
  }
  // draw
  pD3DDevice->SetIndices(m_pD3DIndexBuffer);
  pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
                                   0,
                                   0,
                                   GetNumVertices(),
                                   0,
                                   GetNumFaces());
  if (Null != m_pTexture2) {
    
    
    pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  }
  OnEndRender() ;
}

El motor Unity3D también proporciona una canalización de renderizado de nivel relativamente bajo, que permite la renderización de malla directa a través de instrucciones de canalización de renderización.
Lógica de representación principal después de la portabilidad

  protected override void OnUpdateSurface()
  {
    
    
    base.OnUpdateSurface();

    RenderTexture save = OnUpdateSurfaceBegin(targetTexture, Color.black);
    OnUpdateSurfaceDrawing();
    OnUpdateSurfaceEnd(save, null);
  }

OnUpdateSurfaceBegin realiza la preparación de la canalización de renderizado

  protected virtual RenderTexture OnUpdateSurfaceBegin(RenderTexture target, Color color)
  {
    
    
    GL.PushMatrix();
    RenderTexture save = RenderTexture.active;
    Graphics.SetRenderTarget(target);
    GL.LoadPixelMatrix(0, target.width, 0, target.height);
    CApplicationSetting.Instance.drawBuffer.Clear();
    CApplicationSetting.Instance.drawBuffer.ClearRenderTarget(true, true, color);
    Graphics.ExecuteCommandBuffer(CApplicationSetting.Instance.drawBuffer);
    return save;
  }

OnUpdateSurfaceEnd realiza el trabajo de acabado después del final del proceso de renderizado

  protected virtual void OnUpdateSurfaceEnd(RenderTexture save, Texture dataTexture)
  {
    
    
    GL.PopMatrix();
    Graphics.SetRenderTarget(save);

    // download data target's data
    if (null != dataTexture)
    {
    
    
    }
  }

OnUpdateSurfaceDrawing implementa el cruce y la representación de subventanas

  protected virtual void OnUpdateSurfaceDrawing()
  {
    
    
    // RENDER CODE
    SetRoot(true);
    for (int i = 0; i < transform.childCount; ++i)
    {
    
    
      CWindow child = transform.GetChild(i).GetComponent<CWindow>();
      if (null != child && child.isActiveAndEnabled)
      {
    
    
        CApplicationSetting.Instance.UpdateWindow(child);
      }
    }
    SetRoot(false);
  }

Función UpdateWindow para el recorrido y la representación de la ventana

  public void UpdateWindow(CWindow window)
  {
    
    
    window.OnEraseBkgnd();
    window.OnUpdate();
    for (int i = 0; i < window.transform.childCount; ++i)
    {
    
    
      CWindow child = window.transform.GetChild(i).GetComponent<CWindow>();
      if (null != child)
      {
    
    
        UpdateWindow(child);
      }
    }
    window.OnUpdateFrgnd();
    window.OnUpdateNcFrgnd();
  }

Código de representación de la ventana OnUpdate

  protected virtual void OnUpdate()
  {
    
    
    if (null != Backgnd)
    {
    
    
      Backgnd.Render();
    }
  }

Renderizar entidades de malla de renderizado

  public override void Render()
  {
    
    
    base.Render();

    material.mainTexture = Texture;
    material.SetPass(0);
    if(Vector3.zero != m_Origin)
    {
    
    
      CApplicationSetting.Instance.drawBuffer.DrawMesh(mesh, Matrix4x4.Translate(m_Origin), material);
    }
    else
    {
    
    
      CApplicationSetting.Instance.drawBuffer.DrawMesh(mesh, Matrix4x4.identity, material);
    }
    Graphics.ExecuteCommandBuffer(CApplicationSetting.Instance.drawBuffer);
  }

Estilo de programación de Windows implementado por el código de renderizado Unity3DParece que no hay programación visual del motor Unity3D. De hecho, no lo es. Aún podemos ayudarnos a comprender el proceso de operación a través del árbol de directorios y el panel.

! [Puede ver el valor de ejecución, haga clic en el mapa de renderizado para ver los resultados de renderizado] (https://img-blog.csdnimg.cn/20210113224608321.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10 , text_aHR0cHM6Ly9ibG9FxXQMZMD4LmN0Zsize color_FFFFFF, t_70
Ver resultados de renderizado de RenderToTexture
postscript: Una gran parte de la función de este programa es realizar operaciones de mezcla de capas a través de Windows, es decir, una gran cantidad de renderizado a texturas. cámara y renderizado a texturas, y visualización de una gran cantidad de estados intermedios. Las entidades se apilan en un mundo tridimensional, y la eficiencia no es alta.

Supongo que te gusta

Origin blog.csdn.net/qq_31042143/article/details/112595272
Recomendado
Clasificación