Game Development Community

Tint a Static Sprite?

by Brian Doig · in Torque X 2D · 12/24/2006 (1:56 pm) · 21 replies

Is there a way to tinit a static sprite? I want to create a component that will tint a sprite red as the amount of damage the object takes increases. I can't seem to find in the documentation how to access the 2d sprites graphics information. Could someone post a code snipit example? Or at least the name of the methods I would use to get to the data and the methods to tint the data.
Page «Previous 1 2
#1
01/05/2007 (11:53 am)
Bump :)
#2
01/05/2007 (12:13 pm)
Don't know how to do exactly what you are asking, but I would think you could use lighting for this. Have one light on and full blown blasting the sprite, then simply modify the color of the light as it takes more damage to a full blown red.

#3
01/07/2007 (11:25 am)
Yeah, this is definitely a material feature -- i.e., changing the tint of an object should involve changing a parameter on the material. Adding a light to the material is probably the most straightforward way to do it (see DefaultLight on DefaultEffect).
#4
01/07/2007 (3:53 pm)
I was looking on RenderMaterial object for something that would allow me to modify the material but I didn't see any method or properties that would allow me to change the paramaters of the material other than the name of the texture to map to. Am I looking at the wrong class?

With regards to the adding the light to the material, I posed the question at www.garagegames.com/mg/forums/result.thread.php?qt=56244 about how to do this using only code since I wanted to simply add a component to an object to do this.

What I want to do is have a component that will add the mount point and then mount the light to the object and then vary the color of the light based on the damage the object has taken. I saw plenty of instructions on how to create XML based light sources in the TorqueX Lighting System Guide.html, but not so much on how to create one strictly by code. Can I just add a DirectionalLightInfoComponent to the object and then modify it's values on the fly?
#5
01/07/2007 (3:55 pm)
Why don't you create the light itself inside TGBX and then modify it's attributes from within code? Why do you want to do it all from code?

#6
01/07/2007 (4:17 pm)
Well, partially because I hadn't noticed that there was an icon to create a light object in TGBX. The reason I wanted to do it with code, is that I wanted to create a component that you could add directly to an object that would do all the work of creating the mount point for the light and mounting the light to the mount point along with controling the light. It occurs to me now that I could just provide the light object in a dropdown to my component as well so that works out easier.

The other reason I would like to do it programatically, is simply to learn how the pieces hook together. For example, if I wanted to add a light to the TorqueCombat project, I couldn't use the TGBX editor because there is no TGBX project for it since it's an example of how to create a project using only code.
#7
01/07/2007 (5:06 pm)
I went into TGBX and tried to create a light object. The only dropdown it had was entitled "Light Object" and it didn't have a "Scene Object" or a "Scripting" box. It also didn't have any buttons on top of it when it was selected that would allow you to mount it to other objects or the like. Without a scripting box, I don't know how you would get the object back since it doesn't seem like you could 'name' the light source so that you could find it later in code. I think this may be because a LightObject inherits directly from GarageGames.Torque.Core.TorqueObject rather than from GarageGames.Torque.T2D.T2DSceneObject like the other visible objects implemented by TGBX. It sounds like there may need to be a GarageGames.Torque.T2D.T2DLightObject since LightObject does not support the Mount method you would need to mount it to the ship.
#8
01/07/2007 (5:54 pm)
I also went into the sprite in TGBX and tried enabling the boxs "Enable Lighting" and "Enable Default Lighting" and set both the color and ambient for the default light to red but it didn't seem to change how the sprite looked when I ran the project. I even tried creating a new static sprite and setting the lighting on it and then switching the player sprite to be the new static sprite.

I was thinking that if I could get this default lighting to work, I might be able to change it on the fly for the object but it didn't seem to do anything when I enabled it.
#9
01/07/2007 (6:21 pm)
Have a look at tankbuster template, it uses two light sources and the bombs change color based on those light sources. Remember, you gotta change the size of the light source to cover the area with the object that you 'enable lighting' on or the light wont hit it (i think there's a setting to cover the whole scene, but i can't remember off the top of my head)

#10
01/07/2007 (6:52 pm)
This is just one way to do it. I'm gonna keep it short and sweet cause I've got a tight schedule.

Ok, first you'll need this assembly reference wherever you're modifying the color of a material:
using GarageGames.Torque.Materials.DXEffects;

That will give you the DefaultEffect class, which is most likely what all your materials are, unless you're doing something fancy (in which case this is probably not helpful anyway). Now you can access the DefaultLight properties directly from code. You'll need to make sure EnableDefaultLighting is true for the changes to take effect (which you can do easily from code). None of the other fields matter for this to work, including EnableLighting.

Here's an example of a completely red object:
// turn _animatedSprite's current material red!
            DefaultEffect material = _animatedSprite.Material as DefaultEffect;
            material.EnableDefaultLighting = true;
            material.DefaultLight.InternalColor = new Vector3(1.0f, 0.0f, 0.0f);
            material.DefaultLight.Ambient = new Vector3(0.0f, 0.0f, 0.0f);

Here's a completely white object:
material.DefaultLight.InternalColor = new Vector3(1.0f, 1.0f, 1.0f);
            material.DefaultLight.Ambient = new Vector3(0.0f, 0.0f, 0.0f);

Your redness factor is basically scaling the Y (green) and Z (blue) fields of the 'internal color' vector between 1 and 0 and keeping X (red) at 1.

Note that this affects the material itself, meaning it will affect everything using that material. If you want to affect a single object, you can just clone the material when the object is initialized and adjust the colors of the clone. If you are using multiple animations that you'll be swapping between I would reccomend cloning all the 'animation data's and giving them clones of their materials beforehand. When switching animations you'll want to set the color of the material of the animation data *before* you play that animation to avoid visible color differences. Oh, and you probably want to do a null check on the material as a default effect just in case. ;)

Let me know if this doesn't work for you for whatever reason.

Edit: Spelling, clarifications.
#11
01/07/2007 (7:06 pm)
Thanks! I'll take a look at it and see if it works for me. Sounds like what my original idea was though.

Just for clarification, what is the difference between InternalColor and Ambient? I didn't see that explained anywhere in the TorqueX API Help file for the DirectionalLightInfoComponent class (description is left blank)
#12
01/07/2007 (8:08 pm)
Quote:Just for clarification, what is the difference between InternalColor and Ambient?

Pff.. I don't know. ;)

[guess]
Honestly, it seems like they are exactly the same and just blended additively (I think it's additive). If I had to guess I would assume that there are two values for the sake of convinience. In other words, so you can modify the final color incrementally without losing it's original value (which I guess would explain why Ambient starts at 0.25 grey and Internal starts at black).
[/guess]

Because of the way the two blend you can get pretty intense colors out of it, though. Try setting them both full red and see what it looks like (only pure black doesn't turn red). If you shift ambient up you can get some neat washed out water-pastel-ish colors too.
#13
01/07/2007 (10:57 pm)
Oops.. by "Completely white object" above, I meant "Completely *lit* object". Sorry for any confusion. >_<
#14
01/08/2007 (10:28 am)
Hmmm, ok, I'll have to play with it once I get my components created and see how it works. I'll post my code in a seperate post once I get it working for others who want to modify the lighting on their objects.
#15
03/01/2007 (2:40 am)
@thomas - Could you explain what you mean by cloning the material to get different coloured sprites? I declare my sprites as:

ghost = (T2DSceneObject)(TorqueObjectDatabase.Instance.FindObject("WhiteGhost") as T2DStaticSprite).Clone();
TorqueObjectDatabase.Instance.Register(ghost);

and then applied the code you have above in my AIComponent to change the colour of the ghosts and that works great, except as you state above that all the ghosts change at once. Since the ghost is a clone and every ghost's preoperties seem to be unique in the AIComponent (position ,direction, etc) why do all the colours change at once?
#16
03/01/2007 (10:06 am)
You'll have to pull out the material, clone it, then assign the clone to be the material for the object.
#17
03/01/2007 (8:04 pm)
I tried this:

ghost = (T2DSceneObject)(TorqueObjectDatabase.Instance.FindObject("WhiteGhost") as T2DStaticSprite).Clone();
(ghost as T2DStaticSprite).Material = (RenderMaterial)(ghost as T2DStaticSprite).Material.Clone();
TorqueObjectDatabase.Instance.Register(ghost);

but it didn't make a difference. So I thought maybe I'm supposed to do it in the init of the Component

protected override bool _InitComponent(TorqueObject owner)
{
...
mGhostColour = (RenderMaterial)(_aighost.Material as RenderMaterial).Clone();
_aighost.Material = mGhostColour;
...
}

and again, no difference. Am I getting the location wrong? The syntax?

EDIT: After some reading, I suspect that the .clone() function is only making a shallow clone. If this is the case I guess my question becomes, how do I make a deep clone?
#18
03/13/2007 (10:27 pm)
@Ben - I just tried that also, and I'm getting the same behavior as Shiraz is reporting. He is dead on correct when he says that it doesn't seem as though Material is doing a deep copy when Clone is called.

I'm in the same dilema where I need to take a given T2DStaticSprite, clone it, and tint it differently for N objects. as it stands, when I tint it, all N objects change to the same colour. I am going to have to assume that the Clone operation for Material is not doing it's job (after all this is beta). Can someone correct me?
#19
03/14/2007 (9:49 am)
@LP - sorry to post this so late. In the beta if you wanted a light to shine on only one object you'd add it to the material that object was using. You are running into the short-comings of that process. In the soon to be released 1.0 version you add the light to the object itself. I think everything will work as you want at that point. In a future release, we may add a color value to sprites to make this type of thing easier, but the light solution works and doesn't create a new code path :).
#20
03/14/2007 (10:08 am)
That's great news Clark! That addresses all my concerns.

thanks!
Page «Previous 1 2