Archived

This topic is now archived and is closed to further replies.

Zeblar Nagrim

Normals

Recommended Posts

Hello! My d3d8 normals for my 3ds object are so fu*k*ng wrong! Here is some code:
  

//-----------------------------------------------------------------------------

// Name: CreateVertexBuffer()

// Desc: Create vertexbuffer from vertex and texcoord arrarys

//-----------------------------------------------------------------------------

bool CD3DMesh::CreateVertexBuffer(LPDIRECT3DDEVICE8 device, int NumVertices, float *pfVertices, float *pfTexcoords)
{
    m_iNumFaces = NumVertices/3;

    if(FAILED(device->CreateVertexBuffer( NumVertices*sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_lpVertexBuffer ))) return false;

    CUSTOMVERTEX *pVertices;
    if(FAILED(m_lpVertexBuffer->Lock( 0, 0, (BYTE**)&pVertices, 0 ))) return false;

    float *pfNormals = new float[NumVertices*3];
    GenerateFaceNormals(NumVertices, pfVertices, pfNormals);

    for(int i=0; i<NumVertices; i++)
    {
        pVertices[i].p.x = pfVertices[i*3];
        pVertices[i].p.y = pfVertices[i*3+1];
        pVertices[i].p.z = pfVertices[i*3+2];

        pVertices[i].n.x = pfNormals[i*3];
        pVertices[i].n.y = pfNormals[i*3+1];
        pVertices[i].n.z = pfNormals[i*3+2];

        if(pfTexcoords)
        {
            pVertices[i].tu = pfTexcoords[i*2];
            pVertices[i].tv = pfTexcoords[i*2+1];
        }
        else
        {
            pVertices[i].tu = 0.0f;
            pVertices[i].tv = 0.0f;
        }
    }

    m_lpVertexBuffer->Unlock();

    delete[] pfNormals;

    return true;
}

//-----------------------------------------------------------------------------

// Name: GenerateNormals()

// Desc: 

//-----------------------------------------------------------------------------

void CD3DMesh::GenerateFaceNormals(int NumVertex, float *pdVertexData, float *pfNormalData)
{
    D3DXVECTOR3 vertex1, vertex2, vertex3, normal, vector1, vector2;

    for(int i=0; i<NumVertex/3; i++)
    {
        vertex1 = D3DXVECTOR3(pdVertexData[i*9+0], pdVertexData[i*9+1] , pdVertexData[i*9+2]);
        vertex2 = D3DXVECTOR3(pdVertexData[i*9+3], pdVertexData[i*9+4] , pdVertexData[i*9+5]);
        vertex3 = D3DXVECTOR3(pdVertexData[i*9+6], pdVertexData[i*9+7] , pdVertexData[i*9+8]);

        vector1 = vertex2 - vertex1;
        vector2 = vertex3 - vertex1;

        D3DXVec3Cross(&normal, &vector1, &vector2);
        D3DXVec3Normalize(&normal, &normal);
        normal = -normal;

        pfNormalData[i*9+0] = normal.x;
        pfNormalData[i*9+1] = normal.x;
        pfNormalData[i*9+2] = normal.x;

        pfNormalData[i*9+3] = normal.y;
        pfNormalData[i*9+4] = normal.y;
        pfNormalData[i*9+5] = normal.y;

        pfNormalData[i*9+6] = normal.z;
        pfNormalData[i*9+7] = normal.z;
        pfNormalData[i*9+8] = normal.z;
    }
}

  
Please! If somebody can see what I have done wrong this time, please respond.

Share this post


Link to post
Share on other sites
From DX8SDK Help:

D3DXVECTOR3* D3DXVec3Normalize(
D3DXVECTOR3* pOut,
CONST D3DXVECTOR3* pV
);

Parameters

pOut
[in, out] Pointer to the D3DXVECTOR3 structure that is the result of the operation.

pV
[in] Pointer to the source D3DXVECTOR3 structure.

You're using the same pointers for the pOut and pV parameters:

D3DXVec3Normalize(&normal, &normal);

Instead i think you should use 2 different D3DXVECTOR3 structures:

D3DXVECTOR3 vertex1, vertex2, vertex3, normal, vector1, vector2;

Should be (at least i think so):

D3DXVECTOR3 vertex1, vertex2, vertex3, normalR, normalS, vector1, vector2;

Where normalR is the result of the operation and normalS the source for the function

And
D3DXVec3Normalize(&normal, &normal);

should be: D3DXVec3Normalize(&normalR, &normalS);

Of course, as a result of this,
pfNormalData[i*9+0] = normal.x;

should be changed to:
pfNormalData[i*9+0] = normalR.x;

Try this, though i don't know for sure if this is the problem.

Greetz

Sephiroth The Third

Edited by - sephiroth03 on July 27, 2001 3:27:07 PM

Share this post


Link to post
Share on other sites
If the solution before didn't work, maybe this is the solution:
The "D3DXVECTOR3 normal" structure hasn't been filled out
(x,y,z values etc.). Maybe you should do that, BEFORE using

D3DXVec3Cross(&normal, &vector1, &vector2);

And

D3DXVec3Normalize(&normal, &normal);

Greetz,

Sephiroth The Third

Edited by - sephiroth03 on July 27, 2001 3:28:50 PM

Share this post


Link to post
Share on other sites
Dunnu, but in GenerateFaceNormals() shouldn't the normals be stored in the x, y and z order, i.e.
  
pfNormalData[i*9+0] = normal.x;
pfNormalData[i*9+1] = normal.y;
pfNormalData[i*9+2] = normal.z;
pfNormalData[i*9+3] = normal.x;
pfNormalData[i*9+4] = normal.y;
pfNormalData[i*9+5] = normal.z;
pfNormalData[i*9+6] = normal.x;
pfNormalData[i*9+7] = normal.y;
pfNormalData[i*9+8] = normal.z;


BTW: you can use the same var as input and output in the D3DXVec* function - see the docs/headers.

Bjørn.

Edited by - Boki on July 27, 2001 3:34:28 PM
Finally found the right code tag

Edited by - Boki on July 27, 2001 3:40:29 PM

Share this post


Link to post
Share on other sites