Sign in to follow this  

Turning Multi-texturing on and off .. Is It Possible ? [Looks like its solved]

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

I've been working through Ultimate Game Programming with DirectX and have come up with something that the book has not clarified due to the way their programs are set up. In the book each section of code is set in its own demo program to demonstrate its functionality. However, I have been adding each code in as a separate function on two and trying to get each functionality to run at the press of a button. It was working fine until I introduced extra textures and the ability to alpha blend and multi-texture. Now that the reasoning is set up heres the meat of the problem. And yes, before you ask I know FVF usage is phasing out. My main programs use the non FVF and simple shaders to draw and color/texture things. Once I've got to grips with this alpha/multi stuff I can start introducing new functionality into my main project. I did do a google search and read through various sites explanations including problems described on this site. However, none seem to reflect the problem I am having so if there is a site I overlooked because it was on page 20 :D Feel free to point me there so I can check it out. In my InitObjects routine I have set up 4 global textures as follows:
InitTextures("test.tga",&gTexture);
InitTextures("test2.tga",&gMultiTexture1);
InitTextures("test3.tga",&gMultiTexture2);
InitTextures("sprite.tga",&gAlphaTexture);
In which the function in question does this:
if (D3DXCreateTextureFromFile(gDevice,szFile,pTexture) != D3D_OK) return false;
return true;
I know the function returns true for these textures so that wouldn't explain the problem which I am getting .. My first question is : [code] gDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); gDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); [code] I take it that for each drawing segment I would start at 0 for each texture in use ? As in if I am multi-texturing then I would use 0 and 1 and in single textures always 0 ? Second question is :
gDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0);
gDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
gDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1);
gDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
This would cancel out any texture stage setting previously done ? Now the questions are out of the way here's the InitObjects/Render/CheckInput routines in their entirety before I explain what goes wrong..
bool InitialiseObj(void)
{
	SetProjection();
	SetRenderStates();
	bool bTex1 = InitTextures("test.tga",&gTexture);
	bool bTex2 = InitTextures("test2.tga",&gMultiTexture1);
	bool bTex3 = InitTextures("test3.tga",&gMultiTexture2);
	bool bTex4 = InitTextures("sprite.tga",&gAlphaTexture);
	gDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
	gDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
	gDevice->SetSamplerState(1,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
	gDevice->SetSamplerState(1,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
	SetView();
	Options = new bool[7];
	return true;
}


void RenderScene(void)
{
	gDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(128,128,128),1.0f,0);
	gDevice->BeginScene();
	SetRenderStates();					// Turn off Lighting and Culling
	AlphaBlend(FALSE,false,false);		// Turn off Alpha Blending
	OneBlend(FALSE,false,false);		// Turn off One Blending
	UseSprites(FALSE,FALSE,0.0f,0.0f,0.0f,0.0f,0.0f);	// Turn off PointSprite Use
	UseTexture(0,NULL);					// Clear Texture 0
	UseTexture(3,NULL);					// Clear Texture 3
	UseTexture(1,NULL);					// Clear Texture 1 and its Texture Stage
	gDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0);
	gDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
	UseTexture(2,NULL);					// Clear Texture 2 and its Texture Stage
	gDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1);
	gDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
	UpdateView();						// Position Camera
	// Now the meat of the code.  Based on Function Key Presses do the following:
	if (Options[0] && Option == 1)  
	{
		DrawLines();					// Draw 2 White Lines
	}
	if (Options[1] && Option == 2)  
	{
		DrawTriangle(false,false);		// Draw a 3 Colored Triangle
	}
	if (Options[2] && Option == 3) 
	{
		UseTexture(0,&gTexture);		// Use the first Texture
		DrawTriangle(true,false);		// Draw a single texture triangle
	}
	
	if (Options[3] && Option == 4) 
	{
		// Use the second texture as the first stage
		UseTexture(1,&gMultiTexture1);
		gDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0);
		gDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
		gDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
		gDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
		// Use the third texture as the second stage
		UseTexture(2,&gMultiTexture2);
		gDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1);
		gDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE);
		gDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE);
		gDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT);
		// Finally draw 2 multi-textured triangles 
		DrawTriangle(true,true);
	}
	
	if (Options[4] && Option == 5)
	{
		DrawMeshes();				// Draw the standard Meshes (teapot,torus,sphere,cube)
	}
	if (Options[5] && Option == 6)
	{
		UseTexture(3,&gAlphaTexture);	// Use the fourth texture 
		OneBlend(TRUE,false,true);		// Turn on One Blend
		UseSprites(TRUE,TRUE,1.0f,1.0f,0.0f,0.0f,1.0f);		// Turn on PointSprite Use
		DrawSprites();					// Draw Sprites
	}
	gDevice->EndScene();
	gDevice->Present(NULL,NULL,NULL,NULL);
}

bool CheckSpecialInput(void)
{
	if (gWindow->IsKeyPressed(VK_ESCAPE)) return false;
	if (gWindow->IsKeyPressed(VK_LEFT)) camPos.x -= 0.1f;
	if (gWindow->IsKeyPressed(VK_RIGHT)) camPos.x += 0.1f;
	if (gWindow->IsKeyPressed(VK_UP)) camPos.y += 0.1f;
	if (gWindow->IsKeyPressed(VK_DOWN)) camPos.y -= 0.1f;
	if (gWindow->IsKeyPressed(VK_ADD)) camPos.z += 0.1f;
	if (gWindow->IsKeyPressed(VK_SUBTRACT)) camPos.z -= 0.1f;
	if (gWindow->IsKeyPressed('W')) gDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
	if (gWindow->IsKeyPressed('S')) gDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
	if (gWindow->IsKeyPressed(VK_SPACE)) 
	{
		Option = 0;
		SetWindowText(gWindow->HWnd(),"Press Keys F1 to F8");
	}
	if (gWindow->IsKeyPressed(VK_F1)) 
	{
		Option = 1;
		Options[0] = InitLines();
		SetWindowText(gWindow->HWnd(),"Line Test");
		gDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
	}
	if (gWindow->IsKeyPressed(VK_F2)) 
	{
		Option = 2;
		Options[1] = InitTriangle(false,false);
		SetWindowText(gWindow->HWnd(),"Color Tri Test");
		gDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
	}
	if (gWindow->IsKeyPressed(VK_F3)) 
	{
		Option = 3;
		Options[2] = InitTriangle(true,false);
		SetWindowText(gWindow->HWnd(),"Textured Tri Test");
		gDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
	}
	if (gWindow->IsKeyPressed(VK_F4)) 
	{
		Option = 4;
		Options[3] = InitTriangle(true,true);
		SetWindowText(gWindow->HWnd(),"Multi Textured Tri Test");
	}
	if (gWindow->IsKeyPressed(VK_F5))
	{
		Option = 5;
		Options[4] = InitMeshes();
		SetWindowText(gWindow->HWnd(),"Mesh Test");
	}
	if (gWindow->IsKeyPressed(VK_F6))
	{
		Option = 6;
		Options[5] = InitSprite();
		SetWindowText(gWindow->HWnd(),"Point Sprite Test");
	}
	return true;
}


And here are the Init and Draw routines for each section:
bool InitLines(void)
{
	void* ptr;
	stD3DVertexColor objLines[4];
	objLines[0] = stD3DVertexColor(-0.5f,-0.5f,1.0f,D3DCOLOR_XRGB(255,255,255));
	objLines[1] = stD3DVertexColor(-0.5f, 0.5f,1.0f,D3DCOLOR_XRGB(255,255,255));
	objLines[2] = stD3DVertexColor( 0.5f,-0.5f,1.0f,D3DCOLOR_XRGB(255,255,255));
	objLines[3] = stD3DVertexColor( 0.5f, 0.5f,1.0f,D3DCOLOR_XRGB(255,255,255));
	if (gDevice->CreateVertexBuffer(sizeof(objLines),0,FVF_VERTEX_COLOR,D3DPOOL_DEFAULT, &gVBuffer,NULL) != D3D_OK) return false;
	if (gVBuffer->Lock(0,sizeof(objLines),(void**)&ptr,0) != D3D_OK) return false;
	memcpy(ptr,objLines,sizeof(objLines));
	gVBuffer->Unlock();
	return true;	
}
void DrawLines(void)
{
	gDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	gDevice->SetStreamSource(0,gVBuffer,0,sizeof(stD3DVertexColor));
	gDevice->SetFVF(FVF_VERTEX_COLOR);
	gDevice->DrawPrimitive(D3DPT_LINELIST,0,2);

}
bool InitTriangle(bool bTextured, bool bMultiple)
{
	void* ptr;
	if (bTextured)
	{
		if (bMultiple)
		{
			stD3DVertexTexture2 objTri[6];
			objTri[0] = stD3DVertexTexture2(-0.3f, -0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  0,1,0,1);
			objTri[1] = stD3DVertexTexture2( 0.3f, -0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  1,1,1,1);
			objTri[2] = stD3DVertexTexture2( 0.3f,  0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  1,0,1,0);
			objTri[3] = stD3DVertexTexture2( 0.3f,  0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  1,0,1,0);
			objTri[4] = stD3DVertexTexture2(-0.3f,  0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  0,0,0,0);
			objTri[5] = stD3DVertexTexture2(-0.3f, -0.4f, 0.0f,D3DCOLOR_XRGB(255,255,255),  0,1,0,1);
			if (gDevice->CreateVertexBuffer(sizeof(objTri),0,FVF_VERTEX_TEX2,D3DPOOL_DEFAULT, &gVBuffer,NULL) != D3D_OK) return false;
			if (gVBuffer->Lock(0,sizeof(objTri),(void**)&ptr,0) != D3D_OK) return false;
			memcpy(ptr,objTri,sizeof(objTri));
		}
		else
		{
			stD3DVertexTexture1 objTri[3];
			objTri[0] = stD3DVertexTexture1(-0.3f, -0.3f, 1.0f,D3DCOLOR_XRGB(255,255,255), 0,1);
			objTri[1] = stD3DVertexTexture1(0.3f, -0.3f, 1.0f,D3DCOLOR_XRGB(255,255,255),  1,1);
			objTri[2] = stD3DVertexTexture1(0.3f,  0.3f, 1.0f,D3DCOLOR_XRGB(255,255,255),  1,0);
			if (gDevice->CreateVertexBuffer(sizeof(objTri),0,FVF_VERTEX_TEX1,D3DPOOL_DEFAULT, &gVBuffer,NULL) != D3D_OK) return false;
			if (gVBuffer->Lock(0,sizeof(objTri),(void**)&ptr,0) != D3D_OK) return false;
			memcpy(ptr,objTri,sizeof(objTri));
		}
	}
	else
	{
		stD3DVertexColor objTri[3];
		objTri[0] = stD3DVertexColor(-0.5f, -0.5f, 1.0f, D3DCOLOR_ARGB(255,255,0,0));
		objTri[1] = stD3DVertexColor(0.5f, -0.5f, 1.0f, D3DCOLOR_ARGB(255,0,255,0));
		objTri[2] = stD3DVertexColor(0.5f,  0.5f, 1.0f, D3DCOLOR_ARGB(255,0,0,255));
		if (gDevice->CreateVertexBuffer(sizeof(objTri),0,FVF_VERTEX_COLOR,D3DPOOL_DEFAULT, &gVBuffer,NULL) != D3D_OK) return false;
		if (gVBuffer->Lock(0,sizeof(objTri),(void**)&ptr,0) != D3D_OK) return false;
		memcpy(ptr,objTri,sizeof(objTri));
	}
	gVBuffer->Unlock();
	return true;
}

void DrawTriangle(bool bTextured, bool bMultiple)
{
	gDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	gDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
	if (bTextured)
	{
		if (bMultiple)
		{
			gDevice->SetStreamSource(0,gVBuffer,0,sizeof(stD3DVertexTexture2));
			gDevice->SetFVF(FVF_VERTEX_TEX2);
			gDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
		}
		else
		{
			gDevice->SetStreamSource(0,gVBuffer,0,sizeof(stD3DVertexTexture1));
			gDevice->SetFVF(FVF_VERTEX_TEX1);
			gDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
		}
	}
	else
	{
		gDevice->SetStreamSource(0,gVBuffer,0,sizeof(stD3DVertexColor));
		gDevice->SetFVF(FVF_VERTEX_COLOR);
		gDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
	}
}
bool InitSprite(void)
{
	void* ptr;
	stD3DVertexColor objSprite[4];
	objSprite[0] = stD3DVertexColor(-0.5f, -0.5f, 2.0f, D3DCOLOR_XRGB(255,0,255));
	objSprite[1] = stD3DVertexColor(0.5f, -0.5f, 2.0f, D3DCOLOR_XRGB(0,255,0));
	objSprite[2] = stD3DVertexColor(0.5f,  0.5f, 2.0f, D3DCOLOR_XRGB(0,0,255));			
	objSprite[3] = stD3DVertexColor(-0.5f,  0.5f, 2.0f, D3DCOLOR_XRGB(255,0,0));
	if (gDevice->CreateVertexBuffer(sizeof(objSprite),
				D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | 
				D3DUSAGE_POINTS,FVF_VERTEX_COLOR,D3DPOOL_DEFAULT, 
				&gVBuffer,NULL) != D3D_OK) return false;
	if (gVBuffer->Lock(0,sizeof(objSprite),(void**)&ptr,0) != D3D_OK) return false;
	memcpy(ptr,objSprite,sizeof(objSprite));
	gVBuffer->Unlock();
	return true;
}

bool UseSprites(BOOL bEnableSprite, BOOL bEnableScale, float fSize, float fSizeMin, float fScaleA, float fScaleB, float fScaleC)
{
	gDevice->SetRenderState(D3DRS_POINTSPRITEENABLE,bEnableSprite);
	gDevice->SetRenderState(D3DRS_POINTSCALEENABLE,bEnableScale);
	gDevice->SetRenderState(D3DRS_POINTSIZE,FtoDW(fSize));
	gDevice->SetRenderState(D3DRS_POINTSIZE_MIN,FtoDW(fSizeMin));
	gDevice->SetRenderState(D3DRS_POINTSCALE_A,FtoDW(fScaleA));
	gDevice->SetRenderState(D3DRS_POINTSCALE_B,FtoDW(fScaleB));
	gDevice->SetRenderState(D3DRS_POINTSCALE_C,FtoDW(fScaleC));
	return true;
}

void DrawSprites(void)
{
	gDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	gDevice->SetStreamSource(0,gVBuffer,0,sizeof(stD3DVertexColor));
	gDevice->SetFVF(FVF_VERTEX_COLOR);
	gDevice->DrawPrimitive(D3DPT_POINTLIST,0,4);
}
bool InitMeshes(void)
{
	InitLightAndMaterial();
	bTeapot = SUCCEEDED(D3DXCreateTeapot(gDevice,&gTeapot,NULL));
	bCube = SUCCEEDED(D3DXCreateBox(gDevice,2,2,2,&gCube,NULL));
	bSphere = SUCCEEDED(D3DXCreateSphere(gDevice,1.5,25,25,&gSphere,NULL));
	bTorus = SUCCEEDED(D3DXCreateTorus(gDevice,0.5f,1.2f,25,25,&gTorus,NULL));
	if (bTeapot || bCube || bSphere || bTorus) return true;
	return false;
}

void DrawMeshes(void)
{
	gDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
	gDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
	D3DXMatrixTranslation(&gWorld,2.0f,-2.0f,0.0f);
	gDevice->SetTransform(D3DTS_WORLD,&gWorld);
	gDevice->SetMaterial(&gMaterial);
	gTeapot->DrawSubset(0);
	D3DXMatrixTranslation(&gWorld,-2.0f,-2.0f,0.0f);
	gDevice->SetTransform(D3DTS_WORLD,&gWorld);
	gDevice->SetMaterial(&gMaterial);
	gCube->DrawSubset(0);
	D3DXMatrixTranslation(&gWorld,2.0f,2.0f,0.0f);
	gDevice->SetTransform(D3DTS_WORLD,&gWorld);
	gDevice->SetMaterial(&gMaterial);
	gSphere->DrawSubset(0);
	D3DXMatrixTranslation(&gWorld,-2.0f,2.0f,0.0f);
	gDevice->SetTransform(D3DTS_WORLD,&gWorld);
	gDevice->SetMaterial(&gMaterial);
	gTorus->DrawSubset(0);
}


Oh and of course the FVF set up which will hopefully show I am using the right ones each time .. :D
struct stD3DVertexTexture1
{
	float x,y,z;
	unsigned long c;
	float tu,tv;
	stD3DVertexTexture1() {}
	stD3DVertexTexture1(float fX, float fY, float fZ, unsigned long ulC, float fTU, float fTV)
	{
		x = fX;
		y = fY;
		z = fZ;
		c = ulC;
		tu = fTU;
		tv = fTV;
	}
};
#define FVF_VERTEX_TEX1 (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

struct stD3DVertexTexture2
{
	float x,y,z;
	unsigned long c;
	float tu,tv;
	float tu2,tv2;
	stD3DVertexTexture2() {}
	stD3DVertexTexture2(float fX, float fY, float fZ, unsigned long ulC, float fTU, float fTV, float fTU2, float fTV2)
	{
		x = fX;
		y = fY;
		z = fZ;
		c = ulC;
		tu = fTU;
		tv = fTV;
		tu2 = fTU2;
		tv2 = fTV2;
	}
};
#define FVF_VERTEX_TEX2 (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2)

struct stD3DVertexColor
{
	float x,y,z;
	unsigned long c;
	stD3DVertexColor() {}
	stD3DVertexColor(float fX, float fY, float fZ, unsigned long ulC)
	{
		x = fX;
		y = fY;
		z = fZ;
		c = ulC;
	}
};
#define FVF_VERTEX_COLOR (D3DFVF_XYZ | D3DFVF_DIFFUSE)


Now the majority of the code is there (feel free to ask for any other code I may have not posted) Here is what should and is happening for each test. When pressed in order F1,F2,F3,F4,F5,F6 Test 1 - Line Test - Works fine Test 2 - Color Tri Test = Works fine Test 3 - Single Tex Tri Test = Comes up with no texture white/black only Test 4 - Multi Tex Tri Test = Uses gTexture instead of gMultiTexture1, gMultiTexture2 and thus no blending Test 5 - Mesh Test - Works fine Test 6 - Displays Alpha'd boxes instead of sprite points which is the image set to be used. I'm sure I am missing something but I've run through the code in the book and can't see anything that may have been copied wrong so I can only assume the code for use in one section is affecting all sections and not clearing out. I've read through the texturing part of the chapter again and I can't see anything explaining which numbers go where in the various texture functions. Thanks for any replies and of course for reading this long long post. [Edited by - Xrystal on March 17, 2007 6:07:52 AM]

Share this post


Link to post
Share on other sites
Well, I tried another route round this and created a new project and inserted the code to display the point sprites. Worked as I expected. (Code was almost exactly copied from the code I posted in the last message). I then added the Multi-texturing segment and lo and behold... problems. Even worse than before though, now nothing appears. Probably need to add something else from the other code I overlooked.

If I manage to solve this I'll post up how I did it.

Thanks for all the reads. There must be a way to disable multi texturing as I am sure not every object is multi-textured in every project out there.

Share this post


Link to post
Share on other sites
Well finally solved my problem. Once I made sure that I disabled/reset anything used for each drawing section the only problem I was left with was the fact that it kept using the same texture regardless as to which file I loaded.

So, I set up a separate program that dealt with just the two main issues of Multi Texture and Alpha Blending seeing as they seemed to have been the main culprits. Once I got that working (today) I compared the code to the other program that had multiple drawing sections. And noticed that the DemoClass I set up was assigning each drawing run to the same global texture variable instead of one of the others set up.

What I learnt this time round ...

1) Check and recheck and recheck again any variables used to make sure they are the right ones.

2) Might be a good idea to write a simple demo project to showcase each segment before merging into a single project.

3) Multi-texturing looks cool with the right texture order.

Now that I got it working its time to see if I understand the functionality before moving on to the next step in the book.

Share this post


Link to post
Share on other sites

This topic is 3929 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this