I want to move my light source in my OpenGL-Scene, which is working. But to actually I want to see thee light source as well.
How can I do this?
...
glPushMatrix();
GLfloat lightPos[] = {0, 0, 200, 1};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
GLfloat ambientLight[] = { 0.2, 0.2, 0.2, 1.0};
GLfloat lightColor[] = { 0.5, 0.5, 0.5, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor);
glutSolidSphere(5,50,50);
glPopMatrix();
...
A light source is not a visible object, per se. If you want to "see" a light, you have to place some object at the position that your light is. Maybe use a sphere, a sprite, an arrow (pointing in the direction the light is pointing in, if it's a directional light), etc.
Related
I have this image
Is there a way to achieve brighter look of the light without editing specular material part of the code?
This is my current code:
void drawTeapot() {
GLfloat mat_diffuse[] = {0.2, 1.0, 0.8, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat mat_shininess[] = {128.0};
GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};
GLfloat light_position[] = {1.1, 1.1, 1.0, 1.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT1, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_SPECULAR, mat_specular);
glLightfv(GL_LIGHT1, GL_SHININESS, mat_shininess);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glutSolidTeapot(0.5);
}
I have to use GL_LIGHT1 because there is another function that reacts to mouse clicks and turns that light on and off. Therefore, I can't have the specular on the object before the light turns on. It has to remain matte, sort of. As you can see, shininess is on max, specular also, but it's not really what I'm going for. I basically want it to be tiny bit bigger that it is now, more dispersed.
I can't change any object color when lighting is enabled.
This is my init function (the part of the light and material):
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
GLfloat light_ambient[] = {0.5, 0.5, 0.5, 1.0};
GLfloat light_diffuse[] = {0.0, 0.5, 0.5, 1.0};
GLfloat light_specular[] = {0.0, 0.0, 0.5, 1.0};
GLfloat light_position[]={0, -1.0, 0, 0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Each object has a vector of colors. This is how I draw my objects:
float mat_a[] = {0.0, 0.0, 0.0, 1.0};
float mat_d[] = {0.0, 0.0, 0.0, 1.0};
float mat_s[] = {0.0, 0.0, 0.0, 1.0};
...
colors_vect = some_object->getColor();
glDisable(GL_COLOR_MATERIAL);
mat_a[0] = colors_vect.at(0);
mat_a[1] = colors_vect.at(1);
mat_a[2] = colors_vect.at(2);
mat_d[0] = colors_vect.at(3); //The values are correct.
mat_d[1] = colors_vect.at(4);
mat_d[2] = colors_vect.at(5);
mat_s[0] = colors_vect.at(6);
mat_s[1] = colors_vect.at(7);
mat_s[2] = colors_vect.at(8);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_a);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_d);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_s);
glEnable(GL_COLOR_MATERIAL);
glBegin(GL_POLYGON);
...
This code doesn't work. I tried to give the mat some random values and still nothing changes.
What am I doing wrong? Any help would be appreciated!
Your problem is caused by this line:
glEnable(GL_COLOR_MATERIAL);
This enables functionality that allows material properties to track the current color, which is the color set with regular glColor() calls. If this is enabled, glColorMaterial() controls which parts of the material parameters track the current color. The default is GL_AMBIENT_AND_DIFFUSE, which means that the current color is used for the ambient and diffuse material parameters.
You need to make a choice about how you want to update your material properties:
If you need to change colors very frequently, it can be most efficient to enable GL_COLOR_MATERIAL, and use glColor() to update the material properties.
You can use glColorMaterialfv(), which gives you more control, and e.g. allows you to set different colors for ambient and diffuse. For this approach, you need to keep GL_COLOR_MATERIAL disabled.
You used a mix of these two, where you set the material properties with glColorMaterialfv(), but then also enabled GL_COLOR_MATERIAL. This means that the ambient and diffuse material properties you set are not used. Instead the current color is used for those two properties. These properties would then change any time you call glColor(). If you never call glColor(), they would use the default value for the current color, which is white (1.0, 1.0, 1.0, 1.0).
The lighting doesn't work, the object appears with solid color. The color itself changes with the material or lighting parameters but no shadow or anything just solid grey.
Here's part of the code:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glFrontFace(GL_CCW);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
GLfloat amb[] = {0.6, 0.6, 0.6, 1.0};
GLfloat dif[] = {0.8, 0.8, 0.8, 1.0};
GLfloat spec[] = {0.5, 0.5, 0.5, 1.0};
GLfloat pos[] = {0.0, 0.0, 30.0};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
GLfloat co[4]={0.5, 0.5, 0.5, 0.5};
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, co);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
for(int i=0; i < numofTr; i++)
{
glBegin(GL_TRIANGLES);
glNormal3f(tr[i].v1->n.x, tr[i].v1->n.y, tr[i].v1->n.z);
glVertex3f(tr[i].v1->x, tr[i].v1->y, tr[i].v1->z);
glNormal3f(tr[i].v2->n.x, tr[i].v2->n.y, tr[i].v2->n.z);
glVertex3f(tr[i].v2->x, tr[i].v2->y, tr[i].v2->z);
glNormal3f(tr[i].v3->n.x, tr[i].v3->n.y, tr[i].v3->n.z);
glVertex3f(tr[i].v3->x, tr[i].v3->y, tr[i].v3->z);
glEnd();
}
I don't know what I'm missing, the normals look good when displayed along with the object.
You are using dim light on a gray object. Obviously the result is gray.
If you mean that faces are flat shaded, that's because of glShadeModel(GL_FLAT);. Change it to GL_SMOOTH to enable interpolation.
If the object is in 3D, I think that the fact you are only passing 3 floats as position might be relevant; default value is [0,0,1,0], and the function expects four floats (4th being the W coordinate, which should in most cases be equal to 1, or 0 for lights in infinite distance).
Also double check that the data you give to glVertex and glNormal is correct. When rendering a sphere at 0,0,0, the normal of every vertex is the normalized position of such vertex (only holds for spheres, obviously).
As a side note, this code is obviously outdated, and as a disclaimer I would ditch it alltoghether, if you are only learning, and switch to something that's relatively modern and uses programmable pipeline.
I have a model that needs to be under a spotlight/directional light,
Meaning, I need to switch between the modes (Spotlight and directional).
Here is the code with some explanation:
I can rotate the model / light source with mouse movements so I am using
glRotate and glTranslate for that.
Once the user pressed the 'L' key I'm supposed to switch between the modes.
here is the code for the lightning:
void LightBall::projectLight(void)
{
if(LIGHT == _lightMode){
printf("Entering LIGHT mode\n"); <--- Supposed to be a directional light
glDisable(GL_LIGHT1);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, _light_position);
}
if(SPOT_LIGHT == _lightMode){
printf("Entering SPOTLIGHT mode\n"); <--- Supposed to be a spotlight
glDisable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1, GL_POSITION, _light_position);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 10.0);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,_spotlight_position);
}
}
The problem is I always get the same light mode when switching between them,
Which is the following:
And another example after switching between 2 light modes and still getting same light
source with light source rotation (the small ball):
How can I get the wanted result?
Here are the LIGHT0 & LIGHT1 definitions:
GLfloat light_ambient[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
_light_position[0] = 0.0;
_light_position[1] = 1.0;
_light_position[2] = 0.0;
_light_position[3] = 0.0;
_spotlight_position[0] = 0.0;
_spotlight_position[1] = -1.0;
_spotlight_position[2] = 0.0;
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
Thanks!
Whether a GL light is a directional light or a spotlight depends on the w (4th) component of its position. If the coordinate is 0, it's directional. If nonzero (usually 1), it's a spotlight. You'll have to modify _lightPosition accordingly before calling glLightfv(..., GL_POSITION, ...).
Using OpenGL I am trying to render a simple line between the points p1 and p2, but it doesnt work.
However, I am able to render cubes at these positions.
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash_shiny[] = {50.0};
GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(p1.x, p1.y, p1.z);
glutSolidCube(20);
glLoadIdentity();
glTranslatef(p2.x, p2.y, p2.z);
glutSolidCube(20);
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
I am using the following code for rendering the line. But I cant find the problem why it doesnt get rendered:
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glLoadIdentity();
glColor3f(1,0,0);
glLineWidth(10.0);
glBegin(GL_LINES); //doesnt work with GL_LINE either
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
glEnd();
I assume what happens is that the lines are actually rendered, but there's still a vertex normal set, pointing away from the light source, or being 0. Easy fix: Disable lighting when drawing lines.
While it is possible to "illuminate" lines, the whole operation makes no sense if one assumes the "regular" normal based illumination models. Lines don't have a normal direction, they have a normal plane (or in other words, a line it it's tangent itself).
So the proper way to illuminate a line is by tangent based shading. Fixed function OpenGL can't do it, but it is trivial to implement with a shader.
A couple of suggestions for you, w.r.t your second code snippet:
1) You probably don't need the 'glEnable(GL_COLOR_MATERIAL)', try commenting out that line.
2) You're passing int's to glColor3f(). Try using glColor3f(1.0f, 0.0f, 0.0f); instead.
Also, did you check the line drawing without the cube at the same position? (ie., is it being occluded or not)