Ru/AVI Materials: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
(Created page with "{{pov}} Procedural Materials (Процедурные материалы) используются для воспроизведения фильмов (в частност...")
 
m (obsolete language category)
 
(8 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{pov}}
{{lang|AVI Materials}}
Используя статью {{L|Procedural Materials}} (Процедурные материалы) возможно воспроизводить фильмы (в частности, в формате AVI) на месте монитора на карте, который представляет собой обычную текстуру.  Используя эту технику, вы смогли бы создать, например, кинотеатр на вашей карте, где можно было бы просматривать фильм на экране, или сделав небольшую надстройку вы могли бы добавить возможность воспроизведения видео на VGUI-панелях.  В то время как Source Engine уже позволяет легко смотреть происходящее в других местах на карте (с использованием {{L|Point_camera}}s и {{L|func_monitor}}s), этот метод позволяет воспроизводить реальные видеофайлы с жесткого диска. Этот код / мини-тутор даст вам все необходимое, чтобы достаточно легко добавить точечные объекты (entities) для поддержки AVI-материалов на вашу карту. Эти объекты также позволят использовать определенные текстуры в качестве монитора, и выполнять различные действия - воспроизвденеие, пауза, смена видеотрека, предварительно один кадр, и т.д. Данный код во многом опирается на статью {{L|Procedural Materials}} (Процедурные материалы), которая предоставлена ребятами из Valve (еще раз спасибо, Том и Майк!)


[[Procedural Materials ]] (Процедурные материалы) используются для воспроизведения фильмов (в частности, в формате AVI) на месте текстурных материалов на карте.  Используя эту технику, вы смогли бы создать, например, кинотеатр на вашей карте, где можно было бы просматривать фильм на экране, или сделав небольшую надстройку вы могли бы добавить возможность воспроизведения видео на VGUI-панелях.   В то время как Source Engine уже позволяет легко смотреть происходящее в других местах на карте (с использованием [[Point_camera]]s и [[func_monitor]]s), этот метод позволяет воспроизводить реальные видеофайлы с жесткого диска. Этот код / мини-тутор даст вам все необходимое, чтобы достаточно легко добавить точечные объекты (entities) для поддержки AVI-материалов на вашу карту. Эти объекты также позволят использовать определенные текстуры в качестве монитора, и выполнять различные действия - воспроизвденеие, пауза, смена видеотрека, предварительно один кадр, и т.д. Данный код во многом опирается на статью [[Procedural Materials ]] (Процедурные материалы), котораяпредоставлена ребятами из Valve (еще раз спасибо, Том и Майк!)
== Принцип работы ==
{{L|Procedural Materials}} (Процедурные материалы) позволяют определить некоторые материалы как "procedural" в том смысле, что значения их пикселей задаются программно во время работы; мы получаем 2D массив пикселей, представляющий собой текстуру, которую можно динамично изменять (например, цвет). В данном случае, мы читаем кадр из фильма (который меняется в зависимости от времени воспроизведения), считываем поочередно пиксели и записываем их в текстуру. Так как это делается примерно 60 раз в секунду, мы получаем хорошее, плавное воспроизведение фильма.


== Idea ==
== Установка ==
[[Procedural Materials]] allow you to identify certain materials as ''procedural'' meaning that its pixel values are set programmatically, as the level is running; conceptually, you get a 2d array of pixels representing the texture that you then set to be whatever color you want.  In our case, we read in the appropriate frame of the movie (which frame is of course dependent on where we are in playback), read its pixels one-by-one, and write them to the texture. Since this is done roughly 60 times a second, we get a nice, smooth movie playback.
К сожалению, требуется установить немалое количество кода и изменить некоторые параметры проекта. Это не сложно, и если вы будете следовать этим инструкциям, то все будет работать.


== How to install ==
#Прочитайте тутор {{L|Procedural Materials}} (Процедурные материалы).  Все в этом уроке строится от этого.
Unfortunately, there is a fair amount of code to install, and some project settings to changeIt's all fairly straight-forward, however, and I believe that if you follow these instructions everything should work correctly.
#Скачайте этот архив (~15 МБ).  [http://cs.northwestern.edu/~ndn651/AVIMaterial.zip AVIMaterial.zip].  В нем есть все необходимые файлы.
#Скопируйте файл vf32.lib из C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib (or wherever your VS2003 is installed) в C:\MyMod\src\lib\public (изменить путь для вашего мода.)  Интегрируйте vf32.lib в ваш проект Visual Studio.  vfw32.lib это библиотека видео для Windows, функции которой мы будем использовать для чтения AVI.
#Скопируйте AVIMaterial.h и AVIMaterial.cpp в C:\MyMod\src\dlls.  Эти файлы объявляют и определяют CAVIMaterial на серверной стороне, объекты которой управляют фильмом.
#Скопируйте c_aviMaterial.h, c_aviMaterial.cpp, AVIMaterialProxy.h, AVIMaterialProxy.cpp, AVIMaterialRegen.h, и AVIMaterial.cpp в C:\SecondCity\src\cl_dll.  c_aviMaterial объявляет и определяет C_AVIMaterial, CAVIMaterial.  AVIMaterialProxy объявляет и определяет CAviMaterialProxy, который контролирует экземпляры CAviTextureRegen, который фактически создает графику фильма.
#Добавить запись о SecondCity.fgd к fgd-файлу(-ам) вашего мода в Hammer.  Это позволит видеть AVIMaterial в Hammer как отдельный точечный объект (entity).
#Скопируйте avi_panel1.vmt, avi_panel1.vtf, avi_panel2.vmt, и avi_panel2.vtf в папку materials вашего модаОни должны быть в корне.
#Скопируйте quickone.vmf и quickone.bsp в папку maps.
#Скопируйте newyorkmap.avi и category.avi в корень диска c: Вы можете поместить их в другой каталог, но тогда придется у AVIMaterial в параметре quickone указать новый путь. Не забывайте об этом.
#Откройте Visual Studio, и добавьте vfw32.lib в ваш проект. Правой кнопкой мыши по клиенту->Add->Add Existing Item (Добавить имеющийся элемент).
#В Visual Studio, добавьте c_aviMaterial.h, AVIMaterialProxy.h, и AVIMaterialRegen.h в папку Header Files (Заголовочные файлы) вашего проекта.
#В Visual Studio, добавьте c_aviMaterial.cpp, AVIMaterialProxy.cpp, и AVIMaterialRegen.cpp в папку с исходниками вашего проекта (клиент).
#В Visual Studio, добавьте AVIMaterial.h в папку Header Files (Заголовочные файлы) вашего проекта (сервер)
#В Visual Studio, добавьте AVIMaterial.cpp в папку Header Files (Заголовочные файлы) вашего проекта (сервер)
#Скомпилируйте ваш проект и запустите его.  На карте quickone вы должны увидеть два фильма по центру комнаты.


#Read the tutorial for [[Procedural Materials]].  Everything in this tutorial builds off of that.
== Как это работает ==
#Download this zip file; it's a ~15meg zip file.  [http://cs.northwestern.edu/~ndn651/AVIMaterial.zip AVIMaterial.zip].  It has all the files necessary.
CAVIMaterial и C_AVIMaterial являются типичными клиент/сервер объектами (те самые entity)Пожалуйста, ознакомьтесь со статьями {{L|Networking entities}} для получения дополнительной информацииКогда карта загружена (на примере quickone), avi_panel1 и avi_panel2 имеют соответствующие CAviMaterialProxy экземпляры для них.  (The line  
#Copy vf32.lib from C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib (or wherever your VS2003 is installed) to C:\MyMod\src\lib\public (changing the directory to be appropriate for your mod.)  Add vf32.lib to the client project in Visual Studio.  vfw32.lib is Video for Windows, which has the functions we'll use to read the AVI.
#Copy AVIMaterial.h and AVIMaterial.cpp to C:\MyMod\src\dlls.  These files declare and define CAVIMaterial, the server-side entity that controls the movies.
#Copy c_aviMaterial.h, c_aviMaterial.cpp, AVIMaterialProxy.h, AVIMaterialProxy.cpp, AVIMaterialRegen.h, and AVIMaterial.cpp to C:\SecondCity\src\cl_dll.  c_aviMaterial declares and defines C_AVIMaterial, the cleverly-named client-side version of CAVIMaterial.  AVIMaterialProxy declares and defines CAviMaterialProxy which controls instances of CAviTextureRegen, which does the actual movie drawing.
#Add the entry in SecondCity.fgd to your mod's .fgd.  This exposes our AVIMaterial entity to Hammer.
#Copy avi_panel1.vmt, avi_panel1.vtf, avi_panel2.vmt, and avi_panel2.vtf to your mod's materials directory.  They go in the root.
#Copy quickone.vmf and quickone.bsp to your mod's maps directory.  Again, they go in the root.
#Copy newyorkmap.avi and category.avi to the root of your c: drive.  (If you don't want to put them there, feel free to put them somewhere else, just make sure to update the AVIMaterial entities in quickone to point at the right location.)
#Open Visual Studio, and add vfw32.lib to the client project.  (Right-click on client->Add->Add Existing Item.)
#In Visual Studio, add c_aviMaterial.h, AVIMaterialProxy.h, and AVIMaterialRegen.h to the Header Files folder of your client project.
#In Visual Studio, add c_aviMaterial.cpp, AVIMaterialProxy.cpp, and AVIMaterialRegen.cpp to the Source Files folder of your client project.
#In Visual Studio, add AVIMaterial.h to the Header Files folder of your hl (server) project.
#In Visual Studio, add AVIMaterial.cpp to the Source Files folder of your hl (server) project.
#Compile your project, and run it.  In the quickone map, you should see two movies hanging and playing in the middle of the room.
 
== How it works ==
CAVIMaterial and C_AVIMaterial are a typical client/server entity.  Please look at the excellent article on [[Networking entities]] for more informationWhen the map loads, avi_panel1 and avi_panel2 each have a corresponding CAviMaterialProxy instantiated for them.  (The line  


  EXPOSE_INTERFACE( CAviMaterialProxy, IMaterialProxy, "AviRenderer" IMATERIAL_PROXY_INTERFACE_VERSION );
  EXPOSE_INTERFACE( CAviMaterialProxy, IMaterialProxy, "AviRenderer" IMATERIAL_PROXY_INTERFACE_VERSION );


links them to the AviRenderer listed as the proxy in avi_panel1.vmt and avi_panel2.vmt.  When Init()ted, each proxy is passed in a pointer to the IMaterial they are in charge of.  CAviMaterialProxy also has a static function that searches a static array of CAviMaterialProxy on the basis of their texture names.  This is a clunky way of allowing C_AVIMaterials to link up to the appropriate textures (otherwise you couldn't control which movie was getting drawn on which texture.)  I'm sure there's a better way to do this, please let me know if you know of one.  The CAviMaterialProxy instances are used internally by Source to draw the procedural textures; we mainly use it to passthrough commands to its CAviMaterialRegen, however.  Once a C_AVIMaterial is passed its movie filename and texture, it searches the proxies for the right one (meaning the proxy that is drawing to its texture), and records it.  It then tells the proxy (which passes it to the regenerator) the movie file to load.  From then on, the CAVIMaterial entity can be manipulated using the normal [[Inputs and Outputs | Source I/O system]].  The code is commented, please see it for implementation details.
links them to the AviRenderer listed as the proxy in avi_panel1.vmt and avi_panel2.vmt.  When Init()ted, each proxy is passed in a pointer to the IMaterial they are in charge of.  CAviMaterialProxy also has a static function that searches a static array of CAviMaterialProxy on the basis of their texture names.  This is a clunky way of allowing C_AVIMaterials to link up to the appropriate textures (otherwise you couldn't control which movie was getting drawn on which texture.)  I'm sure there's a better way to do this, please let me know if you know of one.  The CAviMaterialProxy instances are used internally by Source to draw the procedural textures; we mainly use it to passthrough commands to its CAviMaterialRegen, however.  Once a C_AVIMaterial is passed its movie filename and texture, it searches the proxies for the right one (meaning the proxy that is drawing to its texture), and records it.  It then tells the proxy (which passes it to the regenerator) the movie file to load.  From then on, the CAVIMaterial entity can be manipulated using the normal {{L|Inputs and Outputs|Source I/O system}}.  The code is commented, please see it for implementation details.


== How to use it ==
== How to use it ==
Line 66: Line 65:


== Acknowledgments ==
== Acknowledgments ==
As mentioned above, this code is really just an aggregation of different peoples' work.  [[User:Zerodegrez|Zerodegrez]] did the work for the original [[procedural materials]] tutorial, and all of this procedural code is taken straight from that.  Tom Leonard at Valve was nice enough to give me the AVI opening/reading code, and Mike Durand at Valve was very friendly and helpful about getting procedural materials working again in the SDK (turns out they were fixed in the Aug, 2006 update, who knew?)  Thanks again.   
As mentioned above, this code is really just an aggregation of different peoples' work.  [[User:Zerodegrez|Zerodegrez]] did the work for the original {{L|procedural materials}} tutorial, and all of this procedural code is taken straight from that.  Tom Leonard at Valve was nice enough to give me the AVI opening/reading code, and Mike Durand at Valve was very friendly and helpful about getting procedural materials working again in the SDK (turns out they were fixed in the Aug, 2006 update, who knew?)  Thanks again.   
Please let [[User:Ndnichols|me]] know if you have any questions, problems or suggestions.  Good luck!
Please let [[User:Ndnichols|me]] know if you have any questions, problems or suggestions.  Good luck!


[[Category:Tutorials]]
{{ACategory|Tutorials}}
[[Category:Material System]]
{{ACategory|Material System}}

Latest revision as of 03:41, 22 August 2024

English (en)Русский (ru)Translate (Translate)

Используя статью Procedural Materials(en) (Процедурные материалы) возможно воспроизводить фильмы (в частности, в формате AVI) на месте монитора на карте, который представляет собой обычную текстуру. Используя эту технику, вы смогли бы создать, например, кинотеатр на вашей карте, где можно было бы просматривать фильм на экране, или сделав небольшую надстройку вы могли бы добавить возможность воспроизведения видео на VGUI-панелях. В то время как Source Engine уже позволяет легко смотреть происходящее в других местах на карте (с использованием Point_camera(en)s и func_monitor(en)s), этот метод позволяет воспроизводить реальные видеофайлы с жесткого диска. Этот код / мини-тутор даст вам все необходимое, чтобы достаточно легко добавить точечные объекты (entities) для поддержки AVI-материалов на вашу карту. Эти объекты также позволят использовать определенные текстуры в качестве монитора, и выполнять различные действия - воспроизвденеие, пауза, смена видеотрека, предварительно один кадр, и т.д. Данный код во многом опирается на статью Procedural Materials(en) (Процедурные материалы), которая предоставлена ребятами из Valve (еще раз спасибо, Том и Майк!)

Принцип работы

Procedural Materials(en) (Процедурные материалы) позволяют определить некоторые материалы как "procedural" в том смысле, что значения их пикселей задаются программно во время работы; мы получаем 2D массив пикселей, представляющий собой текстуру, которую можно динамично изменять (например, цвет). В данном случае, мы читаем кадр из фильма (который меняется в зависимости от времени воспроизведения), считываем поочередно пиксели и записываем их в текстуру. Так как это делается примерно 60 раз в секунду, мы получаем хорошее, плавное воспроизведение фильма.

Установка

К сожалению, требуется установить немалое количество кода и изменить некоторые параметры проекта. Это не сложно, и если вы будете следовать этим инструкциям, то все будет работать.

  1. Прочитайте тутор Procedural Materials(en) (Процедурные материалы). Все в этом уроке строится от этого.
  2. Скачайте этот архив (~15 МБ). AVIMaterial.zip. В нем есть все необходимые файлы.
  3. Скопируйте файл vf32.lib из C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib (or wherever your VS2003 is installed) в C:\MyMod\src\lib\public (изменить путь для вашего мода.) Интегрируйте vf32.lib в ваш проект Visual Studio. vfw32.lib это библиотека видео для Windows, функции которой мы будем использовать для чтения AVI.
  4. Скопируйте AVIMaterial.h и AVIMaterial.cpp в C:\MyMod\src\dlls. Эти файлы объявляют и определяют CAVIMaterial на серверной стороне, объекты которой управляют фильмом.
  5. Скопируйте c_aviMaterial.h, c_aviMaterial.cpp, AVIMaterialProxy.h, AVIMaterialProxy.cpp, AVIMaterialRegen.h, и AVIMaterial.cpp в C:\SecondCity\src\cl_dll. c_aviMaterial объявляет и определяет C_AVIMaterial, CAVIMaterial. AVIMaterialProxy объявляет и определяет CAviMaterialProxy, который контролирует экземпляры CAviTextureRegen, который фактически создает графику фильма.
  6. Добавить запись о SecondCity.fgd к fgd-файлу(-ам) вашего мода в Hammer. Это позволит видеть AVIMaterial в Hammer как отдельный точечный объект (entity).
  7. Скопируйте avi_panel1.vmt, avi_panel1.vtf, avi_panel2.vmt, и avi_panel2.vtf в папку materials вашего мода. Они должны быть в корне.
  8. Скопируйте quickone.vmf и quickone.bsp в папку maps.
  9. Скопируйте newyorkmap.avi и category.avi в корень диска c: Вы можете поместить их в другой каталог, но тогда придется у AVIMaterial в параметре quickone указать новый путь. Не забывайте об этом.
  10. Откройте Visual Studio, и добавьте vfw32.lib в ваш проект. Правой кнопкой мыши по клиенту->Add->Add Existing Item (Добавить имеющийся элемент).
  11. В Visual Studio, добавьте c_aviMaterial.h, AVIMaterialProxy.h, и AVIMaterialRegen.h в папку Header Files (Заголовочные файлы) вашего проекта.
  12. В Visual Studio, добавьте c_aviMaterial.cpp, AVIMaterialProxy.cpp, и AVIMaterialRegen.cpp в папку с исходниками вашего проекта (клиент).
  13. В Visual Studio, добавьте AVIMaterial.h в папку Header Files (Заголовочные файлы) вашего проекта (сервер)
  14. В Visual Studio, добавьте AVIMaterial.cpp в папку Header Files (Заголовочные файлы) вашего проекта (сервер)
  15. Скомпилируйте ваш проект и запустите его. На карте quickone вы должны увидеть два фильма по центру комнаты.

Как это работает

CAVIMaterial и C_AVIMaterial являются типичными клиент/сервер объектами (те самые entity). Пожалуйста, ознакомьтесь со статьями Networking entities(en) для получения дополнительной информации. Когда карта загружена (на примере quickone), avi_panel1 и avi_panel2 имеют соответствующие CAviMaterialProxy экземпляры для них. (The line

EXPOSE_INTERFACE( CAviMaterialProxy, IMaterialProxy, "AviRenderer" IMATERIAL_PROXY_INTERFACE_VERSION );

links them to the AviRenderer listed as the proxy in avi_panel1.vmt and avi_panel2.vmt. When Init()ted, each proxy is passed in a pointer to the IMaterial they are in charge of. CAviMaterialProxy also has a static function that searches a static array of CAviMaterialProxy on the basis of their texture names. This is a clunky way of allowing C_AVIMaterials to link up to the appropriate textures (otherwise you couldn't control which movie was getting drawn on which texture.) I'm sure there's a better way to do this, please let me know if you know of one. The CAviMaterialProxy instances are used internally by Source to draw the procedural textures; we mainly use it to passthrough commands to its CAviMaterialRegen, however. Once a C_AVIMaterial is passed its movie filename and texture, it searches the proxies for the right one (meaning the proxy that is drawing to its texture), and records it. It then tells the proxy (which passes it to the regenerator) the movie file to load. From then on, the CAVIMaterial entity can be manipulated using the normal Source I/O system(en). The code is commented, please see it for implementation details.

How to use it

Currently, the CAVIMaterial entity has the following inputs:

  • Play - This will start playing whatever movie is set as the current movie. If the movie has not played before, it will start from the beginning; if the movie is paused, it will resume playing back from where it was paused. If the movie is already playing, it has no effect. If no movie is loaded, nothing will happen.
  • Pause - This will pause the currently-playing movie, leaving the last frame visible. If the movie is already paused, nothing will happen. If there is no currently-playing movie, nothing will happen.
  • Stop - This will end and clear the currently playing movie.
  • AdvanceFrame - This will advance the movie one frame. If no movie is currently loaded, nothing will happen. This input assumes the movie is already paused, but doesn't enforce it.
  • SetMovie - This input takes a string which should be the absolute path to an AVI on disk, and sets that AVI to be the currently loaded movie. You should stop playing any active movies before setting a new movie.

The CAVIMaterial entity has the following KeyValues:

  • TextureName - This is the name of the material that this CAVIMaterial will draw to. If a material is in more than one place of the map, the movie will be shown on all of them.
  • MovieName - This is the absolute path on disk to the AVI that will be initially loaded by the CAviMaterialRegen.

The CAVIMaterial entity has the following spawn flags:

  • Play movie immediately - This will start the movie specified in MovieName playing as soon as the map loads.
  • Loop movie - This will cause the movie to begin playing again immediately after it is completed.

Potential improvements

There are a lot of improvements one could make to this code. A few of these are listed below.

  1. Fix bugs in the existing code. I am only moderately familiar with C++ and the Source engine, so if something looks wrong or unnecessarily awkward, it definitely may be. Please let me know, and I'll be happy to update the code.
  2. Add various movie controls. You could straight-forwardly add fast-forward, rewind, slo-mo, etc.
  3. Optimize this code. This code has not been tweaked for performance at all; it runs acceptably, but there is definitely room for speedup in CAviMaterialRegen::RegenerateTextureBits().
  4. Have the path for the movies use Steam directories. Right now, the path to the movie is always an absolute directory, but it should probably be specified in relation to the Steam directories if you actually want to use movies in your mod.
  5. Add support for other movie types You could presumably add support for other movie types (Divx, WMV, etc.), but you're probably better off using a program to convert other movie types to AVIs offline. We've had luck with the open source | ffmpeg, but YMMV.
  6. Improve entity use It's kind of weird/clunky to have to specify the texture name to draw to in the Hammer entries for the CAVIMaterials. There's probably a better way to do this; figure it out!
  7. Add more avi_panels With avi_panel1 and avi_panel2, you can only show two distinct movies at the same time; if you need more than that, simply copy and paste avi_panel1.vtf and avi_panel1.vmt and rename them appropriately. Don't forget to update the .vmt to point at the new .vtf.

Disclaimer

This code is far from bug-free or production ready. It definitely works, though, and it certainly won't kill your computer or anything. If you find bugs, please contact me. I will be using this code in the future, and will certainly find bugs of my own, and I'll update the code as necessary. I wanted to get this code out and available to people before I lost the drive to write it up and everything, so here it is, warts and all.

Acknowledgments

As mentioned above, this code is really just an aggregation of different peoples' work. Zerodegrez did the work for the original procedural materials(en) tutorial, and all of this procedural code is taken straight from that. Tom Leonard at Valve was nice enough to give me the AVI opening/reading code, and Mike Durand at Valve was very friendly and helpful about getting procedural materials working again in the SDK (turns out they were fixed in the Aug, 2006 update, who knew?) Thanks again. Please let me know if you have any questions, problems or suggestions. Good luck!