Multiple Light Sources with GL - c++

I am trying to do something basic with GL. However I got a problem with the lights. I have a cube in the viewport and when I put GL_LIGHT0 at some point, it shades the cube without any problem. But GL_LIGHT1 does not act normally. When I disable light0 and put GL_LIGHT1 at the same location of light0, it just gives a different color to the shape. No shading, no lighting.
What is the problem here?

The default values for GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR with GL_LIGHT0 is (1,1,1), while it is (0,0,0) for GL_LIGHT1 to GL_LIGHT6.
If you set these values using glLight*, you should see consistent behaviour.

Related

Minimum openGL initializations

I am trying to learn OpenGL and currently trying to use it with Qt. The thing I am trying to do is to load frames from a video file into a texture and then display it on the screen. The only thing I might try and do later is to enable zoom functionality on this. Keeping that in mind, what is the minimum OpenGL initializations that I need to use to maximize performance. More specifically, do I need to diasable certain features, so that I can maximize performance for my very limited needs at the moment.
For example, the Qt tutorial on OpenGL initializes it as:
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
I think I should safely be able to disable most of these but am not sure as I am still trying to figure out what most of these things will actually do.
glEnable(GL_DEPTH_TEST);
Enables depth testing which prevents triangles from overwriting others when they should be hidden behind others. Leave enabled to avoid the artifacts.
glEnable(GL_CULL_FACE);
Prevents triangles from being drawn when they are facing away from you. Leave enabled for better performance.
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
All these are part of the deprecated fixed function pipeline and can be removed and emulated with shaders.
If you're just starting to learn, here's additional info:
glEnable(GL_DEPTH_TEST)
Leave it only if you're planning to draw 3D shapes
glEnable(GL_CULL_FACE)
Remove it until you get used to the concept of clockwise, and counter-clockwise importance of drawing the points. otherwise you might fail to see your first rendered shapes, because they could be culled. First draw them without this, then enable it and experiment with clockwise and counter-clockwise drawing.
glShadeModel(GL_SMOOTH)
Leave that. It simply instructs the renderer to mix different colors and smooth them along the shapes. If you put different colors to different points, they'll get interpolated smoothly.
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
If you're past the point of rendering simple shapes, use these to experiment with lighting. You should also provide normals to your geometry, in order to see the effects. If you're really in the beginning, comment those out until you're more familiar with drawing shapes.
Good luck!

Creating helicopter spot light through C++ openGL

I have created a helicopter that moves around a track, now where I'm having trouble is that we're supposed to have 2 light sources in the game, one that replicates the sun ( which i've done it wasnt too hard) and the second is a spotlight located on the actual helicopter itself. This is essentially what i have so far:
GLfloat specular2[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat position2[] = { vx, vy, vz, 1.0 };
glLightfv(GL_LIGHT2, GL_DIFFUSE, ambientLight);
glLightfv(GL_LIGHT2, GL_SPECULAR, specular2);
glLightfv(GL_LIGHT2, GL_POSITION, position2);
glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 60.0f);
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 100.0f);
glEnable(GL_LIGHT2);
But, it doesn't do anything that I notice. I've done a great deal of research on lights and i just cant seem to figure it out. By the way ( vx,vy,vz) is the current position i want the light to be in infront of the helicopter.
The value you use for GL_SPOT_EXPONENT is very large:
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 100.0f);
This controls how quickly the intensity drops off from the center of the cone. For example, with this value of 100.0, the intensity would be down to about 20% at angle of just 10 degrees off the cone center. You may want to try a much smaller value to see if it gives you a better result.
While the vales are not shown, this call looks suspicious just from the naming. It's using a variable named ambientLight to set the diffuse component of the light source:
glLightfv(GL_LIGHT2, GL_DIFFUSE, ambientLight);
Also, you do not specify a direction for the spot light. The default is (0.0, 0.0, -1.0). Unless there is anything in the negative z-direction from the helicopter, the spot light will not illuminate anything. You will need to specify GL_SPOT_DIRECTION if the default is not what you want.
It's also important to be aware that the current modelview transformation is applied when a light source position and direction are specified. So if your helicopter is transformed, it's easiest to specify the position/direction of the spotlight while the transformation is already set up, and before making the draw calls.

can't properly disable gl color material

I have scene with lighting that works fine. I want to addd a sky box that will fade away, so i am using
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
along with glColor4f to do this and it works fine. But for the fade to work i need to enable GL_COLOR_MATERIAL which completly gets rid of my lighting effects. I tried sandwiching the sky box part
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
(..light details..)
glEnable(GL_COLOR_MATERIAL);
(drawSkyBox)|
glDisable(GL_COLOR_MATERIAL);
(draw rest of scene)
but that just lets the fade work and still doesn't show my lighting. Oddly enough if do
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
(..light details..)
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_COLOR_MATERIAL);
(drawSkyBox)
(draw rest of scene)
I lose the fade and my lighting effects. Am I using GL_COLOR_MATERIAL properly? If I enable and disable right away, shouldn't there be no effect, leaving my lighting intact?
A sky box probably shouldn't be affected by lighting. There's nothing like a big shiny specularity on your sky and clouds to make it look very strange. So it makes sense to disable lighting while you render that. If lighting is off, the vertices just take whatever color you assign them (using glColor).
If lighting is on, the vertices will take on a combination of the lights' colors and the material properties. You can set the ambient, diffuse, and specular color filters separately for each vertex and they'll be multiplied with the associated colors from the lights along with some other math to take into account direction and fall-off. If, as is often the case, you're only changing the ambient and diffuse colors and you want them to be the same because you've already set the ambient and diffuse properties of your light source to both be white with the ambient significantly dimmer than the diffuse, then you can enable COLOR_MATERIAL and then setting glColor() is the same as calling glMaterial with GL_AMBIENT_AND_DIFFUSE.

No spot of light on cube

I have made three sources of light and one cube
I don't see a spot of light on faces. It's look like entire polygon is lit.
And i don't know is this posible and cube need more polygons or mayby light settings are bad.
Settings i use.
glShadeModel(GL_SMOOTH);
glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 150.0f);
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 15.0f);
Remember that the fixed-function lighting equation is only evaluated at the vertices of a triangle and interpolated across the fragment. No per-pixel lighting unless you get creative with GL_DOT3_RGB textures.
Therefore if you want to see a nice spotlight highlight on your cube you'll need to subdivide your cube faces so that they're closer to pixel-sized:
EDIT: Also remember to pass in reasonable per-vertex normals. Lighting doesn't work too well without them :)

Lighting issues in OpenGL

I have a triangle mesh that has no texture, but a set color (sort of blue) and alpha (0.7f). This mesh is run time generated and the normals are correct. I find that with lighting on, the color of my object changes as it moves around the level. Also, the lighting doesn't look right. When I draw this object, this is the code:
glEnable( GL_COLOR_MATERIAL );
float matColor[] = { cur->GetRed(), cur->GetGreen(), cur->GetBlue(), cur->GetAlpha() };
float white[] = { 0.3f, 0.3f, 0.3f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matColor);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
Another odd thing I noticed is that the lighting fails, when I disable GL_FRONT_AND_BACK and use just GL_FRONT or GL_BACK.
Here is my lighting setup (done once at beginning of renderer):
m_lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
m_lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
m_lightPosition[] = { 0.0f, 1200.0f, 0.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
EDIT: I've done a lot to make the normals "more" correct (since I am generating the surface myself), but the objects color still changes depending where it is. Why is this? Does openGL have some special environment blending I don't know about?
EDIT: Turns out the color changing was because a previous texture was on the texture stack, and even though it wasn't being drawn, glMaterialfv was blending with it.
If your lighting fails when GL_FRONT_AND_BACK is disabled it's possible that your normals are flipped.
Could you post the code that initializes OpenGL? You're saying that all other meshes are drawn perfectly? Are you rendering them simultanously?
#response to stusmith:
Z-testing won't help you with transparent triangles, you'll need per-triangle alpha sorting too. If you have an object that at any time could have overlapping triangles facing the camera (a concave object) you must draw the farthest triangles first to ensure blending is performed correctly, since Z-testing doesn't take transparency into account.
Consider these two overlapping (and transparent) triangles and think about what happens when that little overlapped region is drawn, with or without Z-testing. You'll probably reach the conclusion that the drawing order does, in fact, matter. Transparency sucks :P
/\ /\
/ \ / \
/ \/ \
/ /\ \
/_____/__\_____\
I'm not convinced that this is your problem, but alpha sorting is something you need to take into account when dealing with partly transparent objects.
Turns out the color changing was because a previous texture was on the texture stack, and even though it wasn't being drawn, glMaterialfv was blending with it.
If your triangles are alpha-blended, won't you have to sort your faces by z-order from the camera? Otherwise you could be rendering a face at the back of the object on top of a face at the front.
#sebastion:
multiple draw calls, each object gets a glDrawArrays. some are textured, some colored, all with normals. gl init code is:
glMatrixMode(GL_MODELVIEW);
// Vertices!
glEnableClientState(GL_VERTEX_ARRAY);
// Depth func
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_LESS );
// Enable alpha blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
// Culling
glDisable( GL_CULL_FACE );
// Smooth Shading
glShadeModel(GL_SMOOTH);
m_glSetupDone = true;
after this i have some camera set up, but thats completely standard, projection mode, frustum, modelview, look at, translate.
Are you sure your normals are normalized?
If not and you are specifying normals via glNormal calls, you could try to let OpenGL do the normalization for you, keep in mind that this should be avoided, but you can test it out:
glEnable(GL_NORMALIZE);
This way you are telling OpenGL to rescale all the normal vectors supplied via glNormal.
I had a transparency issue on my terrain display, slopes would seem transparent when looked from a certain angle. It only happened when lighting was enabled in the shader. Turns out that I had not turned on depth testing, and from a certain angle the terrain was overwritten by other terrain and displaying semi-transparent.
TLDR; check if you have depth testing enabled, having it off may give transparency-like effects when lighting is involved.
https://learnopengl.com/Advanced-OpenGL/Depth-testing