Jump to content

  • Log In with Google      Sign In   
  • Create Account


Strange lighting issues


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 CatmanFS   Members   -  Reputation: 187

Like
0Likes
Like

Posted 10 December 2013 - 12:47 PM

I was working with a default picker for creating light objects. You would type something like:

 

LIGHT light0(AMBIENT);

 

and it would create an ambient light based off of preset values, and handle the rest of the code elsewhere.

 

The problem is when I was changing up the input variables for the lightfv( GL_AMBIENCE, float* ambience)

I ran into a problem.

 

The scene lighting would only work if the viewing position was somewhere near the origin. It didn't make sence. I messed with attenuation, trying to lower it, raise, it, remove it completely, and it didnt seem to have an effect on this issue.

 

Light just stops working once the camera moves more than just a few units from the origin.

 

Now if you know of this to be some sort of aspect of OpenGL and I'm just missing a line of code somewhere, let me know. if we're not so lucky keep reading for a few samples of the code and a the details of when this started happening.

 

 

Now the code for the light is something liek this

 

class LIGHT

{

 

vector3 pos;

color ambience;

color diffuse;

color specular

 

float shine;

float attenuation;

 

LIGHT(LIGHT_PRESET);

void Enable()

void Update()

 

};

 

I'm using a color code like this:

 

struct color

{

      float r, g, b, a;

      void Set(float, float, float);

      float* pFloat(); // this returns an array of 4 numbers like the ones the light needs as input

};

 

float* color::pFloat()

{

       float floater[] = {r, g, b, a};

      return floater;

};

 

the vector code for light positioning works similarly

 

struct vector3

{

     float x, y, z;

     void Set(float, float, float);

     float* pFloat();

};

 

float* color:pFloat()

{

       float floater[] = {x, y, z};

       return floater;

};

 

 

And the light takes those values as such

 

   glLightfv(ID, GL_POSITION, position.pFloat());
   glLightfv(ID, GL_DIFFUSE, diffuse.pFloat());   
   glLightfv(ID, GL_AMBIENT, ambient.pFloat()); 

 

The picker works, there was no problem there, but when I tried to change from setting the color values from this:

 

color[0] = .5;

color[1] = .2;

color[2] = .7;

 

position[0] = 10;

position[1] = 15;

position[0] = 10;

 

to something better like this

 

color.Set(.5, .2, .7);

position.Set(10, 15, 10);

 

The structs for color and position have functions to easily set themselves, and also produce the float* number array that openGl likes to use for it's light and position color values.

 

I got this working, and I've used this concept many times, but I ran into this other lighting problem that I just don't understand.

 

At first it seemed like it wasn't getting the correct positional values and just placing the lights at some far distance place,

then i noticed that it was placing them directly at the center, inside the test object I'm using to work with the lighting.

 

I output the values that would be directly sent into the openGl position input, and found them to be fine.

 

Does anyone have any idea why this is happening?

 



Sponsor:

#2 CatmanFS   Members   -  Reputation: 187

Like
0Likes
Like

Posted 10 December 2013 - 05:58 PM

To help I uploaded a video of this effect.

 



#3 Brother Bob   Moderators   -  Reputation: 7744

Like
1Likes
Like

Posted 10 December 2013 - 06:22 PM

I don't know if it is related to your problem or not, but if this is C++ code then your pFloat() functions are wrong. You are returning the address of a local array which becomes invalid as soon as the function has returned, so you are passing an invalid pointer to OpenGL. You should fix that whether it is related to your lighting problem or not.



#4 L. Spiro   Crossbones+   -  Reputation: 11933

Like
1Likes
Like

Posted 10 December 2013 - 06:25 PM

and also produce the float* number array that openGl likes to use for it's light and position color values.

Except that it does so by taking the address of a temporary.
 
It should be:
float* vector3::pFloat() {
    return reinterpret_cast<float *>(this);
}
Same with colors.

Also, one of the many reasons you should never touch fixed-function OpenGL is because it pre-multiplies light positions (for one) with the model-view matrix when you set them, forcing you to update them carefully (set the model-view matrix to identity first) each frame.


L. Spiro

Edited by L. Spiro, 10 December 2013 - 06:30 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#5 CatmanFS   Members   -  Reputation: 187

Like
0Likes
Like

Posted 10 December 2013 - 06:38 PM

I changed the update light code to this:

 

    float amb[] = {5, 5, 5};
    glLightfv(light->ID, GL_POSITION, amb );

 

and excluded this:
    //glLightfv(light->ID, GL_POSITION, light->position.pFloat());

 

and it works. The problem is that I need to pull the info from the *light that the update function uses as input

 

is there something wrong with using:

 

UpdateLight( LIGHT *light)

 

and the pulling the info using:

 

light->position.pFloat();   // pFloat() returns a pointer to an array of { x, y, z} stored in the vector3

 

Could be that since it uses a pointer to the light struct, and then a pointer to the vector3 struct that somehow the actual data struct gets lost.

I'm still confused as to why the light only works near the origin with this implementation.

 

Any thoughts?



#6 CatmanFS   Members   -  Reputation: 187

Like
1Likes
Like

Posted 10 December 2013 - 06:44 PM

Ahah you saved my life. I'm still a little confused about the matrix multiplying the light positions.

 

Right now, the UpdateAllLights() happens after the modelview matrix has been established.

 

Where would you reccomend that this be placed?



#7 L. Spiro   Crossbones+   -  Reputation: 11933

Like
0Likes
Like

Posted 10 December 2013 - 09:09 PM

is there something wrong with using:
 
UpdateLight( LIGHT *light)
 
and the pulling the info using:
 
light->position.pFloat();   // pFloat() returns a pointer to an array of { x, y, z} stored in the vector3

Yes there is something wrong with it. Brother Bob and I both just told you you are returning an address of a temporary.
Meaning you are not returning a pointer to a valid vector3, you are returning a pointer to garbage. The value to which it points is on the stack and will be overwritten on every function call, possibly even on function exit (it is undefined data on exit so the compiler can do anything it wants).
Make a method and pass the return value as a pointer of type GLfloat. Fill in the values on that pointer and return. Your method of overloading operators simply does not work.


Where would you reccomend that this be placed?

Somewhere just prior to rendering with a given camera.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#8 CatmanFS   Members   -  Reputation: 187

Like
0Likes
Like

Posted 10 December 2013 - 09:58 PM

I had started typing that before you had replied. Thanks again for the help. The reinterpret cast thing is new to me. I've been doing all of that manually, and it's been a real pain. Most of the C++  books I have are >10 years old, and they don't go into alot of detail about stuff like that. Mostly strings and array pointers. I'll do a little research into the methods of overloading operators and such. Thanks again for the help.

 

Got another question. i've got 3 lights, with ambient and diffuse values set around .8 -> .9 and the scene is very dark looking. There's light, but it's not really like the lighting I'm used to. I tried to bump the ambient values up to 10 and it didn't seem to have an effect. Any ideas?






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS