PDA

View Full Version : I'm unAlphabetized ;)



gnoch
24-01-2005, 11:43 AM
Hi there,
Hard to think I'm sort-of a programming veteran when I sort-of come out of hiding after working on PHP websites for two years and start working again on my Delphi stuff, only to realize I know suck at it :lol:
Anyway... I've never been too fond of Direct3D so that's my explanation for it. Here's my problem, anyone who can fix it will be my hero. It sort of synthesizes everything that's never been too clear for me about Direct3D: alpha blending with material alpha component+texture alpha component+vertex alpha component.
Well, there won't be a texture alpha in this case because I've disabled all textures for this code.

This is what I'm trying to do: setting a material (in order to have variable scene-wide alpha blending). Then, setting all my vertices to have ALL different alpha settings (these are, obviously, lit vertices e.g. D3DFVF_LVertex).
Well... Now I need to make these two interact.
It's like the material setting will only be taken into account if I set D3DRS_DIFFUSEMATERIALSOURCE to D3DMCS_MATERIAL instead of D3DMCS_COLOR1. But then my per-vertex color data is forgotten.
I've been on this for over two hours now, and I'm unable to find any info in the DX8.1 documentation files. (Yes I'm using DX8.0 but I guess this kind of code can be converted to any recent version.)

I guess I could have easily done this two years ago, but I had to make some space for PHP and MySQL in my personal RAM. Too bad I can't upgrade it! :roll: Thanks to anyone who can help ;)

<2010 edit> What an interesting post for me! I thought I had learned PHP in 2005... Apparently it was earlier than that.

Clootie
25-01-2005, 11:18 PM
1) alpha-blending is really a final stage - when data produced by rasterizer is blended with backbuffer data.

2) Materials are only working when doing lighting in vertex processing part of 3D pipeline, but you are using D3DFVF_LVertex - so I assume lighting is turned off. And if lighting is off then color data is taken directly from your vertex data and not modified by lighting+material combo. Later this color can be combined with texture data in pixel processor of GPU.

Hope this will help...

gnoch
25-01-2005, 11:32 PM
Hi Clootie, I'm actually using your DirectX headers, great work eheh 8)


2) Materials are only working when doing lighting in vertex processing part of 3D pipeline, but you are using D3DFVF_LVertex - so I assume lighting is turned off.
Nah, it's turned on. I have gazillions of vertex types in my program. I'm just talking about a particular and microscopic polygon that is making spend extra hours trying to remember what I actually used to know in the past. I did a lot of alpha-blending code, I remember I studied a lot to understand all these INVSRCCOLOR things and such, and now I've forgotten some of the basics... Hence my question. It seems like it's the only thing that keeps me from restarting my engines. Some things you can't forget... Some things you can, apparently ;)


And if lighting is off then color data is taken directly from your vertex data and not modified by lighting+material combo. Later this color can be combined with texture data in pixel processor of GPU.

Hope this will help...
Have you got any sample code somewhere, by any chance? I couldn't seem to find anything that does both material+vertex alpha at the same time. Even Microsoft's lighting samples offer material alpha OR vertex alpha, not both at the same time :roll:
Thanks!

Clootie
25-01-2005, 11:55 PM
Hi Clootie, I'm actually using your DirectX headers, great work eheh 8)
Thanks :roll:

OK, opening DirectX 8.0 SDK help: page "Mathematics of Direct3D Lighting" or directly from here: Diffuse Lighting (DirectX 8.1 C++ Archive) (http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dx81_c/directx_cpp/Graphics/ProgrammersGuide/UsingDirect3D/LightsAndMaterials/MathematicsOfLights/Diffuse.asp):

[Vd is Vertex diffuse color]

The value for Vd is one of three values: one of the two possible vertex colors in a vertex declaration, or the material diffuse color. The value is:

vertex color1, if DIFFUSEMATERIALSOURCE = D3DMCS_COLOR1, and the first vertex color is supplied in the vertex declaration.
vertex color2, if DIFFUSEMATERIALSOURCE = D3DMCS_COLOR2, and the second vertex color is supplied in the vertex declaration.
material diffuse color

PS. You have to check is current card suports DIFFUSEMATERIALSOURCE at all (can't recall right now how to check this)
PPS. So, solution is to use COLOR1 and COLOR2 data field in vertex, and using COLOR2 to modulate material based color. Or move diffuce encoded alpha to light alpha and use DIFFUSEMATERIALSOURCE = D3DMCS_COLOR1. Or use COLOR1 and TFACTOR (skipping lighting altogeter)

gnoch
26-01-2005, 12:04 AM
Hi Clootie, I'm actually using your DirectX headers, great work eheh 8)
Thanks :roll:
I insist! ;)


OK, opening DirectX 8.0 SDK help: page "Mathematics of Direct3D Lighting" or directly from here: Diffuse Lighting (DirectX 8.1 C++ Archive) (http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dx81_c/directx_cpp/Graphics/ProgrammersGuide/UsingDirect3D/LightsAndMaterials/MathematicsOfLights/Diffuse.asp):
My... I actually read that page from the SDK yesterday! But didn't get much out of it :(


PS. You have to check is current card suports DIFFUSEMATERIALSOURCE at all (can't recall right now how to check this)
Are there actually cards that don't?


PPS. So, solution is to use COLOR1 and COLOR2 data field in vertex, and using COLOR2 to modulate material based color. Or move diffuce encoded alpha to light alpha and use DIFFUSEMATERIALSOURCE = D3DMCS_COLOR1. Or use COLOR1 and TFACTOR (skipping lighting altogeter)
Ouch... Didn't get it :-/
So, I should be putting two D3DCOLOR fields in my flexible vertex format? Then what...? (Sorry ;))

gnoch
26-01-2005, 03:28 AM
Also got an answer from gamedev:
http://www.gamedev.net/community/forums/topic.asp?topic_id=296714
They're advising me to use TFACTOR because material alpha PLUS vertex alpha is impossible to do without vertex shaders (ouch, not good enough for that).

Clootie
26-01-2005, 10:52 AM
Are there actually cards that don't?I'm not sure by now (it was long time ago when I touched this), but IIRC NVIDIA Riva128 or TNT (or probably another vendor) has some "specific behaviour" due to driver emulating D3DRS_DIFFUSEMATERIALSOURCE, D3DRS_SPECULARMATERIALSOURCE.

By COLOR2 I meant putting two colors in vertex format and later in texture stages setup use D3DTA_SPECULAR to reference COLOR2 (and DIFFUSE to reference your material color+alpha). At least in theory it should work. Or you can try to use single color in vertex format and try to use Specular part of material (redefinable by D3DRS_SPECULARMATERIALSOURCE) and reference by D3DTA_SPECULAR in texture stage setup to it.

Constant TFACTOR per DrawPrimitive is really easier way, but beware it was reported what some drivers have broken it's implementations (probably really old drivers). Another options is to use 1x1 texture and fill it with needed color (but you need to have spare texture unit available for that...)

gnoch
26-01-2005, 09:09 PM
Constant TFACTOR per DrawPrimitive is really easier way
I'm not so sure... :-/
Even this:
Dev.SetRenderState( D3DRENDERSTATE_TEXTUREFACTOR, factor );
Dev.SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTA_TFACTOR );

It won't work... :-/ No fading effect at all (obviously the "factor" color was set to have a non-constant alpha)
Well, maybe there's a problem somewhere else in my code!

Clootie
26-01-2005, 09:34 PM
How about:
...
Dev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
Dev.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
Dev.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);

Dev.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
Dev.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

:?:

gnoch
26-01-2005, 10:46 PM
How about:
...
Dev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
Dev.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
Dev.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);

Dev.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
Dev.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

:?:
I wish I could say it worked... :-/ No change.
Although the previous piece of code I posted was not working at all, I just copied-pasted it from a VB example, modified it under Delphi, and quickly reposted here the VB version, oops ;)

My code would say:

SetRenderState( D3DRS_ALPHABLENDENABLE, Ord(TRUE) );
SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
(Implied earlier: SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, Ord(D3DMCS_COLOR1) ); )

SetRenderState( D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(1,1,1,Round(Max(0,Alpha)*255)));
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

SetTexture(0, nil);
DrawPrim( D3DPT_TRIANGLELIST, (...) SizeOf(TD3DLVertex), D3DFVF_LVERTEX);

(DrawPrim just being an easy shortcut to DrawPrimitive with implied SetStreamSource and calculation of the number of primitives to show.)
I don't set any material, but I think there's already one "installed" and I don't remember if I need to disable them or how to do that :roll:

Any ideas? :(

Clootie
27-01-2005, 12:28 AM
in code above you are
1) not setting SetTextureStageState( 0, D3DTSS_COLOROP, ... );
2) should try to set color op also to D3DTOP_SELECTARG1
3) to lighting take efect you need to enable it :roll:
3.1) create light (directional?)
3.2) I would set some stub material just to be sure everything working (and later remove it if needed).

gnoch
27-01-2005, 02:34 AM
Well, actually I'd done all of that (it's just a sample from a much larger code...), but I hadn't tried to do something different for the COLOROP stuff... It was default (modulate, etc.), I tried to change it to a simple DIFFUSE and it worked!!! 8)

Thanks a lot for your help, Clootie :)