r2t - Sourcecode.

BlitzMax Forums/BlitzMax Programming/r2t - Sourcecode.

TartanTangerine (was Indiepath)(Posted 2006) [#1]
Author: Tim Fisher
License: Indiepath License for non warranted software
Summary: This software is free to use, you may distribute within a pre-compiled executable file only.

If you have a license question then ask, don't assume! If you don't have a copy of the license then get one.

format_codebox('Strict

Rem
bbdoc: Render 2 Texture Module
End Rem
Module Indiepath.Render2Texture

ModuleInfo "Version: 1.0"
ModuleInfo "Author: Tim Fisher"
ModuleInfo "License: Indiepath License for non warranted software"
ModuleInfo "Summary: This software is free to use, you may distribute within a pre-compiled executable file only."
ModuleInfo "Contact: If you have a license question then ask, don't assume! If you don't have a copy of the license then get one."
ModuleInfo "Modserver:Indiepath"
'EndRem


?win32
Import BRL.D3D7Max2D
?
Import BRL.GLMax2D
Import BRL.PNGLoader
Import BRL.Retro


Const DDERR_INVALIDSURFACETYPE = $88760250
Const DDERR_INVALIDPARAMS = $80070057
Const DDERR_INVALIDOBJECT = $88760082
Const DDERR_NOTFOUND = $887600ff
Const DDERR_SURFACELOST = $887601c2

Global tRenderERROR:String

Function tError:String(err:Int)

Select err
Case DDERR_INVALIDSURFACETYPE
Return "DDERR_INVALIDSURFACETYPE"

Case DDERR_INVALIDPARAMS
Return "DDERR_INVALIDPARAMS"

Case DDERR_INVALIDOBJECT
Return "DDERR_INVALIDOBJECT"

Case DDERR_NOTFOUND
Return "DDERR_NOTFOUND"

Case DDERR_SURFACELOST
Return "DDERR_SURFACELOST"

End Select
End Function

Type tRender

?Win32
Global DXFrame:TD3D7ImageFrame
?
Global GLFrame:TGLImageFrame
Global DX:Int
Global Image:TImage = CreateImage(1,1)
Global Width:Int
Global Height:Int
Global o_r,o_g,o_b
Rem
bbdoc: Initialise the Module
about:
The module must be initialised before use. This ensures usage of the correct render pipeline. If the render device is changed then you must
re initialise the module.
End Rem
Function Initialise()
?Win32
If _max2dDriver.ToString() = "DirectX7"
DX = True
' ViewPort = New D3DVIEWPORT7
Else
?
DX = False
' GlEnable(GL_TEXTURE_2D)
?Win32
EndIf
?
Print "tRender : Initialise OK"
Return True
End Function

'#################################################################################

Rem
bbdoc: Create Image with Render Characteristics
returns: TImage Handle to Object
about:
<table>
<tr><td><b>Width:Int</td><td>Width in Pixels of Image, try to follow the normal rules of textures</td></tr>
<tr><td><b>Height:Int</td><td>Height in Pixels of Image</td></tr>
<tr><td><b>Flags:Int</td><td>Normal Image Flags</td></tr>
</table>
End Rem
Function Create:TImage(Width:Int,Height:Int,Flags:Int=FILTEREDIMAGE)

Local t:TImage=New TImage
t.width=width
t.height=height
t.flags=flags
t.mask_r= 0
t.mask_g= 0
t.mask_b= 0
t.pixmaps=New TPixmap[1]
t.frames=New TImageFrame[1]
t.seqs=New Int[1]
t.pixmaps[0]= t.Lock(0,True,False)
t.seqs[0]=GraphicsSeq

' MaskPixmap( t.pixmaps[0],mask_r,mask_g,mask_b )
?Win32
If DX
t.frames[0] = CreateFrame(TD3D7Max2DDriver(_max2dDriver),t.Width,t.Height,t.flags)
Else
?
t.frames[0] = TGLImageFrame.CreateFromPixmap:TGLImageFrame( t.pixmaps[0],t.flags )
?Win32
EndIf
?

Print "tRender : Create OK"


Return t

End Function

'#################################################################################
?Win32
Function CreateFrame:TD3D7ImageFrame( driver:TD3D7Max2DDriver,width,height,flags )
Function Pow2Size( n )
Local t=1
While t<n
t:*2
Wend
Return t
End Function

Local swidth=Pow2Size(width)
Local sheight=Pow2Size(height)
Local desc:DDSURFACEDESC2=New DDSURFACEDESC2
Local res

desc.dwSize=SizeOf(desc)
desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT
desc.dwWidth=swidth
desc.dwHeight=sheight
desc.ddsCaps=DDSCAPS_TEXTURE|DDSCAPS_3DDEVICE|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM ' **************************************************
desc.ddsCaps2=DDSCAPS2_HINTDYNAMIC'|DDSCAPS2_TEXTUREMANAGE
desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT)
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


Local surf:IDirectDrawSurface7
If flags & MIPMAPPEDIMAGE desc.ddsCaps:|DDSCAPS_MIPMAP|DDSCAPS_COMPLEX
res=PrimaryDevice.DDraw.CreateSurface( desc,Varptr surf,Null )
If res<>DD_OK
tRenderERROR = tError(res)
Print "tRender : CreateFrame ERROR : "+tRenderERROR
Return Null
EndIf
'RuntimeError "Create DX7 surface Failed"

Local frame:TD3D7ImageFrame=New TD3D7ImageFrame
frame.driver=driver
frame.surface=surf
frame.sinfo=New DDSurfaceDesc2
frame.sinfo.dwSize=SizeOf(frame.sinfo)
frame.xyzuv=New Float[24]
frame.width=width
frame.height=height
frame.flags=flags
frame.SetUV 0.0,0.0,Float(width)/swidth,Float(height)/sheight


'frame.BuildMipMaps()
Print "tRender : CreateFrame OK"
Return frame
End Function
?

'#################################################################################
Rem
bbdoc: Set Screen Viewport
about:
<table>
<tr><td><b>X:Int</td><td>Set the X Position of the Viewport</td></tr>
<tr><td><b>Y:Int</td><td>Set the Y Position of the Viewport</td></tr>
<tr><td><b>Width:Int</td><td>Set the Viewport Width in Pixels</td></tr>
<tr><td><b>Height:Int</td><td>Set the Viewport Height in Pixels</td></tr>
<tr><td><b>FlipY:Byte</td><td>Flip the Viewport on the Y Axis, OpenGL only. Automatically done by the Texture Renderer.</td></tr>
</table>
End Rem
Function ViewportSet(X:Int=0,Y:Int=0,Width:Int=640,Height:Int=480,FlipY:Byte=False)
?Win32
If DX
TD3D7Max2DDriver(_max2dDriver).viewport.dwX=x
TD3D7Max2DDriver(_max2dDriver).viewport.dwY=y
TD3D7Max2DDriver(_max2dDriver).viewport.dwWidth=width
TD3D7Max2DDriver(_max2dDriver).viewport.dwHeight=height
PrimaryDevice.device.SetViewport(TD3D7Max2DDriver(_max2dDriver).viewport)
Else
?
If FlipY
glViewport(X, Y, Width, Height)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
gluOrtho2D(X, GraphicsWidth(), GraphicsHeight(),Y)
glScalef(1, -1, 1)
glTranslatef(0, -GraphicsHeight(), 0)
glMatrixMode(GL_MODELVIEW)
Else
glViewport(X, Y, Width, Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(X, GraphicsWidth(), GraphicsHeight(), Y, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
EndIf
?Win32
EndIf
?
' Print "tRender : ViewportSet OK"
Return True
EndFunction

'#################################################################################
Rem
bbdoc: Begin the Texture Render Process
about:
<table>
<tr><td><b>Image:TImage</td><td>The Image to Render to, as created with "Create" command.</td></tr>
<tr><td><b>Viewport:Byte</td><td>True (default) to Automatically resize the viewport to the image size</td></tr>
</table>
End Rem
Function TextureRender_Begin(Image1:TImage,Viewport:Byte=True)
Image = Image1
If Viewport Then
Width = image1.width
Height = image1.height
If DX
ViewportSet(0,0,Width,Height)
Else
ViewportSet(0,0,Width,Height,True)
EndIf
Else
Width = GraphicsWidth()
Height = GraphicsHeight()
EndIf

?Win32
If DX
Local DXFrame:TD3D7ImageFrame = TD3D7ImageFrame (image1.frame(0))
PrimaryDevice.Device.SetRenderTarget( DXFrame.Surface,0)
PrimaryDevice.Device.BeginScene()
Else
?
GLFrame:TGLImageFrame = TGLImageFrame(Image1.frame(0))
' ViewportSet(0,0,Width,Height,True)
?Win32
EndIf
?
' Print "tRender : TextureRender_Begin OK"
Return True
End Function

'#################################################################################
Rem
bbdoc: Clear the Current Viewport with color
about:
<table>
<tr><td><b>col:Int</td><td>The Color to clear the Viewport with includes Alpha AARRGGBB format.</td></tr>
</table>
End Rem
Function Cls(col:Int=$FF000000)
?Win32
If dx
PrimaryDevice.device.Clear 1,Null,D3DCLEAR_TARGET,col,0,0
Else
?
Local Red# = (col Shr 16) & $FF
Local Green# = (col Shr 8) & $FF
Local Blue# = col & $FF
Local Alpha# = (col Shr 24) & $FF
' DebugLog Alpha
glClearColor red/255.0,green/255.0,blue/255.0,alpha/255.0
glClear GL_COLOR_BUFFER_BIT
?Win32
EndIf
?
End Function

'#################################################################################
Rem
bbdoc: Setup GreyScale Rendering
about:
<table>
<tr><td><b>state:Byte</td><td>True = Turn GreyScale on, False = Turn it Off</td></tr>
<tr><td><b>dwFactor:Int</td><td>Texture Coloring Factor</td></tr>
<tr><td><b>SourceCol:Int</td><td>Color Source to be used to calculate GreyScale</td></tr>
</table>
End Rem
?win32
Function SetMono(state:Byte=True,dwFactor:Int = $0036B612,SourceCol:Int=$FF0000)
If State
GetColor (o_r,o_g,o_b)
SetColor((SourceCol Shr 16) & $FF,(SourceCol Shr 8) & $FF,SourceCol & $FF)
PrimaryDevice.device.SetRenderState(D3DRS_TEXTUREFACTOR, dwFactor)
' PrimaryDevice.device.SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3)
' PrimaryDevice.device.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE)
' PrimaryDevice.device.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR)

PrimaryDevice.device.SetTextureStageState(1, D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3)
PrimaryDevice.device.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE)
PrimaryDevice.device.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR)
Else
PrimaryDevice.device.SetRenderState(D3DRS_TEXTUREFACTOR, $FFFFFFFF )
' PrimaryDevice.device.SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE)
' PrimaryDevice.device.SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE)
' PrimaryDevice.device.SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE)

PrimaryDevice.device.SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE)
PrimaryDevice.device.SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE)
PrimaryDevice.device.SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_DIFFUSE)
SetColor o_r,o_g,o_b
EndIf
End Function
?win32
'#################################################################################
?win32
Function SetMipMap(Image:TImage,Level:Int)

Local DXFrame:TD3D7ImageFrame = TD3D7ImageFrame (image.frame(0))

'DXFrame.BuildMipMaps()

Local src:IDirectDrawSurface7
Local dest:IDirectDrawSurface7
Local caps2:DDSCAPS2
caps2=New DDSCAPS2
caps2.dwCaps=DDSCAPS_TEXTURE|DDSCAPS_MIPMAP'|DDSCAPS_3DDEVICE
caps2.dwCaps2= DDSCAPS2_MIPMAPSUBLEVEL

src = DXFrame.Surface

Local res = src.GetAttachedSurface(caps2,Varptr dest)

If res<>DD_OK
tRenderERROR = tError(res)
Return False
EndIf

DXFrame.Surface = dest
dest.Release_

Print "MipMap Selected OK"
Return True

End Function
?
'#################################################################################
Rem
bbdoc: End the Texture Render Process
about:
This Must be called when you have finished rendering to the Texture
End Rem
Function TextureRender_End()
?Win32
If dx
PrimaryDevice.Device.EndScene()
Else
?
glBindTexture GL_TEXTURE_2D,GLFrame.name
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, Width, Height, 0)
glBindTexture GL_TEXTURE_2D,0
?Win32
EndIf
?
ViewportSet(0,0,GraphicsWidth(),GraphicsHeight())
DrawImageRect Image,-2000,-2000,1,1
' Print "tRender : TextureRender_End OK"
Return True
End Function

'#################################################################################
Rem
bbdoc: Begin the Normal BackBuffer Rendering Process
End Rem
Function BackBufferRender_Begin()
?Win32
If DX Then
PrimaryDevice.Device.SetRenderTarget PrimaryDevice.backbuffer,0
Else
?
' If GLFrame <> Null Then glBindTexture GL_TEXTURE_2D,GLFrame.name
?Win32
EndIf
?
ViewportSet(0,0,GraphicsWidth(),GraphicsHeight())
' Print "tRender : BackBufferRender_Begin OK"
Return True
End Function

'#################################################################################
Rem
bbdoc: End the Normal BackBuffer Rendering process
about:
This Must be called when you have finished rendering to the BackBuffer and Before the Flip Command.
End Rem
Function BackBufferRender_End()
?Win32
If DX
PrimaryDevice.Device.EndScene()
Else
?
glBindTexture GL_TEXTURE_2D,0
?Win32
EndIf
?
' Print "tRender : BackBufferRender_End OK"
Return True
End Function

'#################################################################################


End Type')


N(Posted 2006) [#2]
Well, first question about the license.. where is it?


Dreamora(Posted 2006) [#3]
I have it (from precompiled 1.18 version) ... its the "default" non-waranty license should should be able to find on license page.

ie: the code is licensed to you but still owned by Tim, no waranty in case of damage etc ... Most likely the same as any application either has as license or as some explicit EULA paragraphs.


tonyg(Posted 2006) [#4]
Thanks for the code Tim. Much appreciated as always.


tonyg(Posted 2006) [#5]
Hi Tim,
This doesn't look right...
format_code('
Strict

Import Indiepath.Render2Texture

HideMouse()
'SetGraphicsDriver GLMax2DDriver()
Graphics 512,512

tRender.Initialise()

Local myImage:TImage = tRender.Create(256,256)
Local image:TImage=LoadImage("max.png")
Delay (500)
' Do Normal Render to Backbuffer

Local ms=MilliSecs()

tRender.BackBufferRender_Begin()
Cls
DrawImage image , 0 , 0
SetColor 255,0,0
DrawRect 100 , 100 , 100 , 100
SetColor 255,255,255
tRender.BackBufferRender_End()

Flip 0

Print MilliSecs()-ms

WaitKey()
Cls

' Do Render To Texture Then draw Textured image on screen

ms=MilliSecs()

tRender.TextureRender_Begin(myImage)
Cls
DrawImage image , 0 , 0
SetColor 255,0,0
DrawRect 100 , 100 , 100 , 100
SetColor 255,255,255
tRender.TextureRender_End()

SetColor 255,255,255

tRender.BackBufferRender_Begin()
Cls
DrawImage myImage,20,0
tRender.BackBufferRender_End()

Flip 0

Print MilliSecs()-ms

WaitKey()
')
The render-to-texture image size is reduced.


Space_guy(Posted 2006) [#6]
Thats great news. now i have the source to all modules i use :)


TartanTangerine (was Indiepath)(Posted 2006) [#7]
TextureRender_Begin has a viewport flag. As a default the viewport is always resized to the size of the render texture. This is a true viewport and as such will re-scale all the GFX to fit within the image bounds.


tonyg(Posted 2006) [#8]
OK, tried it and it works. Thanks


BlackSp1der(Posted 2006) [#9]
Hi, anyone know how to fix it?
I can't clean the texture before draw in it (in real size).

edit: solved, using rects instead whole buffer (null).

format_code('
Strict

Import Indiepath.Render2Texture

SetGraphicsDriver D3D7Max2DDriver()
Graphics 640,480,0
SetBlend(ALPHABLEND)
tRender.Initialise()

Local image:TImage=LoadImage("bmax160_2.png")
MidHandleImage(image)

Local myImage1:TImage = tRender.Create(256,256)
Local myImage2:TImage = tRender.Create(256,256)

Local rot:Int,x:Int,y:Int

Repeat
rot:+1
If rot>10 Then rot=0; x=Rand(100,400); y=Rand(100,400)


tRender.TextureRender_Begin(myImage1,0) 'fit to the screen size
tRender.Cls($90FF0000)
DrawImage image,x,y
tRender.TextureRender_End()

tRender.TextureRender_Begin(myImage2,1) 'fit to the image size
tRender.Cls($900000FF)
DrawImage image,x,y
tRender.TextureRender_End()


tRender.BackBufferRender_Begin()
tRender.Cls($FF000000)
SetScale 10,10
DrawText "********",0,0
DrawText "********",0,130
SetScale 1,1
DrawImage myImage1,0,0
DrawImage myImage2,320,0
tRender.BackBufferRender_End()

Flip

Until KeyHit(KEY_ESCAPE)
')


Tyler(Posted 2006) [#10]
K, I've got problems on when I try to use this on a canvas. I get an unhandled memory exception error when I try to switch to a different graphics canvas in my windowed program. So I SetGraphics CanvasGraphics(), then tRender.Initialise, then do my drawing to an image, and when I'm done, display it on one canvas, then switch canvas to update another image (which isn't using the render2texture capabilities) and right when it tries to SetGraphics again ... error. Please help! Thanks.


Dreamora(Posted 2006) [#11]
That does not work.
The initialisation is special, the image are no BM images and can not be transfered. They are lost if the context is shut down.

You would need to copy the render texture content to a regular image if you want to use it on a different canvas.


Tyler(Posted 2006) [#12]
Ok, thanks for the info! I may have a better way of doing it, but only time (and my lack of skill) will tell :D Thank again.


Armitage 1982(Posted 2010) [#13]
I can only agree with that since using Grabimage doesn't work in some situations (while the game is minimized or Alt-tabbed, grabimage isn't mask friendly too).

I didn't found anything working yet with the max2D driver :(