Вопрос из облости фантастики. Z-ScreenShot.

Тема в разделе "WASM.DirectX", создана пользователем AlexBond, 1 окт 2005.

  1. AlexBond

    AlexBond Member

    Публикаций:
    0
    Регистрация:
    30 янв 2005
    Сообщения:
    69
    Адрес:
    Belarus
    Можно ли захватить программно из DirectX или OpenGL приложений z-буфер или что-то подобное, короче необходимо получить информацию о глубине картинки. Иными словами сдлать скриншот глубины.

    Примечание: захват необходимо произвести из другой программы.



    Я понимаю, что звучит это бредом, даже keYMax написал что это не реально. Но если кто знает, напишите, что вообще можно захватывать из 3D-приложений. И вообще реально ли получить доступ к видео памяти. И что для этого нужно.
     
  2. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    AlexBond



    Вот что можно сделать в первом приближении. Делаешь то, что у товарища Рихрета называется "Троянской DLL". Тут была тема, называлась Forward DLL. Мониторишь хендлы контекстов. А т.к. код-граббер будет в приаттаченой к процессу dll-ке, то никто не будет возражать, если ты скажем перед SwapBuffers (OpenGL) сделаешь дамп z-Buffer-а. При правильном подходе по крайней мере для OpenGL можно написать практически универсальную dll-ку.
     
  3. AlexBond

    AlexBond Member

    Публикаций:
    0
    Регистрация:
    30 янв 2005
    Сообщения:
    69
    Адрес:
    Belarus
    _DEN_



    А смогу ли я использовать функции из библиотеки, вместо которой поставлю свою.



    Можно ли переодресовать вызов определенной функции dll'ки, если да то как.
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    AlexBond







    Конечно.







    Не, мужик, так не годится ;) Ложечку за маму, ложечку за папу? ;) Давай-ка не ленись, поиск по форуму: "Forward DLL"
     
  5. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    keYMax написал что это не реально



    а в чем трудность?

    keYMax писал ДЛЛ-перехватчик, думаю нужно перехватить метод Present или Clear. Дальше получить интерфес буфера методом GetDepthStencilSurface, ну а потом Lock. Трудность в том, что GetDepthStencilSurface может работать не со всеми типами буфера, а только с D3DFMT_D16_LOCKABLE.

    <font color="#808080][многозначительно]я так дууууууумаю :)</font><!--color-->
     
  6. AlexBond

    AlexBond Member

    Публикаций:
    0
    Регистрация:
    30 янв 2005
    Сообщения:
    69
    Адрес:
    Belarus
    _DEN_ может я многого не понимаю, но из темы "Forward DLL" я не нашел ответ на твой вопрос как в этом случае не трогая exe-шник заставить его загрузить мою dll? Так у тебя это получилось сделать?



    По словам в exe-шнике kernel32 меняем на kernel33, нужно менять название dll'ки в exe-шнике. Если нужно менять сам exe-шник, то метод не так уж хорош, т.к. это уже будет не интересно, менять каждый exe-шник с которого хочешь получить дамп буфера.



    Kozyr__

    а в чем трудность?



    keYMax писал:

    Для того чтобы блокировать поверхность, при создании устройства в структуре D3DPRESENT_PARAMETERS в поле AutoDepthStencilFormat должен быть флаг D3DFMT_D16_LOCKABLE. К тому же поверхность имеющая хоть какие то настройки Multysampling'а не подлежит блокированию.

    Именно здесь тебя постигнет первый облом. Создать устройство с таким флагом не удастся почти никогда. Если ты родился под счастливой звездой, возможно тебе и повезет.




    Не думаю, что у всех 3D-приложений будет включен D3DFMT_D16_LOCKABLE.



    Итак, передо мной 3 трудности:

    1. Подключить свою dll'ку к exe-шнику, не меняя его.

    2. Заставить программу вызывать мою функцию первой.

    3. Сделать дамп z-буфера(DirectX), в OpenGL, думаю, выход есть.
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Кидай рядом с exe-шником свою dll и exe-шник с расширением .exe.local
     
  8. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    AlexBond

    Итак, передо мной 3 трудности

    1. Подключить свою dll'ку к exe-шнику, не меняя его.

    2. Заставить программу вызывать мою функцию первой.




    Это только одна трудность :)

    Когда ты подключишь свою dll'ку - твои функции будут запускаться первыми, после чего ты должен будешь вызвать соответствующую функцию из оригинальной dll.

    Про подключение dll здесь читал?



    3. Сделать дамп z-буфера(DirectX), в OpenGL, думаю, выход есть

    Для DX можно перехватить CreateDevice и насильно поставить D3DFMT_D16_LOCKABLE, думаю, это не повлияет на нормальную работу проги.
     
  9. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    Насильно в CreateDevice можно поставить много чего, и во множестве случаев это сработает...



    Просто я не могу понять зачем нужны значения из Z-Буфера

    напрямую ввиде массива...



    Например на том же Gamedev.ru были топики на эту тему, но там простого решения так и не нашли, а были различные извращения с шейдерами, и сохранением значений в текстуру...



    На мой взгляд сама идея получения значений несколько странная, но это мое и только мое мнение
     
  10. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    AlexBond

    Заинтриговал ты меня этим вопросом - я сегодня пол дня потратил, вместо того чтобы делом заниматься :)



    Сделал я длл, которая цепляется к проге и по нажатию F2 делае скриншот.



    Написана прога по-быстрому, поэтому не очень красива внутри и почти не протестирована (может есть баги), но на подопытном файле работает :)



    Я не до конца разобрался со значениями Z-Buffer: в этой версии берутся биты 4..11 , но на примерах keYMax это не подходит (артефакты вылазят), нужно брать биты 3..10. Как правильно здесь поступить я не знаю - пробуй сам.

    [​IMG] 1839541359__Z_Buffer.zip
     
  11. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    keYMax

    Просто я не могу понять зачем нужны значения из Z-Буфера напрямую ввиде массива...



    Мне кажется я знаю зачем, но пусть лучше AlexBond сам расскажет :)
     
  12. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    Хм, только что попробовал свою длл запустить на работе - не получилось :dntknw:

    Похоже интегрированная видяха не любит тип буфера D3DFMT_D16_LOCKABLE, а дома на RADEON'е работает.
     
  13. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    Вот это и является как раз проблемой, что D3DFMT_D16_LOCKABLE поддерживается не всеми видеокартами, поэтому найти универсальное простое решение не так просто...



    Для интереса несколько ссылок с обсуждением этого вопроса:



    Gamedev.ru forum

    Gamedev.ru forum

    Gamedev.ru forum

    Gamedev.ru forum

    Gamedev.ru forum

    Gamedev.net forum
     
  14. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    keYMax

    D3DFMT_D16_LOCKABLE поддерживается не всеми видеокартами

    А ты запускал, у тебя работает?

    Может это проблема только для старых карт и интегрированных? (почитал твои ссылки - так и не понял какие карты поддерживают, а какие нет).
     
  15. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    У меня не работает тоже... GeForce 4200Ti

    Беглым поиском нашел что на карточках ATI такое срабатывает, а вот на NVidia туманно все...



    Ссылки подходят только для ознакомительных целей, в частности, как люди задавались этим же вопросом и что из этого получилось...
     
  16. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    keYMax

    У меня не работает тоже... GeForce 4200Ti

    Беглым поиском нашел что на карточках ATI такое срабатывает, а вот на NVidia туманно все...




    Ясно. Значит, нужно шейдеры ковырять.



    Ссылки подходят только для ознакомительных целей, в частности, как люди задавались этим же вопросом и что из этого получилось...



    :))
     
  17. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан




    Так и не понял, при чем тут шейдеры. Чем glReadPixels не устраивает?
     
  18. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    на карточках ATI такое срабатывает, а вот на NVidia туманно все...



    Вот что мне еще пришло в голову: если все дело в железе, то использовать только программную прорисовку (для этого поставить debug версию DX Runtime и насильно ставить проге D3DDEVTYPE_REF)

    Это была мысль вслух :)



    _DEN_

    Чем glReadPixels не устраивает?



    Цепляться нужно к чужой программе, которая не обязательно использует OpenGL :) Все что я писал, касалось DX.
     
  19. AlexBond

    AlexBond Member

    Публикаций:
    0
    Регистрация:
    30 янв 2005
    Сообщения:
    69
    Адрес:
    Belarus
    У меня никак не получается сделать Forward DLL!!!

    Пробую для OpenGL'а, кстати, SwapBuffer находиться в GDI32 поэтому про него можно сразу забыть, т.к. GDI32 грузиться с системой. Поэтом снимать буфер остается только перед glClear, создал OpenGL32.dll, положил рядом с exe-шником, exe-шник грузит мою OpenGL32.dll, но не может загрузить оригинальную, в чем тут проблема?



    Пример:

    ...

    _glBegin proc

    jmp [glBegin]

    _glBegin endp



    _glBindTexture proc

    jmp [glBindTexture]

    _glBindTexture endp



    _glBitmap proc

    jmp [glBitmap]

    _glBitmap endp

    ...

    В отладчике программа виснет зацикливаясь на OPENGL32.wglChoosePixelFormat, т.е. при первом обращении к dll.

    Что я не так делаю?



    _DEN_ Кидай рядом с exe-шником свою dll и exe-шник с расширением .exe.local

    А какой второй exe-шник с расширением .exe.local, пустой, ну и что это изменит?



    Kozyr__

    Сделал я длл, которая цепляется к проге и по нажатию F2 делае скриншот.

    У меня пишет "CreateDevice failed!" и все. У меня GeForce4 MX 440. Сюдя по всему, про DirectX можно забыть.



    Мне кажется я знаю зачем, но пусть лучше AlexBond сам расскажет :)

    Ну ладно, Z-buffer мне необходим, чтобы получать глубинные карты, которые потом я преобразую в стереокартинки. Давно мечтал сделать картинки из разных там игр, но не знал как. Кто не понял что такое стереокартинки тому сюда.



    _DEN_

    Чем glReadPixels не устраивает?

    Очень даже устраивает, но как говарилось выше, dll'ка работать не хатит. :dntknw:



    Кстати, а как сделать скриншот на OpenGL/DirectX'е превышающий разрешение экрана?
     
  20. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    AlexBond

    Ты смотрел ДЛЛ, которую я здесь выкладывал? Там форвардинг работает.



    как сделать скриншот на OpenGL/DirectX'е превышающий разрешение экрана?

    Наверное, отрендерить в текстуру бОльшего размера. Тебе в своей программе или опять в чужой?