PDA

View Full Version : Tutorial CanvasCaptureActor (To BSP and Terrain)



creasso
07-13-2011, 04:37 PM
OK, since I got that MIC trouble wrote an object to get a ScriptedTexture and draw it to a RenderTarget, this way I can override material textures used on BSP and Terrains if needed.

If you were looking for a way to swap textures in real time this class can also help you since you can use the DRAWTILE from the Canvas to override whatever content you have on your rendertarget. Use this object or study it to put such functionality to others.

I recommend you to read the scriptedtextures and canvas docs since you’ll use then a lot with this object or until they can help you to avoid this hack.


Here is the code:

/*
* ---------------------------- CANVAS CAPTURE ACTOR V 0.1 -------------------------------
*
* Object created to allow UDK users to write to a render target using a scripted texture
*
* NOTES:
* a) IF EPIC GIVE US THE POSSIBILITY TO CREATE SCRIPTEDTEXTURES RIGHT FROM THE EDITOR
* DON'T FORGET TO DELETE THESE GUYS AND RECONFIGURE YOUR MATERIALINSTANCES SINCE THIS
* OBJECT USES AT LEAST TWICE RENDERTARGET MEMORY!
*
* b) CLASS PROVIDED "AS IS", MODIFY, OR IMPROVE IT TO FIT YOUR NEEDS. IMPLEMENTATION AND
* USAGE INSTRUCTIONS ON THE "CANVAS CAPTURE ACTOR THREAD".
*
* c) MOVIE AND DUMMY TEXTURE ALSO PROVIDED, IF YOU DON'T WANT MESS WITH INSTANCE NAMES USE
* THEN, DID A EFFORT TO WORK WITH ALL RENDERTARGET SIZES, BUT MY TARGET WAS THE
* 512 ONES.
*
* d) CREASSO'S GIFT TO ALL YOU, SO ENJOY! ;)
*
* --------------------------------------------------------------------------------------*/
class CanvasCaptureActor extends Actor
placeable;

var(CaptureConfig)SwfMovie LinkerSWF; // The SWF on your package
var(CaptureConfig)TextureRenderTarget2D Output_RT; // The RenderTarget that is feeding your MaterialInstance on your package
var(CaptureConfig)bool bPersistBetweenRenders; // If you want keep what you draw not
var(DebugConfig)bool bShowLogDebug; // Debug messages to log window
var(DebugConfig)bool bShowTestMessage; // Writes a test message on the texture
var(DebugConfig)float TestMessageScale; // Font scale to the test message
var(DebugConfig)string YourTestMessage; // Your test message
var ScriptedTexture Internal_RT; // The writable render target
var GFxMoviePlayer LinkerMovie; // The GFX movie that is doing our connection

simulated function PostBeginPlay()
{
local GFxObject HolderWidget;
super.PostBeginPlay();

LinkerMovie = new class'GFXMoviePlayer'; // Creates our linker movie
LinkerMovie.SetMovieInfo(LinkerSWF); // Defines the swf used
LinkerMovie.RenderTexture = Output_RT; // Defines where the movie will bw drawn
LinkerMovie.Start(); // Begin to play
LinkerMovie.Advance(0); // First advance to allow movie interaction

HolderWidget = LinkerMovie.GetVariableObject("_root.ImageHolder"); // Tries to find our imageholder submovie
if(HolderWidget != none)
{
// Tries scale our image to fit render target size
HolderWidget.SetFloat("_height", Output_RT.SizeY);
HolderWidget.SetFloat("_width", Output_RT.SizeX);
}
else
if(bShowLogDebug)
`log("Holder submovie not found, check what's wrong!");

// Creates our canvas renderer
Internal_RT = ScriptedTexture(class'ScriptedTexture'.static.Crea te(Output_RT.SizeX, Output_RT.SizeY,, MakeLinearColor(0,0,0,1)));

// Assign the Render delegate function
Internal_RT.Render = FlushToRenderTarget;

// Replaces our dummy texture by our dynamic one
LinkerMovie.SetExternalTexture("DYNATEX",Internal_RT);
}

// Canvas drawing routine
function FlushToRenderTarget(Canvas ParentCanvas)
{
// Sets our drawing origin
ParentCanvas.SetOrigin(0,0);
// Sets our clip area
ParentCanvas.SetClip(Internal_RT.SizeX, Internal_RT.SizeY);

// Our test message
if(bShowTestMessage)
{
ParentCanvas.DrawColor = MakeColor(255,255,255,255);
ParentCanvas.SetPos((Internal_RT.SizeX / 2) - 50, (Internal_RT.SizeY / 2) - 50);
ParentCanvas.DrawText(YourTestMessage,false,TestMe ssageScale,TestMessageScale,);
Internal_RT.bNeedsUpdate = true;
}

// Your custom drawing goes on this space...

// ends here, don't forget to call "DynamicBleedTexture.bNeedsUpdate = true" after drawing

Internal_RT.bSkipNextClear = bPersistBetweenRenders; // Our persistency
}

DefaultProperties
{
TestMessageScale=3.0f
YourTestMessage="OK, IT'S WORKING!" // Default test message
// Sprite to display in editor to help you to find then
Begin Object Class=SpriteComponent Name=Sprite
Sprite=Texture2D'EditorResources.S_DecalActorIcon'
Scale=0.15
HiddenGame=True
AlwaysLoadOnClient=False
AlwaysLoadOnServer=False
End Object
Components.Add(Sprite)
}

Here is the link to a swf that works with it:

Movie Download (http://www.4shared.com/file/F32Ycrug/CanvasActorMovie.html)

Here is the implementation:

http://i156.photobucket.com/albums/t22/creasso/UDK/1-PlacingTheSwf.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/2-PlacingTheScript.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/3-RecompileTheScript.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/4-ImportingRequiredSWF.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/5-RenderTargetCreation.jpg

6 – You’ll need a material or materialinstance with a TextureSamplerParameter2D filled with your rendertarget.

http://i156.photobucket.com/albums/t22/creasso/UDK/7-BSPAPPLY.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/8-PlaceTheActor.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/9-ConfigureYourActor.jpg

http://i156.photobucket.com/albums/t22/creasso/UDK/10-TheEnd.jpg

Well, it’s this! Hope that Epic find some way to let us create scriptedtextures inside packages on the editor on next builds to save some rendertarget memory… LOL

Best wishes!


creasso