2011-02-08 6 views
4

Я хотел бы написать свой собственный просмотрщик стереоизображения, потому что есть определенные особенности, мне нужно, которые отсутствуют в одном комплекте с моим NVidia/EVGA GTX 580.Как настроить графическую карту с поддержкой стереофонического стереофонического изображения?

Я не могу понять, как программировать чтобы войти в режим «shutterglass», где каждый другой кадр (на 120 Гц) чередуется влево и вправо.

Я рассмотрел API OpenGL, Direct3D и XNA, а также информацию от NVIDIA и не могу понять, как начать работу. Как установить отдельные левые и правые изображения, как я могу показать экран, чтобы отобразить его, и как я могу сказать драйверу активировать передатчик солнечного стекла?

(Еще одно разочарование заключается в том, что всякий раз, когда я использую прилагаемое программное обеспечение для просмотра стереоизображений и видео в режиме shutterglass, оно находится в полноэкранном режиме, и экран мигает при входе в этот режим - хотя я запускаю экран с частотой 120 Гц в 2D Есть ли способ иметь 3D-поверхность в окне, не нарушая остальную часть экрана на картах NVIDIA «gamer», способных работать в 3D (570, 580)?

ответ

2

Для NVidia 3Dvision с диапазоном GEForce необходимо написать полноэкранную поверхность DirectX в два раза больше ширины дисплея с левым изображением слева, справа (duh).
Затем вам нужно написать магическое значение в левом нижнем углу изображения, которое NVision водитель поднимает и включает очки , вам не нужен nvapi.dll

С очками Nvidia pro и картой Quadra вы можете использовать обычный API-интерфейс OpenGL.

ps.I действительно нашел пример кода, который удается сделать это с помощью обычного окна.
Edit - это код низкого уровня USB разговаривает с xmitter, что я никогда не мог получить, чтобы построить, я думаю, что в конечном итоге стал этот 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 бесполезны, многие люди в сети работают над этим.Nvidia абсолютно бесполезны даже для людей в этой отрасли. –

+0

пс. проверить форумы на http://www.mtbs3d.com/phpBB/ для экспертов 3dvision –

3

Я немного поздно, но я только что получил стереоскопического 3D, чтобы работать, не используя ничего, кроме GTX 580 и OpenGL. Нет необходимости в квадро-карте или DirectX.

У меня есть драйвер nVidia 3D Vision и ИК-излучатель и просто установите излучатель на «Всегда включен» в панели управления nVidia.

В моем игровом движке я переключился на полноэкранный режим с частотой 120 Гц и визуализировал сцену дважды с небольшим смещением усеченного конуса (согласно собственной документации PDF от NVIDIA по ручной реализации «2010_GTC2010.pdf»).

Никаких квадроциклов или каких-либо других трюков не требуется, он отлично работает. Кроме того, я контролирую все настройки, такие как конвергенция и т. Д.

 Смежные вопросы

  • Нет связанных вопросов^_^