2012-06-12 16 views
6

Esta es una especie de maletín, pero estoy desarrollando un juego que utiliza varios monitores. Por razones fuera del alcance de esta pregunta, estoy usando un 'método de múltiples dispositivos' en lugar de cadenas de intercambio. Mi código es similar al siguiente ejemplo:Ventanas múltiples de pantalla completa con DirectX 9.0

http://www.codesampler.com/dx9src/dx9src_1.htm#dx9_multiple_devices

lo que estoy luchando con, y lo que puedo encontrar ninguna documentación acerca, es si es posible ejecutar ambas ventanas en cierto pantalla completa (es decir d3dpp.Windowed = FALSE;) Actualmente recibo un HRESULT de 'parámetros no válidos' cuando llamo al CreateDevice por segunda vez. Funciona bien si uno de las ventanas es a pantalla completa, pero no ambos. Tengo la esperanza de que hay un ajuste para hacer este trabajo, aunque ...

Saludos de antelación

+0

Solo me preguntaba, ¿por qué se utilizaron varios adaptadores en lugar de swapchains adicionales debido al desgarro de la pantalla? Si es así, estoy en el mismo barco que yo, y he estado reescribiendo mi procesador la semana pasada :( – Balk

Respuesta

7

De acuerdo con la documentación Direct3D 9 (Working with Multiple Monitor Systems): "La implicación práctica es que una aplicación de monitorización múltiple puede colocar varios dispositivos en modo de pantalla completa, pero solo si todos estos dispositivos son para diferentes adaptadores, fueron creados por el mismo objeto Direct3D9, y todos comparten la misma ventana de enfoque ".

Notarás que hay dos manejadores de ventana por inicialización del dispositivo; la ventana de presentación y la ventana de enfoque. La ventana de enfoque (pasada a IDirect3D9::CreateDevice) se utiliza para manejar eventos como el cambio de primer plano a fondo, o Alt + Tab. La ventana de presentación se transfiere a la estructura D3DPRESENT_PARAMETERS y se utiliza únicamente como un lienzo para Direct3D.

Debe marcar una de las ventanas que cree (probablemente la primera) como la ventana de enfoque. Comparta la ventana de enfoque en todos los dispositivos, pero mantenga separadas las ventanas de "lienzo" (presentación).

EDITAR:This puede ayudarlo también.

crean una ventana de enfoque para ambos dispositivos.

(opcionalmente) crear una ventana de dispositivo para el primer adaptador.

crear una ventana de dispositivo para el segundo adaptador.

crear un contexto direct3d9.

utilice esto para crear ambos dispositivos.

cree el primer dispositivo a pantalla completa utilizando la ventana de foco compartido y (opcionalmente) la primera ventana del dispositivo.

cree el segundo dispositivo de pantalla completa utilizando la ventana de enfoque compartido y la ventana del segundo dispositivo.

restablecer el primer dispositivo.

la ventana de foco compartido se pasa directamente como un parámetro a CreateDevice.

las ventanas del dispositivo se pasan en la estructura de parámetros de presentación.

3

Q> Actualmente estoy recibiendo un HRESULT '' params no válidos al llamar CreateDevice la segunda vez.Funciona bien si una de las ventanas es a pantalla completa, pero no ambas.

Porque estaba creando dos dispositivos diferentes con el mismo ID de adaptador 0. Utilice la id de adater como 1 para la segunda llamada de dispositivo de creación.

paso importante que debe realizarse después de la creación del dispositivo 2 o 3 o 4 ... es restablecer el dispositivo uno (ID de dispositivo predeterminado 0).

Create Device 1 
Create Device 2 
........ 
........ 
Create Device n  
Reset Device 1 

Para hacer tu y de otra vida más fácil, he añadido un código trabajo para soportar varios monitores en pantalla completa (DirectX 9). Tenga en cuenta que he agregado/cambiado algunas líneas de código del código de muestra tomadas del enlace web que ha mencionado en su pregunta.

#define STRICT 
#define WIN32_LEAN_AND_MEAN 

#include <windows.h> 
#include <mmsystem.h> 
#include <stdio.h> 
#include <d3d9.h> 
#include <d3dx9.h> 
#include "resource.h" 

// define the screen resolution 
#define SCREEN_WIDTH 1920 
#define SCREEN_HEIGHT 1080 

//----------------------------------------------------------------------------- 
// GLOBALS 
//----------------------------------------------------------------------------- 
LPDIRECT3D9 g_pD3D = NULL; 
HWND g_hWnd_0 = NULL; // Handle to the first window 
HWND g_hWnd_1 = NULL; // Handle to the second window 

LPDIRECT3DDEVICE9 g_pd3dDevice_0 = NULL; // Direct3d device for the first window 
LPDIRECT3DDEVICE9 g_pd3dDevice_1 = NULL; // Direct3d device for the second window 

LPD3DXMESH g_pTeapotMesh_0 = NULL; // The two devices can't share resources, so we'll 
LPD3DXMESH g_pTeapotMesh_1 = NULL; // have to create two meshes... one for each device 

D3DMATERIAL9 g_teapotMtrl; 
D3DLIGHT9 g_pLight0; 

LPD3DXFONT g_pd3dxFont = NULL; 

DWORD g_dwBackBufferWidth = 0; 
DWORD g_dwBackBufferHeight = 0; 

bool windowed = false; 

float g_fSpinX = 0.0f; 
float g_fSpinY = 0.0f; 

double g_dElpasedFrameTime = 0.0f; 
double g_dElpasedAppTime = 0.0f; 
double g_dCurrentTime = 0.0f; 
double g_dLastTime = 0.0f; 

struct Vertex 
{ 
    float x, y, z; // Position of vertex in 3D space 
    float nx, ny, nz; // Normal for lighting calculations 
    DWORD diffuse; // Diffuse color of vertex 

    enum FVF 
    { 
     FVF_Flags = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE 
    }; 
}; 

#define TWO 

//----------------------------------------------------------------------------- 
// PROTOTYPES 
//----------------------------------------------------------------------------- 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow); 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 
void CreateFont(void); 
void init_0(void); 
void init_1(void); 
void shutDown_0(void); 
void shutDown_1(void); 
void render_0(void); 
void render_1(void); 
void LoadModels(void); 
void ResetDevice(void); 

//----------------------------------------------------------------------------- 
// Name: WinMain() 
// Desc: The application's entry point 
//----------------------------------------------------------------------------- 
int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow) 
{ 
    WNDCLASSEX winClass; 
    MSG uMsg; 
    bool deviceReset = FALSE; 

    memset(&uMsg,0,sizeof(uMsg)); 
    winClass.lpszClassName = "MY_WINDOWS_CLASS"; 
    winClass.cbSize = sizeof(WNDCLASSEX); 
    winClass.style = CS_HREDRAW | CS_VREDRAW; 
    winClass.lpfnWndProc = WindowProc; 
    winClass.hInstance = hInstance; 
    winClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON); 
    winClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON); 
    winClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
    winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    winClass.lpszMenuName = NULL; 
    winClass.cbClsExtra = 0; 
    winClass.cbWndExtra = 0; 

    if(!RegisterClassEx(&winClass)) 
     return E_FAIL; 

    // 
    // Create window #0... 
    // 

    g_hWnd_0 = CreateWindowEx(NULL, "MY_WINDOWS_CLASS", 
     "Direct3D (DX9) - Multiple Devices (Window #0)", 
     WS_EX_TOPMOST | WS_POPUP, // fullscreen values /* WS_OVERLAPPEDWINDOW | WS_VISIBLE,*/ 
     0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL); 

    if(g_hWnd_0 == NULL) 
     return E_FAIL; 

    ShowWindow(g_hWnd_0, nCmdShow); 
    UpdateWindow(g_hWnd_0); 

#ifdef TWO 
    // 
    // Create window #1... 
    // 
    g_hWnd_1 = CreateWindowEx(NULL, "MY_WINDOWS_CLASS", 
     "Direct3D (DX9) - Multiple Devices (Window #1)", 
     WS_EX_TOPMOST | WS_POPUP, // fullscreen values /* WS_OVERLAPPEDWINDOW | WS_VISIBLE,*/ 
     1920, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL); 

    if(g_hWnd_1 == NULL) 
     return E_FAIL; 

    ShowWindow(g_hWnd_1, nCmdShow); 
    UpdateWindow(g_hWnd_1); 
#endif 
    // 
    // Init Direct3D usage on both windows... 
    // 

    init_0(); 
#ifdef TWO 
    init_1(); 
#endif 

    ResetDevice(); // Important !!! 

    LoadModels(); 

    while(uMsg.message != WM_QUIT) 
    { 
     if(PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&uMsg); 
      DispatchMessage(&uMsg); 
     } 
     else 
     { 
      g_dCurrentTime = timeGetTime(); 
      g_dElpasedFrameTime = g_dCurrentTime - g_dLastTime; // How much time has passed since the last frame? 
      g_dElpasedAppTime += g_dElpasedFrameTime; // How much time has passed overall for the application? 
      g_dLastTime = g_dCurrentTime; 

      render_0(); 
#ifdef TWO 
      render_1(); 
#endif 
     } 
    } 

    // 
    // Cleanup Direct3D usage on both windows... 
    // 
#ifdef TWO 
    shutDown_1(); 
#endif 
    shutDown_0(); 

    UnregisterClass("MY_WINDOWS_CLASS", winClass.hInstance); 
    return uMsg.wParam; 
} 

void ResetDevice(void) 
{ 
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = windowed; 
    d3dpp.hDeviceWindow = g_hWnd_0; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer 
    d3dpp.BackBufferCount = 1; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 
    g_pd3dDevice_0->Reset(&d3dpp); 
} 

void LoadModels(void) 
{ 
    D3DXMATRIX matProj; 
    D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(45.0f), 1920.0f/1080.0f, 0.1f, 100.0f); 
    g_pd3dDevice_0->SetTransform(D3DTS_PROJECTION, &matProj); 

    g_pd3dDevice_0->SetRenderState(D3DRS_ZENABLE, TRUE); 
    g_pd3dDevice_0->SetRenderState(D3DRS_LIGHTING, TRUE); 
    g_pd3dDevice_0->SetRenderState(D3DRS_SPECULARENABLE, TRUE); 

    // Setup a material for the teapot 
    ZeroMemory(&g_teapotMtrl, sizeof(D3DMATERIAL9)); 

    g_teapotMtrl.Diffuse.r = 1.0f; 
    g_teapotMtrl.Diffuse.g = 1.0f; 
    g_teapotMtrl.Diffuse.b = 1.0f; 
    g_teapotMtrl.Diffuse.a = 1.0f; 

    // Setup a simple directional light and some ambient... 
    g_pLight0.Type = D3DLIGHT_DIRECTIONAL; 
    g_pLight0.Direction = D3DXVECTOR3(1.0f, 0.0f, 1.0f); 

    g_pLight0.Diffuse.r = 1.0f; 
    g_pLight0.Diffuse.g = 1.0f; 
    g_pLight0.Diffuse.b = 1.0f; 
    g_pLight0.Diffuse.a = 1.0f; 

    g_pLight0.Specular.r = 1.0f; 
    g_pLight0.Specular.g = 1.0f; 
    g_pLight0.Specular.b = 1.0f; 
    g_pLight0.Specular.a = 1.0f; 

    g_pd3dDevice_0->SetLight(0, &g_pLight0); 
    g_pd3dDevice_0->LightEnable(0, TRUE); 

    g_pd3dDevice_0->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(0.2f, 0.2f, 0.2f, 1.0f)); 

    // Load up the teapot mesh... 
    D3DXLoadMeshFromX("teapot.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice_0, NULL, NULL, NULL, NULL, &g_pTeapotMesh_0); 

    CreateFont(); 

#ifndef TWO 
    return; 
#endif 

    D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(45.0f), 1920.0f/1080.0f, 0.1f, 100.0f); 
    g_pd3dDevice_1->SetTransform(D3DTS_PROJECTION, &matProj); 

    g_pd3dDevice_1->SetRenderState(D3DRS_ZENABLE, TRUE); 
    g_pd3dDevice_1->SetRenderState(D3DRS_LIGHTING, TRUE); 
    g_pd3dDevice_1->SetRenderState(D3DRS_SPECULARENABLE, TRUE); 

    // Setup a material for the teapot 
    ZeroMemory(&g_teapotMtrl, sizeof(D3DMATERIAL9)); 

    g_teapotMtrl.Diffuse.r = 1.0f; 
    g_teapotMtrl.Diffuse.g = 1.0f; 
    g_teapotMtrl.Diffuse.b = 1.0f; 
    g_teapotMtrl.Diffuse.a = 1.0f; 

    // Setup a simple directional light and some ambient... 
    g_pLight0.Type = D3DLIGHT_DIRECTIONAL; 
    g_pLight0.Direction = D3DXVECTOR3(1.0f, 0.0f, 1.0f); 

    g_pLight0.Diffuse.r = 1.0f; 
    g_pLight0.Diffuse.g = 1.0f; 
    g_pLight0.Diffuse.b = 1.0f; 
    g_pLight0.Diffuse.a = 1.0f; 

    g_pLight0.Specular.r = 1.0f; 
    g_pLight0.Specular.g = 1.0f; 
    g_pLight0.Specular.b = 1.0f; 
    g_pLight0.Specular.a = 1.0f; 

    g_pd3dDevice_1->SetLight(0, &g_pLight0); 
    g_pd3dDevice_1->LightEnable(0, TRUE); 

    g_pd3dDevice_1->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(0.2f, 0.2f, 0.2f, 1.0f)); 

    // Load up the teapot mesh... 
    D3DXLoadMeshFromX("teapot.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice_1, NULL, NULL, NULL, NULL, &g_pTeapotMesh_1); 
} 

//----------------------------------------------------------------------------- 
// Name: WindowProc() 
// Desc: The window's message handler 
//----------------------------------------------------------------------------- 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    static POINT ptLastMousePosit; 
    static POINT ptCurrentMousePosit; 
    static bool bMousing; 

    switch(msg) 
    { 
    case WM_KEYDOWN: 
     { 
      switch(wParam) 
      { 
      case VK_ESCAPE: 
       PostQuitMessage(0); 
       break; 
      } 
     } 
     break; 

    case WM_LBUTTONDOWN: 
     { 
      ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam); 
      ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam); 
      bMousing = true; 
     } 
     break; 

    case WM_LBUTTONUP: 
     { 
      bMousing = false; 
     } 
     break; 

    case WM_MOUSEMOVE: 
     { 
      ptCurrentMousePosit.x = LOWORD (lParam); 
      ptCurrentMousePosit.y = HIWORD (lParam); 

      if(bMousing) 
      { 
       g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x); 
       g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y); 
      } 

      ptLastMousePosit.x = ptCurrentMousePosit.x; 
      ptLastMousePosit.y = ptCurrentMousePosit.y; 
     } 
     break; 

    case WM_CLOSE: 
     { 
      PostQuitMessage(0); 
     } 

    case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
     } 
     break; 

    default: 
     { 
      return DefWindowProc(hWnd, msg, wParam, lParam); 
     } 
     break; 
    } 

    return 0; 
} 

void CreateFont(void) 
{ 
    HRESULT hr; 
    HDC hDC; 
    //HFONT hFont; 
    int nHeight; 
    int nPointSize = 9; 
    //char strFontName[] = "Arial"; 

    hDC = GetDC(NULL); 

    nHeight = -(MulDiv(nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72)); 

    ReleaseDC(NULL, hDC); 

    // Create a font for statistics and help output 
    hr = D3DXCreateFont(g_pd3dDevice_0, nHeight, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &g_pd3dxFont); 

    if(FAILED(hr)) MessageBox(NULL, "Call to D3DXCreateFont failed!", "ERROR", MB_OK | MB_ICONEXCLAMATION); 
} 

//----------------------------------------------------------------------------- 
// Name: init_0() 
// Desc: 
//----------------------------------------------------------------------------- 
void init_0(void) 
{ 
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); 

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 

    d3dpp.Windowed = windowed; 
    d3dpp.hDeviceWindow = g_hWnd_0; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer 
    d3dpp.BackBufferCount = 1; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 

    g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd_0, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice_0); 

} 

//----------------------------------------------------------------------------- 
// Name: init_1() 
// Desc: 
//----------------------------------------------------------------------------- 
void init_1(void) 
{ 
    HWND window; 

    if(!windowed) 
    { 
     window = g_hWnd_0; 
    } 
    else 
    { 
     window = g_hWnd_1; 
    } 

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = windowed; 
    d3dpp.hDeviceWindow = window; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer 
    d3dpp.BackBufferCount = 1; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 

    g_pD3D->CreateDevice(1, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice_1); 

} 


//----------------------------------------------------------------------------- 
// Name: shutDown() 
// Desc: 
//----------------------------------------------------------------------------- 
void shutDown_0(void) 
{ 
    if(g_pTeapotMesh_0 != NULL) 
     g_pTeapotMesh_0->Release(); 

    if(g_pd3dDevice_0 != NULL) 
     g_pd3dDevice_0->Release(); 

    if(g_pD3D != NULL) 
     g_pD3D->Release(); 
} 

//----------------------------------------------------------------------------- 
// Name: shutDown() 
// Desc: 
//----------------------------------------------------------------------------- 
void shutDown_1(void) 
{ 
    if(g_pTeapotMesh_1 != NULL) 
     g_pTeapotMesh_1->Release(); 

    if(g_pd3dDevice_1 != NULL) 
     g_pd3dDevice_1->Release(); 
} 

//----------------------------------------------------------------------------- 
// Name: render_0() 
// Desc: 
//----------------------------------------------------------------------------- 
void render_0(void) 
{ 
    D3DXMATRIX matView; 
    D3DXMATRIX matWorld; 
    D3DXMATRIX matRotation; 
    D3DXMATRIX matTranslation; 
    static int nFrameCount = 0; 
    static double nTimeOfLastFPSUpdate = 0.0; 
    static char fpsString[50] = "Frames Per Second = "; 
    RECT destRect; 

    // Now we can clear just view-port's portion of the buffer to red... 
    g_pd3dDevice_0->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(1.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0); 

    g_pd3dDevice_0->BeginScene(); 

    // For the left view-port, leave the view at the origin... 
    D3DXMatrixIdentity(&matView); 
    g_pd3dDevice_0->SetTransform(D3DTS_VIEW, &matView); 

    // ... and use the world matrix to spin and translate the teapot 
    // out where we can see it... 
    D3DXMatrixRotationYawPitchRoll(&matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f); 
    D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, 5.0f); 
    matWorld = matRotation * matTranslation; 
    g_pd3dDevice_0->SetTransform(D3DTS_WORLD, &matWorld); 

    g_pd3dDevice_0->SetMaterial(&g_teapotMtrl); 
    g_pTeapotMesh_0->DrawSubset(0); 

    g_pd3dDevice_0->EndScene(); 

    // Report frames per second and the number of objects culled... 
    ++nFrameCount; 

    if(g_dElpasedAppTime - nTimeOfLastFPSUpdate > 1000) // Update once a second 
    { 
     sprintf(fpsString, "Frames Per Second = %4.2f", nFrameCount*1000.0/(g_dElpasedAppTime - nTimeOfLastFPSUpdate)); 

     nTimeOfLastFPSUpdate = g_dElpasedAppTime; 
     nFrameCount = 0; 
    } 

    SetRect(&destRect, 5, 5, 0, 0); 

    g_pd3dxFont->DrawText(NULL, fpsString, -1, &destRect, DT_NOCLIP, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); 

    g_pd3dDevice_0->Present(NULL, NULL, NULL, NULL); 
} 

//----------------------------------------------------------------------------- 
// Name: render_1() 
// Desc: 
//----------------------------------------------------------------------------- 
void render_1(void) 
{ 
    D3DXMATRIX matView; 
    D3DXMATRIX matWorld; 
    D3DXMATRIX matRotation; 
    D3DXMATRIX matTranslation; 

    // Now we can clear just view-port's portion of the buffer to green... 
    g_pd3dDevice_1->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f, 1.0f, 0.0f, 1.0f), 1.0f, 0); 

    g_pd3dDevice_1->BeginScene(); 

    // For the left view-port, leave the view at the origin... 
    D3DXMatrixIdentity(&matView); 
    g_pd3dDevice_1->SetTransform(D3DTS_VIEW, &matView); 

    // ... and use the world matrix to spin and translate the teapot 
    // out where we can see it... 
    D3DXMatrixRotationYawPitchRoll(&matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f); 
    D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, 5.0f); 
    matWorld = matRotation * matTranslation; 
    g_pd3dDevice_1->SetTransform(D3DTS_WORLD, &matWorld); 


    g_pd3dDevice_1->SetMaterial(&g_teapotMtrl); 
    g_pTeapotMesh_1->DrawSubset(0); 

    g_pd3dDevice_1->EndScene(); 

    // We're done! Now, we just call Present() 
    g_pd3dDevice_1->Present(NULL, NULL, NULL, NULL); 
} 
+0

gracias por el ejemplo del código (¡me ha ayudado mucho!) Sin embargo, 'init_1()' tiene el defecto que utiliza el mismo argumento 'window' para' d3dpp.hDeviceWindow' y como argumento para 'CreateDevice'. Esto falla para el caso' windowed = false' (como se indica en la otra respuesta). La forma correcta sería usar 'hDeviceWindow = g_hWnd_1'. –