Code archives/3D Graphics - Misc/3d movie playback

This code has been declared by its author to be Public Domain code.

Download source code

3d movie playback by John Blackledge2007
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

Doggie2008
doesn't work


_332008
doesn't work either :(


Panno2009
its driver dependig .
some driver work with some not .
with nvidia it works for my with all cards i tested


b322009
Try drawing the movie to the backbuffer and copying it onto the texture using CopyRect. It might be more compatible.


Panno2009
but slow ;)


Knight #512009
I think the reason the movie is not drawing is because you are calling the DrawMovie function before the Updateworld and Renderworld commands.


N2009
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.


John Blackledge2009
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



Warner2009
Maybe you could use ScaleTexture movietex, texturewidth(movietex) / w, textureheight(movietex) / h ?


John Blackledge2009
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):



_PJ_2010
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.


chi2010
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


Serpent2010
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:



_PJ_2010
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