Jump to content
  • Advertisement
Sign in to follow this  
idloco

Missing Normals when using multiple textures

This topic is 4723 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

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);
		}
	}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
thanks that helps, i got the normals of the fisrt texture but on the second texture i got no normals yet.

Share this post


Link to post
Share on other sites
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 alpha
of this stage to be the diffuse alpha, no operation made. I think this should
be 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 your
stage operation will end up in the next stage. If you set RESULTARG to
something else only that single argument is carried on.*/


// Detail texture (2 layer)
/* Here you set the COLOROP twice. The last operation will overwrite the first
so 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 to
CURRENT which is the default value so it doesn't have to be set. Try
replacing 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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!