Showing posts with label texture. Show all posts
Showing posts with label texture. Show all posts

Friday, April 10, 2009

Testing some shading options

As I've been testing lately, you can purchase all the source code for this sample for $5
(http://store.payloadz.com/go?id=254377).

I’ve been testing some shading options and working on the 3D aspects of XNA that I have been needing to learn. One of the problems is that I have 3DStudioMax, but it is only on a machine I don’t use as much. I’ve been contemplating moving the license, but that has issues. I’ve used Blender in the past and have enough knowledge to be dangerous to myself, but went back to it as I have not been able to use Max when I need it. So, this was as much a Blender session as an XNA lighting session.

I’m using Reimer Grootjan’s book XNA 2.0 Game Programming Recipesand found it very helpful in the shading and rendering aspects. I know it’s for XNA 2.0 and I’m using XNA 3.0, but the stuff I’m looking at has not changed (as is most of the book) so it is still highly relevant to learning XNA 3.0.

The section I used was on directional lighting on page 514. It shows how to get the BasicEffect to work with a directional light.

My code looked like this when I was done.

effect.LightingEnabled = true;
effect.DirectionalLight0.Direction = light0Pos;
effect.DirectionalLight0.DiffuseColor = Color.White.ToVector3();
effect.DirectionalLight0.Enabled = true;
effect.PreferPerPixelLighting = false;
effect.DirectionalLight0.SpecularColor = Color.White.ToVector3();
effect.SpecularPower = specPower;
With, specPower and light0Pos set at the top of the class definition.


Vector3 light0Pos = new Vector3(-0.5f, -1.0f, 0.0f);
float specPower = 64;
After weeks of procrastination and thinking I was going to have to create a custom shader it was nice to find out that adding a directional light was very simple. One of the games I was going to do requires a spotlight and I do think that will require a custom shader so it's off the list until I get some extra time.

So, first up with Blender. I’m trying to display a gemstone. I created a isosphere then scaled and stretched it to look like a gem stone. Then I added a red texture. You can see that I set the Col (Color), Spe (Specular Color) and the Mir (Mirror Color) for the gem.


This was fine, except that the gem came out all smooth.


I know from experience that this is caused by the rendering system using vertex normals to draw the individual triangles of the gem as smoothly as possible. This is almost always the case. But for a gemstone, you want it to have facets. I spent a ton of time trying to figure out how to get blender to remove the vertex normals and only use surface normals.

This ended up being easy inside of blender, but took a while to figure out how to get this information into the direct X file. To do this in blender, you select the object in edit mode, then click the Set Smooth button to use vertex normals for rendering and Set Solid to use surface normals for rendering.


Easy and you can see the two rendered versions here.


That’s all well and good in Blender rendering, but XNA kept displaying the gem as a smooth surface. After tons of fiddling, I noticed one of the options on the Blender DirectX exporter was “no smooth”. The tool tip says exactly what I wanted to hear “Every vertex has the face normal, no smoothing”.



Once I exported with that setting everything worked.



Getting back to Blender, I found it really hard to learn, and hard to relearn, but for the price (Free) it really is an amazing tool. I have a book on it that I've barely touched called Introducing Character Animation with Blender by Tony Mullen. I've had it for a few years and only touched the surface on it and every time I pick it up I'm always impressed. It really does look like a great book. As I write this he has a new version due out soon and another book on Blender that was just released. See below.

My real problem with Blender came in the classes I was teaching on Torque last year and the fact that we could never get the bone systems to work properly. It seemed that 3DSMax was the only real way to do modeling for Torque. Maybe that has changed?

I did find this great reference image on the Blender hotkeys (http://en.wikibooks.org/wiki/File:BlenderHotkeysObjectMode.png. If you are going to use Blender, you are going to want to learn as many as possible. It really is a fast fast tool once you get to know the UI. Mostly I only use Space Bar, B (box select), A (select/deselect all), S (scale), R (rotate X,Y,Z).




As I've been testing lately, you can purchase all the source code for this sample for $5.
(http://store.payloadz.com/go?id=254377).

Friday, June 27, 2008

Second Life Script - Number Texture Display #2

Once I had a working number I had to place a few of them in sequence and allow a master prim to control them.



I had to first have a way for the root prim (the scoreboard) to send a message to the individual numbers telling them to update their display. I did this with a link message.


integer MSG_SET_NUM = 141; // arbitray message number
link_message(integer from, integer msg_id, string str, key id)
{
if (msg_id == MSG_SET_NUM)
{
curval = (integer)str;
llOwnerSay("setting num to "+(string)curval);
doOffset();
}
}


Then in the root prim I had to find the individual link numbers of the linked numbers. This is done like this. You first iterate through the list of links and find the ones named 1,10,100,1000 and save their link number. An avatar siting on the item will have a key and will have the highes link number so you have to skip them.

integer thousands = -1;
integer hundreds = -1;
...
state_entry()
{
integer current_link_nr = llGetNumberOfPrims();
// Check if it's more than one
if (1 <>0)
{
if (llGetLinkName(current_link_nr)=="1")
{
llOwnerSay("found 1: "+(string)current_link_nr);
one = current_link_nr;
}
else if (llGetLinkName(current_link_nr)=="10")
{
ten = current_link_nr;
llOwnerSay("found 10: "+(string)current_link_nr);
}
....
current_link_nr--;
}
}
}


Then when the number is changed, you send get the value of the thousands, then hundreds, then tens, then ones and send each on to the various number displays.



integer MSG_SET_NUM = 141; // the same message id defined in the number
doSendNumbers()
{
integer itmp = curval;
if (itmp>10000)
itmp=9999;

integer i;
i = itmp / 1000;
llOwnerSay("thousands = "+(string)i);
if (thousand!=-1)
{
// send the value to the thousands number
llMessageLinked(thousand, MSG_SET_NUM, (string)i, NULL_KEY);
}
itmp = itmp - (i*1000);

i = itmp / 100;
llOwnerSay("hundreds = "+(string)i);
if (hundred!=-1)
{
llMessageLinked(hundred, MSG_SET_NUM, (string)i, NULL_KEY);
}
itmp = itmp - (i*100);
.....


I had one more method on the scoreboard. When an avatar touches the scoreboard I increment the value and send the value out to the various individual numbers.

touch_start(integer total_number)
{
curval++;
if (curval>9999)
curval = 0;

doSendNumbers();
}

Thursday, June 26, 2008

Second Life Script - Number Texture Display

I needed a number display system. I've seen these in other items, but as usual I'm willing to just figure it out and build my own.

I first created a simple 16x256 pixel image of all the numbers. I made 16 numbers because textures are all power of two stuff. I doubt I'll do any hexadecimal displays, but I had the extra room.


I then used hit and miss to figure out the offsets for the numbers. I found the change from one number to the next was about 0.6 then worked backwards and forwards until I had both edges and -0.47 and +0.47. To make this programticall, I used (0.47*2)/16 to get 0.05875 which I tried, then finally figured out that I needed to divide by 15 because one cell is not counted in the actual size. That gave me an offset of 0.62666666.

integer curval = 0;
doOffset()
{
float ftmp = -0.47+(curval*0.062666);
llOwnerSay("offset ="+(string)ftmp);
llOffsetTexture(ftmp,0.0,ALL_SIDES);
}

default
{
state_entry()
{
doOffset();
}

touch_start(integer total_number)
{
// u offsets
//0=-0.47
//1=-0.41
//2=-0.35
//3=-0.29 *
//4=-0.22
//5=-0.16
//6=-0.10
//7=-0.04 *
//8=0.03
//9=0.09
//A=0.15
//B=0.21
//C=0.28 *
//D=0.34
//E=0.41
//F=0.47
// 0.47*2/15 = 0.06266666
curval++;
if (curval>16)
curval = 0;
doOffset();
}
}

There is one glaring problem I noticed after I got the number image uploaded. I probably need one cell that is only transparent so I can turn of the number. I'll do this later with another image upload and use -1 to display the blank number, but then I will not be able to show a hexadecimal number! Oh well... I'll probably end up making the other columns numeric symbols like dollar, pound, comma, period and such.



Make sure you apply the number texture to only one face. The rest of the faces are completely transparent. A simple trick is to select the texture face on the build dialog, then click on the individual faces to apply the texture to only that face.