Tutorials

Light functions, global time and rendering text

wSample name: SampleLighting
Script source code file: sample/lighting/main.lua

SampleLighting

The goal of this tutorial is to show you
  • how to manipulate lights in your scene
  • how to handle time
  • how to print a text on the screen
New functions in this tutorial

setLightDiffuseColor()
getLightDiffuseColor()
setLightRange()
getLightRange()
renderText()

The first thing you might notice is that there are two new additional variables that we’re going to use:
 local globalTime = 0;
 local lightRadius = 7;

In this, and also in further tutorials, we will just cover the new functions and variables. So, if there is anything you don’t understand, have a look at Tutorial 1.

init()

In the init() function we additionally store the id of the point light in the variable pointLightId.

 pointLightId = getChildAt(id, 2);

When you open the i3d file cubeWithPointLight.i3d, you can see that the light is in third position. Since the function getChildAt()starts counting from 0, the argument 2 points to the third child.

Set the light radius to an initial value of 7.

 setLightRange(pointLightId, lightRadius);

keyEvent()

Here are two more keys: Key 1 and Key 2. When they are pressed, the functions decreaseLightRadius and increaseLightRadius are called.

if sym == Input.KEY_1 and isDown == true then
 decreaseLightRadius();
end;

if sym == Input.KEY_2 and isDown == true then
 increaseLightRadius();
end;

increase- decreaseLightRadius()
These two functions change the variable lightRadius by 0.5 and then call the lightRadius function with the new value.

function increaseLightRadius()
 lightRadius = lightRadius + 0.5
 setLightRange(pointLightId,lightRadius);
end;

update(dt)

Two variables are new here:

Why do we need a globalTime here? Well, we want the light to rotate around the cube. Therefore, we need a value that constantly changes in corrrespondence with time. Of course you could also increase a number every frame, but since the framerate isn’t constant we also use the time which has passed since the last frame and thus get an exact and constantly growing number that isn’t affected by the different framerates. Remember that dt is the time passed between the last and the actual frame in milliseconds. So, if dt is multiplied by 0.001 you get seconds. We also need a distance to the center which is stored in the variable radius.

 globalTime = globalTime+dt*0.001;
 local radius = 2;

This function handles the translation of the pointLight using the globalTime and the radius 2.

 setTranslation(pointLightId, math.sin(globalTime)*radius, 3, math.cos(globalTime)*radius);

We also change the color of the diffuse color of the light. This is done with the setLightDiffuseColor() function. As arguments it uses the id, and then the three values for red, green and blue as floats between 0 and 1. As r we use the sinus of the globalTime.

 setLightDiffuseColor(pointLightId, math.sin(globalTime), 0.4, 0.2);

When you execute the program, you see that there is a white box where the point light is. This may seem a bit odd since you probably don’t want this cube to be visible at all. When you open the file cubeWithPointLight.i3d and click on the plus left of the light in the scene graph, you see that we have attached a little cube to the light. We have done this to to give you a better visual feedback on where the pointLight is. On top of that, it shows also another important thing: as a child it inherits the translations of the parent and thus also moves with it.

draw()

Like the update function, the draw function is executed after every frame.

First we store the rgb values of the pointLight using the getLightDiffuseColor() function. It returns three different values. So be careful, you need to separate the different variables by commas!

 local r, g, b = getLightDiffuseColor(pointLightId);

Then we use the function renderText() to render the result directly onto the screen.

renderText

Description
Render text to viewport
Definition
function renderText(float x, float y, float size, string str)
Arguments
floatxx position [0, 1]
floatyy position [0, 1]
floatsizefont size
stringstrstring to print
When using renderText you can also weld parts together with the .. operator to concatenate variables and strings like in the example.

 renderText(0,0.95,0.05,"r value: " .. r);
 renderText(0,0.90,0.05,"g value: " .. g);
 renderText(0,0.85,0.05,"b value: " .. b);

The next line stores the value of the getLightRange() function in the lightRadius variable

 local lightRadius = getLightRange(pointLightId);

and then the variable is rendered onto the screen:

 renderText(0,0.75,0.05,"LightRadius: " .. lightRadius);

With the last line we simply render the globalTime. Since it is a float we use math.floor to get an integer.

 renderText(0,0.65,0.05,"seconds: " .. math.floor(globalTime));