• Advertisement
Sign in to follow this  

Spot light no functioning

This topic is 4614 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I modeled a pool table surface and I'm trying to put some spot light into it but it looks like if every surface has a gradient like so: well, I don't know if I used the correct way to import an X file so it can get proper lighting. I someone knows what is the proper way to use a spot light or a point light please let me know. this is my first attepmt to use lights in directx. One more thing the coordinates are in the image and I get in the debug window:
Direct3D9: (ERROR) :Invalid D3DLIGHT type

First-chance exception at 0x7c81eb33 in Billiards.exe: Microsoft C++ exception: long @ 0x0012f3ac.
Direct3D9: (ERROR) :SetLight failed.

thanks.

Share this post


Link to post
Share on other sites
Advertisement
The error is pretty much self-explanatory, you're doing something wrong with your light structure. Try something like:

D3DLIGHT9 light;
ZeroMemory(&light, sizeof(D3DLIGHT9));
light.type = D3DLIGHTTYPE_SPOT;
light.Diffuse.r = light.Diffuse.g = light.Diffuse.b = light.Diffuse.a = 1;
light.Position = D3DXVECTOR3(0, 20, 0);
light.Direction = D3DXVECTOR3(0, -1, 0);
light.Range = 100.0f;
light.Falloff = 1.0f;
light.Attenutation1 = 1.0f;
light.Theta = 60 * D3DX_PI/180.0f;
light.Phi = 90 * D3DX_PI/180.0f;

Share this post


Link to post
Share on other sites
Here is a quick example of how you would create and set up a spotlight:


D3DLIGHT9 m_LightSource;

// one-time initialization of the light
D3DXVECTOR3 LightPos(5.0f, 0.0f, -15.0f);
D3DXVECTOR3 LightDir(0.0f, 0.0f, 1.0f);

ZeroMemory( &m_LightSource, sizeof( m_LightSource ) );

m_LightSource.Type = D3DLIGHT_SPOT;
m_LightSource.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 0.5f );
m_LightSource.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 0.5f );
m_LightSource.Specular = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 0.5f );
m_LightSource.Direction = LightDir;
m_LightSource.Position = LightPos;
m_LightSource.Range = 20.0f;
m_LightSource.Falloff = 1.0f;
m_LightSource.Attenuation0 = 1.0f;
m_LightSource.Attenuation1 = 0.0f;
m_LightSource.Attenuation2 = 0.0f;
m_LightSource.Theta = 0.4f;
m_LightSource.Phi = 0.9f;



Then, after everytime you reset your device, add this:


// Add the light to the scene
pd3dDevice->SetLight( 0, &m_LightSource );
pd3dDevice->LightEnable( 0, true );

// Don't forget to enable specular lighting if you're going to use it
pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, true );
// You may also want to add this if you are getting weird results --
// your normals may becoming non-normal during transformations
pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, true );



I'm not sure what exactly your problem is, but that's really all there is to it. Hope this helps some.

Share this post


Link to post
Share on other sites
Well, I tryed both of you suggestion, the first one was pretty much what I had and the second one I didn't have this part

pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, true );
pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, true );

but anyway, It didn't work and I still get the same error... do you think is something wrong with the X file.

Maybe this happens because is a double sided mesh? I really don't know. the other thing I there a problem if I do this.


struct LIGHT
{
D3DLIGHT9 g_light;
float g_fLightPositionX;
float g_fLightPositionY;
float g_fLightPositionZ;
float g_fLightDirectionX;
float g_fLightDirectionY;
float g_fLightDirectionZ;
float g_fAttenuation0;
float g_fAttenuation1;
float g_fAttenuation2;
float g_fRange;
float g_fTheta;
float g_fPhi;
float g_fFalloff;
bool ON;
int index;
LPCTSTR Type;
};

class Lights
{
public:
void initLighting(LIGHT &light );
void SetLight(LIGHT &light);
};

void Lights::initLighting (LIGHT &light)
{
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
g_pd3dDevice->LightEnable( light.index , TRUE );

// Set up our spot light...
ZeroMemory( &light.g_light, sizeof(D3DLIGHT9) );
light.g_light.Diffuse.r = 1.0f;
light.g_light.Diffuse.g = 1.0f;
light.g_light.Diffuse.b = 1.0f;
light.g_light.Diffuse.a = 1.0f;
light.g_light.Position = D3DXVECTOR3( light.g_fLightPositionX , light.g_fLightPositionY, light.g_fLightPositionZ );
light.g_light.Direction = D3DXVECTOR3( light.g_fLightDirectionX, light.g_fLightDirectionY, light.g_fLightDirectionZ );
light.g_light.Attenuation0 = light.g_fAttenuation0;
light.g_light.Attenuation1 = light.g_fAttenuation1;
light.g_light.Attenuation2 = light.g_fAttenuation2;
light.g_light.Range = light.g_fRange;
light.g_light.Theta = light.g_fTheta;
light.g_light.Phi = light.g_fPhi;
light.g_light.Falloff = light.g_fFalloff;
g_pd3dDevice->SetLight( light.index , &light.g_light );

// Enable some dim, grey ambient lighting...
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT,
D3DCOLOR_COLORVALUE( 0.25, 0.25, 0.25, 1.0 ) );
}



void Lights::SetLight(LIGHT &light)
{
//
// Set up our light and apply a material...
//
if (light.Type == "spot")light.g_light.Type = D3DLIGHT_SPOT;
if (light.Type == "point")light.g_light.Type = D3DLIGHT_POINT;
light.g_light.Diffuse.r = light.g_light.Diffuse.g = light.g_light.Diffuse.b = light.g_light.Diffuse.a = 1.0f;
light.g_light.Position.y = light.g_fLightPositionY;
light.g_light.Direction.x = light.g_fLightDirectionX;
light.g_light.Attenuation0 = light.g_fAttenuation0;
light.g_light.Attenuation1 = light.g_fAttenuation1;
light.g_light.Attenuation2 = light.g_fAttenuation2;
light.g_light.Range = light.g_fRange;
light.g_light.Theta = light.g_fTheta;
light.g_light.Phi = light.g_fPhi;
light.g_light.Falloff = light.g_fFalloff;

g_pd3dDevice->SetLight( light.index , &light.g_light );
g_pd3dDevice->LightEnable( light.index , light.ON );

// Don't forget to enable specular lighting if you're going to use it
g_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, true );
// You may also want to add this if you are getting weird results --
// your normals may becoming non-normal during transformations
g_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, true );
}



then I just call the class with the structure of the light I'm using...


Share this post


Link to post
Share on other sites
One potential problem I see is if you are calling initLighting before setLight:
...
void Lights::initLighting (LIGHT &light)
{
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
g_pd3dDevice->LightEnable( light.index , TRUE );

...

If this is called before your setLight function, you are trying to enable a light that has not yet been added to the device.

Also, there is really no reason to create a struct that holds all of those values in addition to the D3DLIGHT9 struct. The D3DLIGHT9 struct itself holds those values. The only values that it does not hold are on/off and the index, so in that case it might be appropriate to make a struct like this:

struct LIGHT
{
D3DLIGHT9 light;
bool on;
int index;
};

Share this post


Link to post
Share on other sites
Are you sure your problem is the light source itself? It seems to me your normals are screwed. Looks as they´re pointing in the wrong direction.

Share this post


Link to post
Share on other sites
What are the values you are initialising the light with? From your error message it seems that neither type is being set in your SetLight method. If neither of these are true:

if (light.Type == "spot")light.g_light.Type = D3DLIGHT_SPOT;
if (light.Type == "point")light.g_light.Type = D3DLIGHT_POINT;

then you will be passing zero in as your light type which might explain the invalid light type message you have been getting.

Share this post


Link to post
Share on other sites
Quote:
Original post by superpig
That's an interesting way to compare strings...


Thats what I thought but when testing it with visual studio 2003 the damn thing kept replacing the strings as they are constants and accepted it, still I agree I wouldn't be ton it working.

Share this post


Link to post
Share on other sites
...
if (light.Type == "spot")light.g_light.Type = D3DLIGHT_SPOT;
if (light.Type == "point")light.g_light.Type = D3DLIGHT_POINT;
...

Are you sure that the type is getting set? If both of these fail, the type will not be set and thus give the error invalid D3DLIGHT type

Share this post


Link to post
Share on other sites
If I set a break point, in that place, the value is passed. I really don't know what is wrong. The problem with the string comparison is just like you said. It didn't pass the value. Maybe is not passing the rest of the values, but I'm setting again in every frame so I don't know what could be the problem really. I think is maybe the faces... I'm remodelling the table and will let you guys know what has happened...

I just read something in the debug window... which can clear things up...

'Billiards.exe': Loaded 'C:\WINDOWS\system32\mslbui.dll', No symbols loaded.
Detected memory leaks!
Dumping objects ->
{62} normal block at 0x00EF5D98, 24 bytes long.
Data: < ` > 00 00 00 00 00 00 00 00 00 00 00 00 60 A3 7F 01
{61} normal block at 0x00EF5BC0, 408 bytes long.
Data: < ? ? ?> 00 00 80 3F 00 00 80 3F 00 00 00 00 00 00 80 3F
Object dump complete.

normal block... I suppose that is something with the model.

Share this post


Link to post
Share on other sites
If I set a break point, in that place, the value is passed. I really don't know what is wrong. The problem with the string comparison is just like you said. It didn't pass the value. Maybe is not passing the rest of the values, but I'm setting again in every frame so I don't know what could be the problem really. I think is maybe the faces... I'm remodelling the table and will let you guys know what has happened...

I just read something in the debug window... which can clear things up...

'Billiards.exe': Loaded 'C:\WINDOWS\system32\mslbui.dll', No symbols loaded.
Detected memory leaks!
Dumping objects ->
{62} normal block at 0x00EF5D98, 24 bytes long.
Data: < ` > 00 00 00 00 00 00 00 00 00 00 00 00 60 A3 7F 01
{61} normal block at 0x00EF5BC0, 408 bytes long.
Data: < ? ? ?> 00 00 80 3F 00 00 80 3F 00 00 00 00 00 00 80 3F
Object dump complete.

normal block... I suppose that is something with the model.

Share this post


Link to post
Share on other sites
Ok guys, I remodeled the table and same thing. This time I only made it single sided mesh so I knew what was happening and all of the faces are inverted. Is there another exporter for blender.

Share this post


Link to post
Share on other sites
I suggest you completely start over from scratch and look at an online tutorial / sample project as you go. Copy the source exactly if you have to. Use someone elses model first that you KNOW will work.

When you get it working correctly, try swapping in your own model and see if it still works correctly. When you can do that, start changing it around into your own classes/framework.

Share this post


Link to post
Share on other sites
Ok so I followed advice and this is what I have comed up... I checked the mesh on the mesh viewer and it came out perfectly so I know that the mesh is not the problem. I tryied out a couple of things and found out it had to do with my projection matrix so I can see everything perfectly. Now for the main question the spot light. It's not happening. The wierd part is that it only lights up the object when is under it and looking away. example position -2 in "y" and direction -1 in "y".
Any suggestion on why is this happening.

Share this post


Link to post
Share on other sites
Perhpaps your normals are inverted. Try multiplying your normals by -1 and see if the light shows up.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement