2011-02-08 1 views
4

내 NVIDIA/EVGA GTX 580에 번들로 제공되는 기능 중 일부가 필요하기 때문에 자신의 스테레오 이미지 뷰어를 작성하고 싶습니다.스테레오 이미지를 표시하기 위해 스테레오 가능 그래픽 카드를 프로그래밍하려면 어떻게합니까?

어떻게 프로그램 할 수 있는지 알 수 없습니다. 카드를 사용하여 다른 모든 프레임 (120HZ)이 왼쪽과 오른쪽으로 번갈아 가면서 "셔터 글래스"모드로 들어갑니다.

나는 OpenGL, Direct3D 및 XNA API와 NVIDIA의 정보를 살펴 보았고 시작하는 방법을 알 수 없습니다. 별도의 좌우 이미지를 어떻게 설정합니까? 디스플레이 화면에 어떻게 말합니까? 그리고 드라이버에게 셔터 글래스 트랜스미터를 활성화하도록 지시하는 방법은 무엇입니까?

(다른 흥미로운 점은 묶음 처리 된 소프트웨어를 사용하여 셔터 글래스 모드에서 스테레오 이미지와 비디오를 볼 때마다 전체 화면으로 표시되고 화면이 깜박 거리며 그 모드로 들어갈 때 깜박입니다. 3D 가능 (570, 580) NVidia "게이머"카드의 나머지 화면을 뒤집어 놓지 않고 창에 3D 표면을 표시 할 수 있습니까?

답변

2

GEForce 범위의 NVidia 3Dvision 디스플레이의 너비의 두배의 화면 전체를 directX 표면에 쓸 필요가 있습니다. 왼쪽에있는 오른쪽 이미지 (duh)
그런 다음 이미지의 왼쪽 하단에 마법 값을 써야합니다. 운전수가 안경을 들고 안경을 켠다. , nvapi.dll이 필요하지 않습니다.

Nvidia pro 안경과 Quadra 카드를 사용하면 일반 OpenGL 스테레오 API를 사용할 수 있습니다.

ps.I 일반 창으로이 작업을 관리하는 몇 가지 샘플 코드를 찾았습니다.
편집 - 그것이 내가 구축 할 결코 수 XMITTER 이야기 낮은 수준의 USB 코드를했다, 나는 그것이 결국 여기이 http://sourceforge.net/projects/libnvstusb/

가 된 엔비 안경 전체 화면에 대한 몇 가지 샘플 코드라고 생각합니다.
저는 DirectX 전문가가 아니므로이 중 일부는 최적이 아닐 수도 있습니다.
내 애플은 또한 Qt를 기반으로, 거기에 약간의 Qt를 비트는 내가 여기에 조금 늦게 해요

----------------------------------------------------------------- 
    // header 
    void create3D(); 
    void set3D(); 
    IDirect3D9 *_d3d; 
    IDirect3DDevice9 *_d3ddev; 
    QSize _size; // full screen size 

    IDirect3DSurface9 *_imageBuf; //Source stereo image 
    IDirect3DSurface9 *_backBuf;  


-------------------------------------------------------- 
    // the code  
#include <windows.h> 
#include <windowsx.h> 
#include <d3d9.h> 
#include <d3dx9.h> 
#include <strsafe.h> 

#pragma comment (lib, "d3d9.lib") 

#define NVSTEREO_IMAGE_SIGNATURE 0x4433564e //NV3D 

typedef struct _Nv_Stereo_Image_Header 
{ 
unsigned int dwSignature; 
unsigned int dwWidth; 
unsigned int dwHeight; 
unsigned int dwBPP; 
unsigned int dwFlags; 
} NVSTEREOIMAGEHEADER, *LPNVSTEREOIMAGEHEADER; 


// ORedflags in the dwFlagsfielsof the _Nv_Stereo_Image_Headerstructure above 
#define SIH_SWAP_EYES 0x00000001 
#define SIH_SCALE_TO_FIT 0x00000002 

// call at start to set things up 
void DisplayWidget::create3D() 
{ 
     _size = QSize(1680,1050); //resolution of my Samsung 2233z 

     _d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface 

     D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information 

     ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use 
     d3dpp.Windowed = FALSE; // program fullscreen 
     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames 
     d3dpp.hDeviceWindow = winId(); // set the window to be used by Direct3D 
     d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; // set the back buffer format to 32 bit // or D3DFMT_R8G8B8 
     d3dpp.BackBufferWidth = _size.width(); 
     d3dpp.BackBufferHeight = _size.height(); 
     d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 
     d3dpp.BackBufferCount = 1; 

     // create a device class using this information and information from the d3dpp stuct 
     _d3d->CreateDevice(D3DADAPTER_DEFAULT, 
          D3DDEVTYPE_HAL, 
          winId(), 
          D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
          &d3dpp, 
          &_d3ddev); 


    //3D VISION uses a single surface 2x images wide and image high 
    // create the surface 
    _d3ddev->CreateOffscreenPlainSurface(_size.width()*2, _size.height(), D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &_imageBuf, NULL); 

    set3D(); 

} 

// call to put 3d signature in image 
void DisplayWidget::set3D() 
{ 

    // Lock the stereo image 
    D3DLOCKED_RECT lock; 
    _imageBuf->LockRect(&lock,NULL,0); 

    // write stereo signature in the last raw of the stereo image 
    LPNVSTEREOIMAGEHEADER pSIH = (LPNVSTEREOIMAGEHEADER)(((unsigned char *) lock.pBits) + (lock.Pitch * (_size.height()-1))); 

    // Update the signature header values 
    pSIH->dwSignature = NVSTEREO_IMAGE_SIGNATURE; 
    pSIH->dwBPP = 32; 
    //pSIH->dwFlags = SIH_SWAP_EYES; // Src image has left on left and right on right, thats why this flag is not needed. 
    pSIH->dwFlags = SIH_SCALE_TO_FIT; 
    pSIH->dwWidth = _size.width() *2; 
    pSIH->dwHeight = _size.height(); 

    // Unlock surface 
    _imageBuf->UnlockRect(); 

} 

// call in display loop 
void DisplayWidget::paintEvent() 
{ 
    // clear the window to a deep blue 
    //_d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0); 

    _d3ddev->BeginScene(); // begins the 3D scene 

    // do 3D rendering on the back buffer here 
    RECT destRect; 
    destRect.left = 0; 
    destRect.top = 0; 
    destRect.bottom = _size.height(); 
    destRect.right = _size.width(); 

    // Get the Backbuffer then Stretch the Surface on it. 
    _d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_backBuf); 
    _d3ddev->StretchRect(_imageBuf, NULL, _backBuf, &destRect, D3DTEXF_NONE); 
    _backBuf->Release(); 

    _d3ddev->EndScene(); // ends the 3D scene 

    _d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame 
} 

// my images come from a camera 
// _left and _right are QImages but it should be obvious what the functions do 
void DisplayWidget::getImages() 
{ 
       RECT srcRect; 
       srcRect.left = 0; 
       srcRect.top = 0; 
       srcRect.bottom = _size.height(); 
       srcRect.right = _size.width(); 

       RECT destRect;    
       destRect.top = 0; 
       destRect.bottom = _size.height(); 

       if (isOdd()) {      
        destRect.left = _size.width(); 
        destRect.right = _size.width()*2; 
        // get camera data for _left here, code not shown    
        D3DXLoadSurfaceFromMemory(_imageBuf, NULL, &destRect,_right.bits(),D3DFMT_A8R8G8B8,_right.bytesPerLine(),NULL,&srcRect,D3DX_DEFAULT,0);   
       } else { 
        destRect.left = 0; 
        destRect.right = _size.width(); 
        // get camera data for _right here, code not shown   
        D3DXLoadSurfaceFromMemory(_imageBuf, NULL, &destRect,_left.bits(),D3DFMT_A8R8G8B8,_left.bytesPerLine(),NULL,&srcRect,D3DX_DEFAULT,0);   
       } 


       set3D(); // add NVidia signature 

} 

DisplayWidget::~DisplayWidget() 
{ 
    _d3ddev->Release(); // close and release the 3D device 
    _d3d->Release(); // close and release Direct3D 

} 
+0

고마워요! NVidia는 실제로이를 명확하게하지 않습니다. Pro 카드 (Quadra)의 경우 OpenGL에서 "제대로 작동"할 수 있다고 생각하지만 소비자 카드에는 이상한 트릭이 있습니다. 방금 NVAPI에 대한 몇 가지 페이지를 보았습니다.이 페이지는 카드를 다양한 모드로 찔러 넣을 수 있습니다. 소비자 카드는 전문 카드와 달리 "전체 화면"모드에서만 스테레오를 처리하므로 샘플 코드를보고 싶습니다. –

+0

AFAIK는 전체 화면 모드에서만 (제대로) 작동합니다. NVAPI 문서는 쓸모가 없습니다. 많은 사람들이 인터넷을 통해이 문제를 해결하려고 노력하고 있습니다.엔비디아는 업계 사람들에게조차도 전혀 도움이되지 않습니다. –

+0

ps. http://www.mtbs3d.com/phpBB/에서 3dvision 전문가를위한 포럼을 체크 아웃 –

3

코드에 남아 있지만, 난 그냥 GTX를 제외한만을 사용하여 작동하도록 입체 3D를 가지고 수 있습니다 580 및 OpenGL. 쿼드로 카드 나 DirectX가 필요 없습니다.

nVidia 3D Vision 드라이버와 IR 이미 터가 있고 nVidia 제어판에서 이미 터를 항상 켜기로 설정하십시오.

내 게임 엔진에서 120Hz로 전체 화면 모드로 전환 한 다음 약간의 절두체 오프셋을 사용하여 장면을 두 번 렌더링합니다 (수동 구현 "nvidia 자신의 설명서 PDF"에 따라 "2010_GTC2010.pdf").

쿼드 버퍼 또는 다른 트릭이 필요하지 않습니다. 훌륭한 기능입니다. 또한 컨버전스 등 모든 설정을 제어 할 수 있습니다.