Archived

This topic is now archived and is closed to further replies.

Custom lighting

This topic is 6359 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all... I have a big terrain mesh, and each point gets a light value stores in a structure that looks like this (I''m doing my own lighting): typedef struct { char b,g,r,a; } RGBLIGHT,*LPRGBLIGHT; No, when I want to stand something on the mesh, it is supposed to get the light value of the four points it is nearest, according to how close it is. I arranged a lookup table for this, so when I say ''plot at x,y,z'' it tells me, take 10% of the light from this vertex, 80% from this vertex, 5% from this vertex, and 5% from this vertex. Works nicely, and is ''fast enough,'' but I''m trying to wrangle a little more speed out of it. I also arranged a lookup table that represents each percentage of light, so no math calculations are actually being done, at any time. The bummer is, I need to individually fiddle with each r,g,b,a item. What I would love to do is say "Take 10% of (r,g,b,a)" instead of "Take 10% of r, take 10% of g, take 10% of b, take 10% of a," etc, etc. Of course, if I tried to take 10% of the long integer that rgba comprises, I''d get a nonsense number. I thought there might be some advanced mathematical method of doing this, or possibly an MMX method. Has anyone played with such a thing before, and could give me some pointers? I guess I could do a 4,294,967,295 x 4,294,967,295 lookup table, right? Thanks in advance! -- Goodlife ----------------------------- Those whom the gods would destroy, they first drive mad. --DirectX design team official motto

Share this post


Link to post
Share on other sites
Yup it''s possible to use mmx... First off you''ve got 4 variables right? And each variable is 1 byte? Am I correct? Cause with mmx every instruction will execute in 1 cpu cycle vs. the old instructions which a multiply or divide could take between 17-50+ cpu cycles! And every mmx instruction operates on 64bit values at a time.

Now you can treat this 64 bit value as 8 bytes and do 8 seperate byte multiplications at once or you could treat this 64 bits as 4 word values (This is what I do fo 16bpp alphablending) or 2 dword values or one qword value. So if your working with bytes, you could load up two pixels and operate on both at the same time then go on to the next.

So you want a function that will take in 8bytes and reaturn 8bytes where each of the resultant bytes is 10% of the original byte?

Post the formula and I''ll tell you what I''d do (Actually I want to implement lighting in my game anyways someday, it''d be nice to have some exposure :-)

Now last time when I gave a C++ user my asm code to convert to inline we ended up needing the help of another good c++ programmer to get it to work right, so if you can''t do the in-line assembly well yourself, hope that someone stumbles along here and wants to help! Cause I don''t do C++ worth mentioning..

- Ben

Share this post


Link to post
Share on other sites
Oh yah I forgot to mention... MMX sounds to good with those timings right? Well here''s the catch:

It uses the fpu registers to get this speed, which means you can only use eith mmx or fpu at a time. So when your finished with mmx you have to call an instruction "emms" which empties the mmx registers and frees them up for fpu again, but you''ve lost whatever values you had in the fpu registers first. So if you have values in there that you want to keep you have to push the fpu registers onto the stack and pop them off when your done which can cost more time than it''s worth sometimes for simple calculations like 10%... so tell me if your using fpu in these lighting functions.
- Ben

Share this post


Link to post
Share on other sites
i dont know MMX at all so I didn''t know about the instructions it uses and the number of cycles it takes to execute each. The point is the same though, you have to operate on each component separately (i see that you mentioned two components at the time, hope that''s possible and still get a correct result). If that''s correct than you''re in luck. Benm, please post the ASM code!

btw, is there anything i have to do to be able to use MMX instructions in my code? any websites that explain the instructions and stuff that it uses? Thanks!


..-=gLaDiAtOr=-..

Share this post


Link to post
Share on other sites
Ok I''ll give you the quick low down:

mov al, b ;Move in blue color value into lower 8 bits of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, g ;Move in green colour value into lower 8 bits of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, r ;Move in red colour value into lower 8 bit of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, a ;Move in Alpha value into lower 8 bits of eax

movd MM0,eax ; Copy Our bytes into MM0 - 0000 0000 bbgg rraa
psllq MM1,32 ; Shift those to MM0 - bbgg rraa 0000 0000 (I may have to look up this one, I don''t remember if this is the right shift instruction)

;Second set of values
mov al, b ;Move in blue color value into lower 8 bits of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, g ;Move in green colour value into lower 8 bits of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, r ;Move in red colour value into lower 8 bit of eax
shl eax, 8 ;Shift those 8 bits over to allow room for the next 8bits
mov al, a ;Move in Alpha value into lower 8 bits of eax

movd MM0,eax ; Copy Our bytes into MM0 - bbgg rraa bbgg rraa


So what I''ve done here is a sort of pseado code, you''d have to replace,b,g,r,a with real variable''s or something. This basically loaded b, shifted it over 8bits, loaded g (Which is now just under the b byte), shifted it over, loaded the r (Which is now below g, which is below b), shifted it over and loaded a. This 32 bit value is now moved into the lower half of the mmx register MM0 (You''ve got eight of them MM0-MM7) and then shifted up 32 bits. Then we do that all again for the second set of values. Now we''ve got a 64 bit value with two sets of b,g,r,a. Now let''s see how we''d divide by 10 to get 10%:

First we need to set up the value''s we want to divide by, which will be 8 bytes with the values of 10 or 0A0A 0A0A 0A0A 0A0A
I believe in C++ you can set it up like this:
__int64 DIV64 = 0x0A0A0A0A0A0A0A0A;


pdivb MM0,DIV64 ;I''ll have to look this one up too.


Then you''d simply extract your values, so reverse of what we did before.. I''m sure you could simplify all the shifting with a line of C++ and just use a couple lines of asm though. This is just to give you an idea of what''s involved, if you seriously want to do this, I''ll check back later and look up the shifting a div codes (There are different version, depending on wheather you want to operate on the value as bytes, words, dwords, or a qword)

Hope that gives you an idea of what''s involved!
BTW there''s a tutorial on MMX alpha blitting in C++ in the resource area and even though it''s alpha blending it explains a lot of the theory too and is well commented source, you can figure out some asm stuff from that, I learned most of my mmx from there anyhow! :-)

See ya,
Ben

Share this post


Link to post
Share on other sites