Jump to content
  • Advertisement
Sign in to follow this  
mvtapia

Spot light no functioning

This topic is 4790 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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!