Lighting Meshes...

Started by
6 comments, last by Squirell 19 years, 5 months ago
I'm trying to get lighting working for my meshes. I load everything and set the ambient color to 255, 0, 0. However, when I set the texture in my rendering phase it acts like lighting is set to white (255, 255, 255). When I comment out the set texture part it renders it in red like it should. What do I need to do to get the lights to work with textures?

/*Stuff in header
LPDIRECT3DDEVICE9 m_pD3DDevice;
DWORD m_dwNumMaterials;
LPD3DXMESH m_pMesh;
D3DMATERIAL9* m_pMeshMaterials;
LPDIRECT3DTEXTURE9* m_pMeshTextures;
*/

bool CMesh::LoadMesh(LPDIRECT3DDEVICE9 pD3DDevice, LPSTR pFilename)
{
	LPD3DXBUFFER pMaterialsBuffer = NULL;
	LPD3DXMESH pMesh = NULL;	

	m_pD3DDevice = pD3DDevice;
	
	if(FAILED(D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, m_pD3DDevice, NULL, 
                                &pMaterialsBuffer, NULL, &m_dwNumMaterials, &pMesh)))
	{
		m_pMesh = NULL;
		m_pMeshMaterials = NULL;
		m_pMeshTextures = NULL;

		Log->LogError("Mesh '%s' failed to load", pFilename);
		return false;
	}

    D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)pMaterialsBuffer->GetBufferPointer();
    
	//Create two arrays. One to hold the materials and only to hold the textures
	m_pMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials];
    m_pMeshTextures  = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

    for(DWORD i = 0; i < m_dwNumMaterials; i++)
    {
        // Copy the material
        m_pMeshMaterials = matMaterials.MatD3D;

        // Set the ambient color for the material (D3DX does not do this)
		m_pMeshMaterials.Ambient = m_pMeshMaterials.Diffuse;

		// Create the texture
        if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, 
                                            matMaterials.pTextureFilename, 
                                            &m_pMeshTextures)))
        {
            m_pMeshTextures = NULL;
        }
    }

    //We've finished with the material buffer, so release it
    SafeRelease(pMaterialsBuffer);

	
	//Make sure that the normals are setup for our mesh
	pMesh->CloneMeshFVF(D3DXMESH_MANAGED, MESH_D3DFVF_CUSTOMVERTEX, m_pD3DDevice, &m_pMesh);
	SafeRelease(pMesh);

	D3DXComputeNormals(m_pMesh, NULL);
	return true;
}


DWORD CMesh::Render()
{
    m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255, 0, 0));
	if(m_pMesh != NULL)
	{
		for(DWORD i = 0; i < m_dwNumMaterials; i++)
		{
			m_pD3DDevice->SetMaterial(&m_pMeshMaterials);

			//When this line is commented out it renders red
			m_pD3DDevice->SetTexture(0, m_pMeshTextures);

        
			m_pMesh->DrawSubset(i);
		}

		return m_pMesh->GetNumFaces();
	}
	else
	{
		return 0;
	}
}


[Edited by - Squirell on October 25, 2004 11:13:04 AM]
Advertisement
Hope somebody answers you coz i am facing this same problem.
I RuLz tha GamE...

I am not an expert, but are your render states set up correctly? E.g. you need to tell the renderer to take each texel in turn and apply some sort of blending between lighting and texel colour. you tell it to perform a maths op on the pixels.

e.g. use -

pD3Dinterface->SetRenderState(blah...);

How did you set up your material structure?
Have you enabled D3DRS_LIGHTING?
Also, do you have any lights in your scene?

Hope I can help you because in my engine everything works fine.
Yes I've enabled D3DRS_LIGHTING. I have no lights in my scene though. I thought that the ambient light would still affect it though. I'm setting up my materials in the LoadMesh function above.

I'm not doing any sort of blending between lighting and texture colors. Can you be more specific about how to do this?

I think you're missing something like this:
	d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);	d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);	d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);


This tells DX to modulate (mix) the texture color with the diffuse color (which I think includes the ambient color once everything is lit).
Sirob Yes.» - status: Work-O-Rama.
From the SDK:

"Texture-stage state is the first alpha argument for the stage, identified by by D3DTA. The default argument is D3DTA_TEXTURE. If no texture is set for this stage, the default argument is D3DTA_DIFFUSE."

This is about the D3DTSS_ALPHAARG1 type, but I think it would also make sense for them to do the same thing with the Color operation...although it's not stated in the SDK. If they did, then it makes sense. When no texture is set, it passes in D3DTA_DIFFUSE. Then, DirectX uses the Diffuse color in the vertex structure IF lighting is disabled and it uses the result of the lighting operation (based on material and normal only, not diffuse color) if lighting is enabled. So, that explains why you get the proper results with NULL set as the texture.

I wouldn't expect it to work right without a texture applied if normals aren't defined properly, because they are required. I think Sirob has the right idea. I misread your post originally. I thought you said the output was a white mesh, but I just saw that it's just coming out as if the light was white. Sorry if this was too much info.

Chris
Chris ByersMicrosoft DirectX MVP - 2005
Quote:Original post by sirob

I think you're missing something like this:
*** Source Snippet Removed ***

This tells DX to modulate (mix) the texture color with the diffuse color (which I think includes the ambient color once everything is lit).


Yes, it works now thank you so much.

This topic is closed to new replies.

Advertisement