Missing Normals when using multiple textures

Started by
12 comments, last by idloco 18 years, 10 months ago
the normals on my terrain engine disappear when i try to implement some kind of texture blending. this is the source code of the blending

	TheGraphics.GetDevice()->SetTexture(0, terrainTexture[0]->GetTextureHandle() );
	TheGraphics.GetDevice()->SetTexture(1, terrainTexture[1]->GetTextureHandle() );


	TheGraphics.GetDevice()->SetFVF(D3DFVF_CUSTOMVERTEX);

	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE);
	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);

	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTOP_MODULATE);
	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
	TheGraphics.GetDevice()->SetTextureStageState(0,D3DTSS_RESULTARG,D3DTA_DIFFUSE);


	// Detail texture (2 layer)
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_ADDSIGNED);
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE);
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT);

	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_ALPHAARG1,D3DTOP_MODULATE);
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
	TheGraphics.GetDevice()->SetTextureStageState(1,D3DTSS_RESULTARG,D3DTA_CURRENT);

this is the code for the normals

HRESULT CTerrainSection::LoadSection(unsigned char* pHeightMap, uint16 pX, uint16 pY)
{

	uiXPos = pX*(SECTION_SIZE);
	uiYPos = pY*(SECTION_SIZE);
	for(int iy = 0; iy < ( SECTION_SIZE + 1 );++iy)
	{
		for(int ix = 0; ix < ( SECTION_SIZE + 1 );++ix)
		{
			// Compute the normal of the vertex
			tempNormal1.x = (float)ix+uiXPos;
			tempNormal1.y = (float)iy+uiYPos;
			tempNormal1.z = (float)pHeightMap[((iy+uiYPos)*100)+(ix+uiXPos)] / TERRAIN_SCALE;

			tempNormal2.x = (float)ix+uiXPos+1;
			tempNormal2.y = (float)iy+uiYPos;
			tempNormal2.z = (float)pHeightMap[((iy+uiYPos)*100)+(ix+1+uiXPos)] / TERRAIN_SCALE;

			tempNormal3.x = (float)ix+uiXPos;
			tempNormal3.y = (float)iy+uiYPos-1;
			tempNormal3.z = (float)pHeightMap[((iy-1+uiYPos)*100)+(ix+uiXPos)] / TERRAIN_SCALE;

			ComputeNormal(&out, &tempNormal1, &tempNormal2, &tempNormal3 );
			if (iy < 15)
			{
				pVertexData[ix + iy * (SECTION_SIZE + 1)].diffuse = 0x0fFFFFFF;
			}else
				pVertexData[ix + iy * (SECTION_SIZE + 1)].diffuse = 0xFFFFFFFF;
			
			pVertexData[ix + iy * (SECTION_SIZE + 1)].v.x = (float)ix;
			pVertexData[ix + iy * (SECTION_SIZE + 1)].v.y = (float)iy;
			pVertexData[ix + iy * (SECTION_SIZE + 1)].v.z = (float)pHeightMap[((iy+uiYPos)*100)+(ix+uiXPos)] / TERRAIN_SCALE;
			pVertexData[ix + iy * (SECTION_SIZE + 1)].n = out;
			pVertexData[ix + iy * (SECTION_SIZE + 1)].tu1 = (float)(ix);
			pVertexData[ix + iy * (SECTION_SIZE + 1)].tv1 = (float)(iy);
			pVertexData[ix + iy * (SECTION_SIZE + 1)].tu2 = (float)(ix);
			pVertexData[ix + iy * (SECTION_SIZE + 1)].tv2 = (float)(iy);
		}
	}

------------------------------------ IDLoco Game Studios
Advertisement
Methinks you have a typo on this line
TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTOP_MODULATE );

and on this line
TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTOP_MODULATE );

setting an argument to an operation.

Stay sharp.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
I got the same results removing those lines :(
------------------------------------ IDLoco Game Studios
I think he means

D3DTSS_ALPHARAG1, D3DTOP_MODULATE should be D3DTSS_ALPHAOP, D3DTOP_MODULATE

Since modulate is the operation you want to make, and not the source colour
thanks that helps, i got the normals of the fisrt texture but on the second texture i got no normals yet.
------------------------------------ IDLoco Game Studios
Quote:Original post by jikbar
I think he means

D3DTSS_ALPHARAG1, D3DTOP_MODULATE should be D3DTSS_ALPHAOP, D3DTOP_MODULATE

Since modulate is the operation you want to make, and not the source colour


Exactly. Sorry for being unclear.

Let's look some more at your stage states.

/* This block looks alright.You multiply the texture color with the diffuse color.*/TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );/* This is what I mentioned above.You set ALPHAARG1 to MODULATE which doesn't make sense.Then you set the RESULTARG to DIFFUSE, which will cause the resulting alphaof this stage to be the diffuse alpha, no operation made. I think this shouldbe changed to the commented block below.*/TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTOP_MODULATE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_DIFFUSE );/*TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );*//* RESULTARG will be set to CURRENT by default which is the only way yourstage operation will end up in the next stage. If you set RESULTARG tosomething else only that single argument is carried on.*/// Detail texture (2 layer)/* Here you set the COLOROP twice. The last operation will overwrite the firstso the first of them is useless. Is this your intention?*/TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA );TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );/* See the previous alpha block about ALPHAARG1. Here you set RESULTARG toCURRENT which is the default value so it doesn't have to be set. Tryreplacing this block with the commented block below.*/TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTOP_MODULATE );TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 1, D3DTSS_RESULTARG, D3DTA_CURRENT );/*TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );TheGraphics.GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT );*/

Remember, the arguments are processed by the operation and the result ends up in current. Resultarg is waht is passed on to the next stage or to the draw.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
thx but.., i change the code to what you said and i still got the normals only drawn on the first texture of the blend, the others textures got no normals on.
Look at these images..
On this one you can see the normals been drawn..
Free Image Hosting at www.ImageShack.us

But on this one they all are gone.. thats because i change the blending factor of the second texture the normals disapear.. and i don't know why..
Free Image Hosting at www.ImageShack.us

The blending works just fine ( add more textures instead of just 2, will be nice thoug ). is the normal what's given me trouble..


[EDIT] Make the images smaller
------------------------------------ IDLoco Game Studios
How exactly is it you want the normals to be drawn? Your code is quite hard to follow so it's difficult to see how you want it to function.

Please explain what your code is supposed to do.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
ok, the normals are only drawn on the texture 0,
This one..
TheGraphics.GetDevice()->SetTexture(0, terrainTexture[0]->GetTextureHandle() );

if i use a blening to make the other texture appear, then the normals dont show..

i want the normals to be drawn on every texture not just the 0, this is the first time i work with blending and normals.. so i don't really know yet if im using them wrong or expeting something diferent to what they do..

btw by normals i mean the dark places on hills and such, that look like "shadows"

and what part exactly you want to me yo explain? the SetTextureStages is the first time. so i got no experience on them..
------------------------------------ IDLoco Game Studios
Quote:btw by normals i mean the dark places on hills and such, that look like "shadows"

Ok, that clarifies it somewhat. [smile]

This is what I gather from your LoadSelection( ) function. Correct me where I'm wrong.

You supply it a heightmap in the form of a char array containing height values for every vertex. Then it computes a normal for the vertex which is stored in out which I assume is a vector. Then you set the current vertex' diffuse alpha component to 0F or FF depending on whether the y-loop index is less than 15 or not. This I do not understand.

Then you set the vertex' position properly and you set it's normal to out. After that the two texture coordinate pairs are set to the vertex' x and y position, which I don't follow since texcoords are ranged from 0.0f to 1.0f (and loops outside of that. Anyway that has nothing to do with the shadow of you hill not showing.

How do you transfer your normal vector angle to the texture stage? Only colors and textures can affect the blending, so you must have converted your vector by some means.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker

This topic is closed to new replies.

Advertisement