Add extra TCoord to S3DVertexTangents

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Add extra TCoord to S3DVertexTangents

Post by Lambda »

Currently i'm computing the tangents at the GPU and i want to write it statically to my own level format.

How hard is to add an extra texture coord to the engine? Actually i'm only interested in Direct3D9, i have tryed some things but they all have failed.
Image
zillion42
Posts: 324
Joined: Wed Aug 29, 2007 12:32 am
Location: Hamburg, Germany

Post by zillion42 »

just realized you want tangents... you have to check if there are 2TTangents or something similar...

Code: Select all

scene::SMesh* LoadLightmapMeshes(scene::IAnimatedMesh* texturemesh, scene::IAnimatedMesh* lightmapmesh )
{

	scene::IMesh* workTextureMesh = texturemesh->getMesh(0);
	scene::IMesh* workLightmapMesh = lightmapmesh->getMesh(0);

	scene::SMesh* SFinalMesh = new irr::scene::SMesh();

	u32 TmbCount = workTextureMesh->getMeshBufferCount();
	u32 LMmbCount = workLightmapMesh->getMeshBufferCount();
	printf("Amount of Buffers in texturemesh: %d \n",TmbCount);
	printf("Amount of Buffers in lightmapmesh: %d \n\n",LMmbCount);

	if(TmbCount == LMmbCount){
		u32 i;
		for(i=0; i < workTextureMesh->getMeshBufferCount(); i++){

			scene::SMeshBufferLightMap * new2Tbuffer = new scene::SMeshBufferLightMap();
			scene::IMeshBuffer* bufferTM = workTextureMesh->getMeshBuffer(i);
			scene::IMeshBuffer* bufferLM = workLightmapMesh->getMeshBuffer(i);

			// get the amount of vertices in Texturemesh meshbuffer
			u32 numVerticesTM = bufferTM->getVertexCount(); 
			// get the amount of indices in Texturemesh meshbuffer
			u32 numIndicesTM = bufferTM->getIndexCount(); 
			// get the amount of vertices in Lightmapmesh meshbuffer
			u32 numVerticesLM = bufferLM->getVertexCount(); 
			// get the amount of indices in Lightmapmesh meshbuffer
			u32 numIndicesLM = bufferLM->getIndexCount(); 

			printf("Amount of Vertices in texturemesh: %d \n ",numVerticesTM);
			printf("Amount of Vertices in lightmapmesh: %d \n \n ",numVerticesLM);

			//get pointer to Vertices and cast to irr::video::S3DVertex - Texturemesh
			video::S3DVertex *bufferVerticesTM = (irr::video::S3DVertex*)bufferTM->getVertices();

			//get pointer to Indices - Texturemesh
			irr::u16 *bufferIndicesTM = bufferTM->getIndices();

			//get pointer to Vertices and cast to irr::video::S3DVertex - LightmapMesh
			video::S3DVertex *bufferVerticesLM = (irr::video::S3DVertex*)bufferLM->getVertices();

			//get pointer to Indices - LightmapMesh
			irr::u16 *bufferIndicesLM = bufferLM->getIndices();

			//Create storage for new combined S3DVertex2TCoords,indices and material
			core::array<video::S3DVertex2TCoords> vertices;
			core::array<u16> indices;
			video::SMaterial CurrMaterial = bufferTM->getMaterial();

			// push vertices into Storage and push
			// TCoords of Lightmapmesh to TCoords2 of Texturemesh
			u32 j;
			u32 Cmax;
			if(numVerticesTM > numVerticesLM){
				Cmax = numVerticesLM;
			}else if(numVerticesLM > numVerticesTM){
				Cmax = numVerticesTM;
			}else if(numVerticesLM == numVerticesTM){
				Cmax = numVerticesLM;
			}
			for (j = 0; j < Cmax; ++j){
				//Maya X-Exporter bug (vertex color is black)
				bufferVerticesTM[j].Color = 16777215; 
				vertices.push_back(video::S3DVertex2TCoords(bufferVerticesTM[j].Pos,
															bufferVerticesTM[j].Normal,
															bufferVerticesTM[j].Color, 
															bufferVerticesTM[j].TCoords, 
															bufferVerticesLM[j].TCoords));
			}

			// push indices into Storage
			u32 k;
			for (k = 0; k < numIndicesTM; ++k)
				indices.push_back(bufferIndicesTM[k]);

			//get Texture from slot1 of Lightmapmesh
			video::SMaterial CurrMaterialLM = bufferLM->getMaterial();
			video::ITexture* CurrentTextureLM = CurrMaterialLM.getTexture(0);

			//change Material Type and apply Lightmapmeshs Texture to slot2 of Texturemesh
			CurrMaterial.MaterialType = irr::video::EMT_LIGHTMAP_LIGHTING_M2;
			CurrMaterial.setTexture(1,CurrentTextureLM);
			CurrMaterial.Lighting = false;

			//Add stored data to new buffer
			new2Tbuffer->Material = CurrMaterial;
			new2Tbuffer->Vertices = vertices;
			new2Tbuffer->Indices = indices;


			new2Tbuffer->recalculateBoundingBox();
			SFinalMesh->addMeshBuffer(new2Tbuffer);

		}
	}else{
		printf("Unsane operation... trying to combine meshes with different amounts of Materials");
		return 0;
	}
	SFinalMesh->recalculateBoundingBox();
	return SFinalMesh;
}
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

That doesn't work in my case since i need the extra TCoord in order to do the lightmapping in a shader and i need the 2 TCoords and both tangent & binormals passed as parameters.
Image
zillion42
Posts: 324
Joined: Wed Aug 29, 2007 12:32 am
Location: Hamburg, Germany

Post by zillion42 »

since S3DVertexTangents are derived from S3DVertex it should also be possible to make something like "S3DVertexTangents2T" based on S3DVertex2TCoords, I guess you'd need some help though. You should maybe also consider making a HLSL shader for irrlicht, especially if you're into d3d9.
Copy the source of S3DVertex2TCoords and try to squeeze in the binormals and tangents (maybe better copy the source of S3DVertexTangents and try to squeeze in additional TCoords), ask someone to check it in, get some help. Maybe Blindside could... good luck ! http://irrlicht.sourceforge.net/docu/st ... gents.html
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

zillion42 wrote:since S3DVertexTangents are derived from S3DVertex it should also be possible to make something like "S3DVertexTangents2T" based on S3DVertex2TCoords, I guess you'd need some help though. You should maybe also consider making a HLSL shader for irrlicht, especially if you're into d3d9.
Copy the source of S3DVertex2TCoords and try to squeeze in the binormals and tangents (maybe better copy the source of S3DVertexTangents and try to squeeze in additional TCoords), ask someone to check it in, get some help. Maybe Blindside could... good luck ! http://irrlicht.sourceforge.net/docu/st ... gents.html
Yes, all of this is already done, i have a S3DVertexTangents2 but i dont know what part of the engine should modify to let irrlicht send the second UV Coord to the shader.
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Sending the data happens in the driver, it's usually part of drawVertexPrimitiveList.
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

I think that this is the function:

Code: Select all

void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType)
{
	if (newType != LastVertexType)
	{
		LastVertexType = newType;
		HRESULT hr = 0;

		switch(newType)
		{
		case EVT_STANDARD:
			hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1);
			break;
		case EVT_2TCOORDS:
			hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2);
			break;
		case EVT_TANGENTS:
			hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX4 |
				D3DFVF_TEXCOORDSIZE2(0) | // first texture coord
				D3DFVF_TEXCOORDSIZE2(1) | // second texture coord
				D3DFVF_TEXCOORDSIZE3(2) | // misuse texture coord 3 for tangent
				D3DFVF_TEXCOORDSIZE3(3) // misuse texture coord 4 for binormal
				);
			break;
		}

		if (FAILED(hr))
		{
			os::Printer::log("Could not set vertex Shader.", ELL_ERROR);
			return;
		}
	}
}
I have changed D3DFVF_TEX3 to D3DFVF_TEX4 in order to pass 4 texture coords (2 real coords and the other two are tangent & binormal) and added the extra D3DFVF_TEXCOORDSIZE2 but i dont get the second coord at the shader, maybe i'm missing something?

EDIT: nvm, got it working :)
Image
Viz_Fuerte
Posts: 91
Joined: Sun Oct 19, 2008 5:29 pm
Location: Valencia (Spain)
Contact:

Post by Viz_Fuerte »

Hi!

Would you mind show the code you've changed?
Would be very helpful.

I'm trying to combine DIffuse + Normal + Specular + Light Map and can not.

Gracias :lol:
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

Viz_Fuerte wrote:Hi!

Would you mind show the code you've changed?
Would be very helpful.

I'm trying to combine DIffuse + Normal + Specular + Light Map and can not.

Gracias :lol:
YOu should edit the S3DVertexTangents class and derive it from S3DVertex2TCoords instead S3DVertex, then find the avobe function in your D3D9 driver and add the modifications.

[Español]
Como eres de españa, te lo escribo en nuestro idioma que seguro que se me entiende mejor xD.

Esto solo funciona con el Direct3D9 para los otros drivers tendras que buscar tu la funcion donde envia al shader los parametros.

Ve al .h donde esta definido S3DVertexTangents y derivalo de S3DVertex2TCoords asi tendras 2 coordenadas.

Despues ve al cpp del driver del DX9, busca la función que esta arriba en mi otro post y dejala igual que esta ahi, con eso deberia de bastar.
Image
Post Reply