Code archives/3D Graphics - Misc/3d movie playback
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Playing a movie onto an entity - but without needing CopyRect(). (Final code solution at the bottom of this thread) | |||||
Graphics3D 800,600,32,2 SetBuffer BackBuffer() font=LoadFont("arial",20) : SetFont font camera=CreateCamera() light=CreateLight() cube = CreateCube() MoveEntity cube,0,0,3 ScaleEntity cube,1,0.5,1 movietex = CreateTexture(256,128) EntityTexture cube,movietex movie$ = "sample.avi" ; <- your movie here ; any AVI or MPG hmovie = OpenMovie(movie$) framePeriod = 1000/30 frametimer = CreateTimer(framePeriod) While Not KeyHit(1) WaitTimer frametimer If t>5 t=0 If Not MoviePlaying(hmovie) CloseMovie(hmovie) hmovie = OpenMovie(movie$) frame = 0 Else SetBuffer TextureBuffer(movietex) DrawMovie(hmovie) frame = frame + 1 : Color 255,255,255 : Text 0,0,"Frame "+frame SetBuffer BackBuffer() EndIf EndIf t=t+1 TurnEntity cube,0,.4,0 UpdateWorld() : RenderWorld() Text 0,0,"AvailVidMem() "+AvailVidMem() Flip() Wend End |
Comments
| ||
doesn't work |
| ||
doesn't work either :( |
| ||
its driver dependig . some driver work with some not . with nvidia it works for my with all cards i tested |
| ||
Try drawing the movie to the backbuffer and copying it onto the texture using CopyRect. It might be more compatible. |
| ||
but slow ;) |
| ||
I think the reason the movie is not drawing is because you are calling the DrawMovie function before the Updateworld and Renderworld commands. |
| ||
Just so nobody gets the wrong idea, that would not be why the movie would not be rendered. The movie is drawn into a texture buffer, not into the back or front buffers. Check to see if your video card supports non-power-of-two textures and the size of the video to determine what will and will not work. ATI cards usually don't support them, and as a result there's usually some issues with this sort of thing. |
| ||
The original reason for writing this code was to prove that there _was_ a memory leak in the Blitz movie playback code, which Mark has since fixed (about 2 years ago). DrawMovie before UpdateWorld etc doesn't actually matter. Nilium is right though - the problem is about powers of two. The movie I was originally using was 256x128 and worked fine. When I tried odd sizes I got the same as you guys, a blank cube. The code below is a slight rewrite to cope with this. It creates a texture (based on MovieWidth and MovieHeight) which is put onto the cube. Unfortunately Blitz then does it's usual trick of resizing the texture in memory to powers of 2 which leaves black areas aroung the movie. Somebody wake Puki up - I'm sure he wrote a version that got around this (probably by buffering) but as you say was slightly slower. Mind you, on modern machines that probably wouldn't be a problem. Graphics3D 800,600,32,2 SetBuffer BackBuffer() font=LoadFont("arial",20) : SetFont font camera=CreateCamera() : light=CreateLight() cube = CreateCube() : MoveEntity cube,0,0,3 : ScaleEntity cube,1,0.5,1 movie$ = "sttoday.mpg" ; my movie is 240 x 180 hmovie = OpenMovie(movie$) w = MovieWidth(hmovie) h = MovieHeight(hmovie) movietex = CreateTexture(w,h) : EntityTexture cube,movietex CameraClsColor camera,127,127,127 framePeriod = 1000/30 : frametimer = CreateTimer(framePeriod) While Not KeyHit(1) WaitTimer frametimer If Not MoviePlaying(hmovie) CloseMovie(hmovie) hmovie = OpenMovie(movie$) frame = 0 Else SetBuffer TextureBuffer(movietex) DrawMovie(hmovie) frame = frame + 1 : Color 255,255,255 : Text 0,0,"Frame "+frame SetBuffer BackBuffer() EndIf TurnEntity cube,0,.4,0 UpdateWorld() : RenderWorld() Text 0,0,"AvailVidMem() "+AvailVidMem() Flip() Wend End |
| ||
Maybe you could use ScaleTexture movietex, texturewidth(movietex) / w, textureheight(movietex) / h ? |
| ||
Doh! Why does it seem so obvious in hindsight? Thanks Warner, except it needs to use floats: ScaleTexture movietex, Float(TextureWidth(movietex))/ Float(w), Float(TextureHeight(movietex)) / Float(h) Final code solution (I hope): |
| ||
Using a square texture, but 'drawing' the movie always sso that it's centred (or whatever really) works fine in all situations I've tested. Although the ScaleTexture also works, I am concerned, that some drivers still might not like it. |
| ||
here´s a quick sample using eps´ bvid lib... (also plays divx, xvid,...)Include "bvid.bb" Graphics3D 1024,768,0,2 movie$ = "sample.avi" file = WriteFile( "bvid.avs" ) WriteLine( file, "AVISource(" + Chr$(34) + movie$ + Chr$(34) + ")" ) CloseFile file movie$ = "bvid.avs" camera=CreateCamera() CameraClsColor camera,128,128,128 PositionEntity camera,0,0,-5 cube = CreateCube() ScaleEntity cube,1.5,1.5,1.5 tex=CreateTexture(512,512,1) ScaleTexture tex,1.3,1.3 EntityTexture cube,tex bvid_Init() image = bvid_Open( movie$ ) MidHandle image bvid_Play(image) Repeat TurnEntity cube,0,MouseXSpeed()/5,0 UpdateWorld RenderWorld SetBuffer TextureBuffer(tex) bvid_Refresh(image) DrawBlock image, 256/1.3,256/1.3 SetBuffer BackBuffer() Delay 10 Flip Until KeyHit(1) Or bvid_GetCloseEvent() DeleteFile( "bvid.avs" ) bvid_Exit() End lib: http://www.east-power-soft.de/index.php?menu=blitzbasic_blitzbasic_codes_blitzvideo cheers, chi |
| ||
If this helps, CopyRect-ing from the Backbuffer to a texture isn't always slow. If you specify the 256 flag - store in vram - the copy is extremely fast. In fact on my computer it takes 1 millisec rather than 35 ms from the backbuffer to a texture not in vram. I found this out from jfk in a thread I created. Here's jfk's code as an example: |
| ||
Yeah, I think the 256 flag was never relally mtaken advantage of in B3D's infancy (or at whatever point it got added), since in in those days, graphics cards of the likes of 32Mbit RAM were pretty much unheard of. With most cards over 128M nowadays, (albeit a lot more graphics info being stored in the card RAM), it's certainly worth taking advantage of. |
Code Archives Forum