This is really getting annoying. I want to render to an image a la imagebuffer. I've got it working... kind of. There's a lot of problems but, as it stands, the resulting image is tiny. I did read once that this would happen (some DX7 tutorial) but it didn't say how to resolve it. Uncomment everything in the mainloop as it works BUT you have to escape quickly to actuqally grab the image before it disappears... for some reason. Comment out the drawoval (notice it's parms are 0,0,0,0) and the resulting image is even smaller. Any ideas?
Strict
Graphics 640,480
Local image1:TImage=LoadImage("man.png")
Local image2:TImage=LoadImage("body.png")
' Because Bmax users DX Texture Manager it is necessary to create a dummy rendertarget surface
' and then blit from that surface to the image surface.
'Global mysurf:IDirectDrawSurface7 ' The dummy surf to be used as the rendertarget.
'While Not KeyHit(KEY_ESCAPE)
Local mysurf:IDirectDrawSurface7=render2image_start(image1) ' set image1 as the destination image for the draw
DrawImage image2,0,0
DrawOval 0,0,0,0
render2image_stop(image1,,mysurf) ' stop rendering to the image and reset to the backbuffer
' Cls
' SetBlend maskblend
' SetAlpha 1.0
' DrawImage image1,0,0 ' draw the new image
' DrawText GCMemAlloced(),0,300
' Flip
'Wend
Cls
DrawImage image1 , 0 , 0
DrawText ImageWidth(image1) + " " + ImageHeight(image1),100,100
Flip
WaitKey()
Function render2image_start:IDirectDrawSurface7(image:TImage , frame:Int = 0)
' mysurf.release_()
Local mypix:TPixmap=LockImage(image) ' lock the image to obtain a pixmap.
Local mysurf:IDirectDrawSurface7=createsurffrompixmap(mypix) ' Create the rendertarget surface
Local res=PrimaryDevice.Device.SetRenderTarget(mysurf,0) ' set the new surface as the rendertarget.
If res<>DD_OK RuntimeError "D3D7Max2D Rendertarget failed" ' Check it worked OK.
Cls ' Clear the rendertarget
DrawImage image , 0 , 0 'need to copy the 'destination' image to the render surface.
Return mysurf
End Function
Function render2image_stop(image:TImage,frame=0,mysurf:IDirectDrawSurface7)
' Set the src and dest sizes to copy from/to. Thought I could leave these null but it produces horrid results.
' These parms could be used to copy a part of an image to another.
Local src[]=[0,0,ImageWidth(image),ImageHeight(image)]
Local dest[]=[0,0,ImageWidth(image),ImageHeight(image)]
dest[2]:+dest[0]
dest[3]:+dest[1]
' Do the blit from the dummy rendertarget to the image surface.
TD3D7ImageFrame(image.frame(frame)).surface.Blt dest,mysurf,src,0,Null
' Release the surface
mysurf.release_()
' reset rendering to the backbuffer
render2backbuffer()
End Function
Function render2backbuffer()
'set the rendertarget to the backbuffer
PrimaryDevice.Device.SetRenderTarget PrimaryDevice.backbuffer,0
End Function
Function createsurffrompixmap:IDirectDrawSurface7(temppix:TPixmap)
'lifted and butchered from Bmax source.
' I Don't use the POW2SIZE in this case.
Function Pow2Size( n )
Local t=1
While t<n
t:*2
Wend
Return t
End Function
Local surf:IDirectDrawSurface7 ' The dummy surface to return as the rendertarget
Local desc:DDSURFACEDESC2=New DDSURFACEDESC2 ' the 'description' of the surface
Local res ' Used to hold the return code of DX operations.
desc.dwSize=SizeOf(desc) ' size of the description
desc.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH 'Something to do with valid members?
desc.dwWidth=temppix.width ' Width of the surface = to the pixmap width
desc.dwHeight=temppix.height ' Same but for height.
desc.lPitch=temppix.pitch ' Think this is for pixmap memory location
desc.lpSurface=temppix.pixels ' and this
desc.ddsCaps=DDSCAPS_3DDEVICE|DDSCAPS_VIDEOMEMORY ' Surface can be rendered to and held in videomem.
desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT)
Select temppix.format
Case PF_BGR888
desc.ddpf_dwFlags=DDPF_RGB
desc.ddpf_BitCount=24
desc.ddpf_BitMask_0=$ff0000
desc.ddpf_BitMask_1=$00ff00
desc.ddpf_BitMask_2=$0000ff
Case PF_RGB888
desc.ddpf_dwFlags=DDPF_RGB
desc.ddpf_BitCount=24
desc.ddpf_BitMask_0=$0000ff
desc.ddpf_BitMask_1=$00ff00
desc.ddpf_BitMask_2=$ff0000
Case PF_BGRA8888
desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS
desc.ddpf_BitCount=32
desc.ddpf_BitMask_0=$ff0000
desc.ddpf_BitMask_1=$00ff00
desc.ddpf_BitMask_2=$0000ff
desc.ddpf_BitMask_3=$ff000000
Case PF_RGBA8888
desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS
desc.ddpf_BitCount=32
desc.ddpf_BitMask_0=$0000ff
desc.ddpf_BitMask_1=$00ff00
desc.ddpf_BitMask_2=$ff0000
desc.ddpf_BitMask_3=$ff000000
End Select
' Create the surface and return the result into RES
res=PrimaryDevice.DDraw.CreateSurface( desc,Varptr surf,Null )
If res<>DD_OK RuntimeError "D3D7Max2D Create System Surface Failed"
Return surf
End Function
|