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.
Add extra TCoord to S3DVertexTangents
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;
}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
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.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
I think that this is the function:
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
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;
}
}
}EDIT: nvm, got it working
-
Viz_Fuerte
- Posts: 91
- Joined: Sun Oct 19, 2008 5:29 pm
- Location: Valencia (Spain)
- Contact:
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.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
[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.
