Problems with smooth shading in DX7
Ok, I have a model I have imported from a 3ds max .ase file. (I wrote the importer.)
I render the object using the D3DPT_TRIANGLELIST "option" with D3DFVF_VERTEX as the vertex type.
The model renders but it looks flat shaded. What do I have to do to make it smooth shaded?
Here are the states I am setting:
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0x00000000 );
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_DITHERENABLE, TRUE );
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_SPECULARENABLE, FALSE );
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE );
Video->AGS3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
Video->AGS3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
Video->AGS3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
Video->AGS3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );
Video->AGS3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
Video->AGS3DDevice->SetRenderState( D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD );
Can someone please tell what I am doing wrong?
Well, I haven''t done much with d3d, but I do know that normal Gouraud shading uses vertex normals instead of just triangle normals. I would think d3d would need the same information (or maybe there''s a way to tell it to compute the vertex normals for you).
Yeah, lich is right, it seems as if you''re not using the right normals. I had exactly the same problems (look for a post ~w weeks ago), so I started coding a routinw which would
-search for vertex shared by at least 3 triangles
-calculate the vertex normal out of the 3 plane normals.
It proved quite difficult (because of my strange way of saving the data), and it works only paritially. If you happen to find a better approach, I''d be glad to hear about it!
-search for vertex shared by at least 3 triangles
-calculate the vertex normal out of the 3 plane normals.
It proved quite difficult (because of my strange way of saving the data), and it works only paritially. If you happen to find a better approach, I''d be glad to hear about it!
ASE file contains normals per face (triangle). The "*MESH_VERTEXNORMAL" is what you nead to look at for normals data in ASE file. And becouse multiple triangles can share each vertex, this data is saved multiple times for each vertex. You shoud simply load first normal for first vertex and then add second normal for same vertex, add third normal for same vertex... And at the end you must NORMALIZE all normals to get good results.
Sentinel,
Could you please show some psuedo code using example .ase data?
I am a little confused about what you mean by loading normals three times for each.
Thanks,
AG
Could you please show some psuedo code using example .ase data?
I am a little confused about what you mean by loading normals three times for each.
Thanks,
AG
Here''s the code I use:
float* ptr; // Pointer to vertex
WORD num=0,max=0; // Just counters
while (strcmp(data,"*MESH_NORMALS") // feof(File)) fscanf(File,"%s",data);
while (strcmp(data,"}") // feof(File))
{
if (strcmp(data,"*MESH_VERTEXNORMAL")==0)
{
fscanf(File,"%i %f %f %f",&num,&x,&z,&y);
ptr[num*8+3]+=x; // += !!
ptr[num*8+4]+=y; // += !!
ptr[num*8+5]+=z; // += !!
if (num>max) max=num;
}
fscanf(File,"%s",data);
}
if (feof(File)) return;
for (num=0; num{
a.dvX=ptr[3]; a.dvY=ptr[4]; a.dvZ=ptr[5]; // Read normal
a=Normalize(a); // Normalize normal
ptr[3]=a.dvX; ptr[4]=a.dvY; ptr[5]=a.dvZ; // Write normal
ptr+=8;
}
And here''s a part of ASE file for example:
*MESH_NORMALS {
*MESH_FACENORMAL 0 -0.134989 0.155329 -0.978596
*MESH_VERTEXNORMAL 3362 -0.096996 0.131464 -0.986564
*MESH_VERTEXNORMAL 1124 -0.110075 0.154374 -0.981861
*MESH_VERTEXNORMAL 0 -0.124476 0.139596 -0.982353
*MESH_FACENORMAL 1 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 3363 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 1128 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 0 -0.119393 0.191704 -0.974163
*MESH_FACENORMAL 2 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 3364 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 1131 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 0 -0.252629 0.179425 -0.950781
*MESH_FACENORMAL 3 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 3365 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 1134 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 0 -0.303272 0.021187 -0.952668
*MESH_FACENORMAL 4 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 3366 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 1125 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 0 -0.160276 0.130236 -0.978442
As you can see here, five triangles share each vertex, but the normal is allways different. So you simply add all normals in one normal and normalize it.
D3DVECTOR normal; // Y and Z are swaped around
normal.x: (-0.124476)+(-0.119393)+(-0.252629)+(-0.303272)+(-0.303272)+(-0.160276)
normal.z: (0.139596)+(0.191704)+(0.179425)+(0.021187)+(0.130236)
normal.y: (-0.982353)+(-0.974163)+(-0.950781)+(-0.952668)+(-0.978442)
Normalize(normal);
That''s all...
float* ptr; // Pointer to vertex
WORD num=0,max=0; // Just counters
while (strcmp(data,"*MESH_NORMALS") // feof(File)) fscanf(File,"%s",data);
while (strcmp(data,"}") // feof(File))
{
if (strcmp(data,"*MESH_VERTEXNORMAL")==0)
{
fscanf(File,"%i %f %f %f",&num,&x,&z,&y);
ptr[num*8+3]+=x; // += !!
ptr[num*8+4]+=y; // += !!
ptr[num*8+5]+=z; // += !!
if (num>max) max=num;
}
fscanf(File,"%s",data);
}
if (feof(File)) return;
for (num=0; num{
a.dvX=ptr[3]; a.dvY=ptr[4]; a.dvZ=ptr[5]; // Read normal
a=Normalize(a); // Normalize normal
ptr[3]=a.dvX; ptr[4]=a.dvY; ptr[5]=a.dvZ; // Write normal
ptr+=8;
}
And here''s a part of ASE file for example:
*MESH_NORMALS {
*MESH_FACENORMAL 0 -0.134989 0.155329 -0.978596
*MESH_VERTEXNORMAL 3362 -0.096996 0.131464 -0.986564
*MESH_VERTEXNORMAL 1124 -0.110075 0.154374 -0.981861
*MESH_VERTEXNORMAL 0 -0.124476 0.139596 -0.982353
*MESH_FACENORMAL 1 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 3363 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 1128 -0.119393 0.191704 -0.974163
*MESH_VERTEXNORMAL 0 -0.119393 0.191704 -0.974163
*MESH_FACENORMAL 2 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 3364 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 1131 -0.252629 0.179425 -0.950781
*MESH_VERTEXNORMAL 0 -0.252629 0.179425 -0.950781
*MESH_FACENORMAL 3 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 3365 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 1134 -0.303272 0.021187 -0.952668
*MESH_VERTEXNORMAL 0 -0.303272 0.021187 -0.952668
*MESH_FACENORMAL 4 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 3366 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 1125 -0.160276 0.130236 -0.978442
*MESH_VERTEXNORMAL 0 -0.160276 0.130236 -0.978442
As you can see here, five triangles share each vertex, but the normal is allways different. So you simply add all normals in one normal and normalize it.
D3DVECTOR normal; // Y and Z are swaped around
normal.x: (-0.124476)+(-0.119393)+(-0.252629)+(-0.303272)+(-0.303272)+(-0.160276)
normal.z: (0.139596)+(0.191704)+(0.179425)+(0.021187)+(0.130236)
normal.y: (-0.982353)+(-0.974163)+(-0.950781)+(-0.952668)+(-0.978442)
Normalize(normal);
That''s all...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement