Просмотр 3D-изображения с помощью AMD Quad Buffer SDK — DirectX 9

В настоящее время я работаю над проектом, и мне нужно отобразить 3D-изображение, используя изображения, снятые с помощью 3D-камеры Bumblebee2. Я работаю на компьютере MSI AE2420, на котором установлен AMD HD 5730 с поддержкой 3D. У меня также есть затворное стекло. для просмотра изображений в стереорежиме.

Я использую библиотеки DirectX 9 (d3dx9.h). IDE - это VS 2008 Express Edition.

У меня есть образцы изображений (слева и справа), и я импортировал их в программу последовательно с линиями;

pDevice->CreateOffscreenPlainSurface(IMAGE_WIDTH,IMAGE_HEIGHT,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&leftImageBuffer,NULL);
pDevice->CreateOffscreenPlainSurface(IMAGE_WIDTH,IMAGE_HEIGHT,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&rightImageBuffer,NULL);

D3DXLoadSurfaceFromFile(leftImageBuffer,NULL,NULL,"left0000.bmp",NULL,D3DX_FILTER_NONE,0,NULL)
D3DXLoadSurfaceFromFile(rightImageBuffer,NULL,NULL,"right0000.bmp",NULL,D3DX_FILTER_NONE,0,NULL)

После некоторых исследований я обнаружил, что Direct3D9 не поддерживает активный стереофонический буфер с четырьмя буферами. Поэтому я не могу использовать четыре буфера (левый передний, левый задний, правый передний, правый задний). Вот где задействован AMD Quad Buffer SDK. Они указывают, что DirectX 9 не разрешайте активное стерео, а мне нужно использовать функции SDK. Я использую «AtiDx9Stereo.h», который является одним из шести файлов заголовков в SDK (остальные пять предназначены для DirectX 11 и DirectX10).

Однако после долгого кодирования и тестирования мне наконец удалось включить стерео, и теперь я вижу левое изображение на левой стороне стекла затвора, но на правой стороне стекла я ничего не вижу. справа я вижу только левое изображение. Когда я закрываю левый глаз, я вижу только черную страницу (или синюю после очистки цели рендеринга до синего или другого цвета). Вот мой код рендеринга и инициализация указателей. Если кто-то работал с этой средой, было бы здорово поделиться некоторыми знаниями.

Операторы инициализации

pD3D=Direct3DCreate9(D3D_SDK_VERSION);
pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWindow,64,&d3pp,&pDevice);
pDevice->CreateOffscreenPlainSurface(10,10,(D3DFORMAT)FOURCC_AQBS,D3DPOOL_DEFAULT,&driverCommSurface,NULL);
SendStereoCommand(ATI_STEREO_ENABLESTEREO, NULL, 0, 0, 0);
SendStereoCommand(ATI_STEREO_GETLINEOFFSET, (BYTE *)(&lineOffset), sizeof(DWORD), 0, 0);

После этих утверждений моя функция render() выглядит примерно так:

D3DVIEWPORT9 viewPort;

    memset(&viewPort,0,sizeof(viewPort));
    pDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backBuffer);
    viewPort.X = 0;
    viewPort.Width = WINDOW_WIDTH;
    viewPort.Height = WINDOW_HEIGHT;

    if(SUCCEEDED(pDevice->BeginScene()))        //Start the device .
    {
        pDevice->SetRenderTarget(0, backBuffer);

        // Draw Right Eye Scene

        viewPort.Y = lineOffset;
        pDevice->SetViewport(&viewPort);
        pDevice->StretchRect(rightImageBuffer,NULL,backBuffer,NULL,D3DTEXF_LINEAR);




        // Draw Left Eye Scene

        viewPort.Y = 0;
        pDevice->SetViewport(&viewPort);
        pDevice->StretchRect(leftImageBuffer,NULL,backBuffer,NULL,D3DTEXF_LINEAR);

        backBuffer->Release();
        pDevice->EndScene();
        // Present both left and right buffers to the driver which will continuously
        // alternate between them until the next present

        pDevice->Present(NULL, NULL, NULL, NULL);





        return S_OK;
    }
    return E_FAIL;

И в WINMAIN я вызываю рендеринг с этими операторами;

MSG msg;                                                    

    while(GetMessage(&msg,NULL,0,0))
    {

        if(str.isReady)                     //If rendering fails,an error-message is shown.
        {
            str.SwitchToRightEye();
            str.pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x000000ff, 1.0f, 0.0f); 
            str.UpdateRightQuadBuffer();
            str.render();

        }

        TranslateMessage(&msg);                     //Translate and dispatch the messages for the getMessage loop.
        DispatchMessage(&msg);
    }

person MCG    schedule 05.12.2011    source источник


Ответы (3)


Я думаю, вам стоит попробовать;

viewPort.Height = lineOffset;

вместо

viewPort.Height = WINDOW_HEIGHT;
person Emir Akaydın    schedule 08.12.2011
comment
Я тоже пробовал это. Это ничего не меняет. Даже AMD не предоставляет никакой надлежащей документации для изображения или видео стерео. Их форумы просто краб. Они не отвечают ни на один вопрос! Я буду держаться подальше от AMD с этого момента. У nVidia есть много простых документов, и их подпись может быть записана в VRAM напрямую с помощью команды подкачки, поэтому пользователю не нужно писать дополнительные функции подкачки. Я все еще работаю над этим. Я пытался запустить проект на OpenGL, но из-за того, что IZ3D не разрешает стерео OpenGL на AMD, я даже не могу включить стереорежим! - person MCG; 08.12.2011

Вы должны вызывать SendStereoCommand(ATI_STEREO_SETDSTEYE,..) до и после вызова StretchRect для rightImageBuffer.

Что-то такое:

RECT destRect;

// Draw Right Eye Scene
destRect.top = lineOffset;
destRect.bottom = lineOffset + height;
viewPort.Y = lineOffset;

pDevice->SetViewport(&viewPort);

DWORD dwEye = ATI_STEREO_RIGHTEYE;
SendStereoCommand(ATI_STEREO_SETDSTEYE, NULL, 0, (BYTE *)&dwEye, sizeof(dwEye));

pDevice->StretchRect(rightImageBuffer,NULL,backBuffer,&destRect,D3DTEXF_LINEAR);    

// restore the destination
dwEye = ATI_STEREO_LEFTEYE;
SendStereoCommand(ATI_STEREO_SETDSTEYE, NULL, 0, (BYTE *)&dwEye, sizeof(dwEye)); 

// Draw Left Eye Scene
destRect.top = 0;
destRect.bottom = height;
viewPort.Y = 0;
pDevice->SetViewport(&viewPort);
pDevice->StretchRect(leftImageBuffer,NULL,backBuffer,&destRect,D3DTEXF_LINEAR);

...

и удалите этот код из WINMAIN:

str.SwitchToRightEye();
str.pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x000000ff, 1.0f, 0.0f); 
str.UpdateRightQuadBuffer();

Обновление:

Я проверил код в нашем драйвере iZ3D, и я думаю, что вы также должны установить правильный прямоугольник назначения в вызовах StretchRect для BackBuffer в соответствии с lineOffset. Вероятно, это могло бы работать без изменения области просмотра вообще.

Вы должны убедиться, что драйвер возвращает правильное значение для lineOffset (немного больше, чем высота заднего буфера) и HRESULT, возвращаемый из SendStereoCommand().

person KindDragon    schedule 08.12.2011
comment
Я тоже попробовал это, и ничего не изменилось. Просто черный экран в правом стекле вместо синего, потому что я удаляю оператор Clear(). Я не думаю, что стереокоманды AMD работают хорошо. Потому что они ни на что не влияют. Кроме того, эта строка включает стерео; pDevice->CreateOffscreenPlainSurface(10,10(D3DFORMAT)FOURCC_AQBS,D3DPOOL_DEFAULT,&driverCommSurface,NULL); не SendStereoCommand(ATI_STEREO_ENABLESTEREO,...) - person MCG; 08.12.2011
comment
Я изменил программу так, как вы сказали, но опять же в правой части изображения нет. Есть много операторов if, которые проверяют значения HRESULT, и кажется, что все работает нормально. Но lineOffset не такое уж большое значение, оно равно 204. Я нашел его во время отладки. - person MCG; 08.12.2011
comment
да, это работает. однако, не имеет значения, удаляю ли я инструкции ENABLE_RIGHT или ENABLE_STEREO, демо все еще работает в стереорежиме. это действительно интересно - person MCG; 09.12.2011

Я решил проблему, используя совершенно другой метод из документации AMD. И я думаю, что функции в их SDK не работают должным образом. Для меня было совершенно пустой тратой времени пытаться выполнить эти шаги в документации.

Вот ссылка на проект.

http://code.google.com/p/3d-viewer-buffer

person MCG    schedule 13.12.2011