In this article, we'll examine ScriptENGINE Render Targets and Dynamic Textures.
Dynamic textures are modifiable images applied to 3D entity surfaces. We can manipulate the texture in real-time using the IGraphics interface to modify the 3D entity look and feel.
Render targets allow different views of the 3D world to be drawn simultanenously, from different cameras, into dynamic textures. The results can then be applied to 3D entities to produce some pretty cool effects.
View the Demo Code
The demos are included in the ScriptENGINE SDK. Now's a great time to get the ScriptENGINE SDK from our website (including the SciTE code editor, Programmer's Reference and ScriptENGINE Demos).
Navigate to the ScriptENGINE SDK/[Dynamic Textures] Render targets and texture editing folder for the example.
Open the world.e76script in the SciTE code editor. We will be referring to the world.e76script for the rest of this article.
The ScriptENGINE Demo Framework
The ScriptENGINE Demos are run using the runDemo.e76script framework code in the ScriptENGINE SDK/Demos folder.
Loading the 3D Entity Ids
The ScriptENGINE 3D World Editor, included with the SDK, creates a worldIds.e76script when saving your world. The worldIds.e76script maps entity names defined in the editor (eg. Light1) with their unique identifiers used by the ScriptENGINE (eg. idLight_Light1 = '1591e233-ae39-4937-8b14-527187bb8af2'). These IDs are globally unique. No two are ever the same.
Load the worldIds.e76script into the ScriptENGINE:
IApp:loadScript(IWorld:getNameLong() .. '/worldIds');
Initialisation Code: The OnWorldLoad() function
The runDemo.e76script framework calls the OnWorldLoad() function after it loads the 3D World. This gives the demo a chance to perform any specific initialisation.
Loading ScriptENGINE constants:
IApp:loadScript(IApp:getExeFilePath() .. './Constants/constantsMaterialTypes');
ScriptENGINE constants help make our code more readable. So we'll be able to use the pre-defined constants (eg. MAT_TRANSPARENT_ALPHA_CHANNEL) in our scripts instead of magic-numbers (eg. 13). This avoids scripts being littered with numbers and strings that are difficult to interpret later on.
The constantsxxx.e76script files are included with the ScriptENGINE Runtime distribution and automatically installed with the ScriptENGINE Runtime.
Load the GUI for this example:
IGraphics:loadGui('help');
The GUI was created with the ScriptENGINE SDK Editor, and saved as help.e76gui.
Create a periodic tick subscriber:
IEvents:subscribeTickPeriodic('OnRotateCube', 100).
The function returns the new subscriber's identifier that's used with IEvents:unsubscribe() later on. The subscribe function takes a parameter defining your callback function name (OnRotateCube) to call when the event is fired, and the time period between each periodic tick (100). This function must be defined in your script.
Callback function signatures can be found in the ScriptENGINE Programmer's Reference and are also included in the SciTE code editor supplied with the SDK.
Create a GUI subscriber:
IEvents:subscribeGui('OnGui').
Set the initial animation for the 3D Agent:
IGraphics:setEntityAnimation(idAgent_Chastity, nil, true, 10).
Cleanup Code: The OnWorldUnload() function
The runDemo.e76script framework calls the OnWorldUnload() function before it unloads the 3D World. This gives the demo a chance to perform any specific cleanup.
The GUI Subscriber: Handling GUI events
Process GUI events like user button clicks:
function OnGui(callerId, eventType, userData)
The actual GUI controls for this example were originally created with the ScriptENGINE SDK Editor, and saved to *.e76gui files. Each GUI definition is loaded into the ScriptENGINE using the IGraphics:loadGui() function and can be saved using the IGraphics:saveGui() function.
When a GUI event occurs, your GUI callback function is passed parameters to inform you what event occurred (eventType) and what GUI control initiated the event (callerId).
We check these parameters using the IGraphics event utility functions to determine what event just occurred and respond as required.
In response to the combobox selection being changed, we call the doRenderTarget(), doSetPixels() or doWriteData() functions.
The Periodic Tick Subscriber: Handling Tick events
Process tick events and rotate the cube from the script code:
function OnRotateCube(currentTime, lastTime, isWindowActive, userData)
Setting up a Render Target
The doRenderTarget() function is called by the GUI event subscriber to setup a render target that will be applied to the 3D cube.
First check that render targets are supported by the graphics card. Some old graphics cards cannot, so it's necessary to check this before continuing.
If the graphics card supports render targets, the next step is to create a render target in the ScriptENGINE using:
IGraphics:createRenderTarget('#render1', '64 64', idCamera_renderFrom)
- #render1 is the new render target texturename
- '64 64' is the texture dimensions in pixels
- idCamera_renderFrom is the 3D world's camera used to generate the render target view
Then apply the render target texture to the 3D cube and modify the material type to MAT_SOLID. The 3D cube will display this texture on the next graphics frame refresh.
Manually modifying texture pixels
The doSetPixels() and doWriteData() functions both manipulate textures dynamically, but in slightly different ways. The doSetPixels() function illustates how to modify individual pixels, while the doWriteData() illustrates how to modify a block of pixels.
Locking dynamic textures
Before you can modify a texture, you first must lock it using IGraphics:textureLock(). This function returns the dynamic texture identifier for use with functions like IGraphics:textureSetPixel() and IGraphics:textureUnlock().
Use the IGraphics:textureSetPixel() function to modify an individual pixel in the texture.
Use the IGraphics:textureWriteData() function to modify a block of pixels in the texture.
The ScriptENGINE Programmer's Reference
We recommend reading about the IGraphics Interface in the Programmer's Reference which includes more information on dynamic textures and render targets.
| < Prev | Next > |
|---|