How to set up a graphics card that supports stereo to display stereo images?

I would like to write my own stereo image viewer, because there are some functions that I need that are not included with my NVidia / EVGA GTX 580.

I canโ€™t figure out how to program the card to enter shutterglass mode, where every other frame (at 120 Hz) alternates left and right.

I looked at the OpenGL, Direct3D, and XNA APIs, as well as information from NVIDIA, and cannot figure out how to get started. How to set separate left and right images, how can I show the screen to display it, and how can I tell the driver to activate the solar glass transmitter?

(Another disappointment is that whenever I use related software to view stereo images and videos in shutterglass mode, it is displayed in full screen mode and the screen blinks when I enter this mode - even though I launch the screen with a frequency of 120 Hz in 2D. Is there a way to have a 3D surface in the window without disturbing the rest of the screen on NVIDIA "gamer" cards that can work in 3D (570, 580)?

+4
source share
2 answers

For NVidia 3Dvision with the GEForce range, you need to write a DirectX full-screen surface twice the width of the display with the left image on the left, on the right (duh).
Then you need to write the magic value in the lower left corner of the image that the NVision driver takes and turns on the glasses, you do not need nvapi.dll

With Nvidia pro glasses and a Quadra card, you can use the regular OpenGL API.

ps.I found some sample code that manages to do this with a regular window.
Edit - it was a low-level USB code talking to xmitter that I can never build, I think it eventually became http://sourceforge.net/projects/libnvstusb/

Here is sample code for full screen with NVision glasses.
I am not a DirectX expert, so some of them may be less optimal.
My application is also based on Qt, there may be some Qt bits left in the code

----------------------------------------------------------------- // 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 } 
+2
source

I'm a little late for this, but I just got stereoscopic 3D to work using only the GTX 580 and OpenGL. No need for a quad card or DirectX.

I have an nVidia 3D Vision driver and an IR emitter and just set the emitter to "Always on" in the nVidia control panel.

In my game engine, I switched to full-screen mode with a frequency of 120 Hz and twice visualized a scene with a slight offset of a truncated cone (according to nVidiaโ€™s own PDF documentation for manual implementation " 2010_GTC2010.pdf ").

No ATVs or any other tricks are needed; it works great. In addition, I control all settings, such as convergence, etc.

+3
source

Source: https://habr.com/ru/post/1338797/


All Articles