I have loaded an object, and when I draw the object, I set the color to green..
After drawing the object, I draw lines in red.
It all worked out fine. The problem arise when I input lighting properties.
When I create a light source, everything where the light projects becomes white.
Why does the lighting over writes my color? And how do I solve this problem?
Thanks in advance..
The code you have would help in diagnosing the problem. This sounds like a problem with setting up the materials for the items (which define how they interact with the lights).
You may want to look into the glColorMaterial function. The following snippet of code will set this up:
GLfloat mat_specular[] = {0.3, 0.3, 0.3, 1.0};
GLfloat mat_shininess[] = { 10.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
Related
I get triangle vertex data and Normal vector data from a stl file, but when I render it with code like this
for(uint32_t i = 0 ;i < mVertexCnt - 9;){
int z = i/9;
glBegin(GL_TRIANGLES);
glNormal3f(mNorm[3*z], mNorm[3*z+1], mNorm[3*z+2]);
glVertex3f(mVertix[i]/100,mVertix[i+1]/100,mVertix[i+2]/100); //1
glVertex3f(mVertix[i+3]/100,mVertix[i+4]/100,mVertix[i+5]/100); //1
glVertex3f(mVertix[i+6]/100,mVertix[i+7]/100,mVertix[i+8]/100); //1
i += 9;
glEnd();
}
the result is like
I think it is because the because normal vector direction is opposite to light direction.
my question is does OpenGL can handle itself. Ignore this direction issue and show the right light in every direction.
anyone know about it?
The light setting is like this:
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_BACK, GL_SHININESS, mat_shininess);
//灯光设置
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light); //散射光属性
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light); //镜面反射光
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Light_Model_Ambient); //环境光参数
glEnable(GL_LIGHTING); //开关:使用光
glEnable(GL_LIGHT0); //打开0#灯
When the light model should be applied to both sides of a polygon, then you have to enable GL_LIGHT_MODEL_TWO_SIDE (see glLightModel) By default GL_LIGHT_MODEL_TWO_SIDE is 0.
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
But note this does not cause that the best fitting direction normal vector is found magically. It just causes that the normal vector of back facing polygons is inverted. Whether a polygon (triangle) is back face, is determined by the Winding order of the vertices in the projection on the viewport. Whether clockwise or counterclockwise polygons are meant to be front facing, can be set by glFrontFace.
I want to add a Light source to my OpenGl code.
I have added following code to my init function...
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightf(GL_LIGHT0, GL_POSITION,(50.0,0.0,0.0,1.0));
Moreover I have drawn a quad:
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,1.0);
glVertex3f(0.0,0.0,20.0);
glVertex3f(0.0,10.0,20.0);
glVertex3f(10.0,10.0,20.0);
glVertex3f(10.0,0.0,20.0);
glEnd();
But no matter what value I use for the Position,
the lighting doesn't change at all...
glLightf(GL_LIGHT0, GL_POSITION,(50.0,0.0,0.0,1.0));
^^^^^^^^^^^^^^^^^^
(50.0,0.0,0.0,1.0) in this context will evaluate to the last expression in the list (1.0). Probably not what you want.
You need to use a real array and glLightfv() to specify light positions:
GLfloat pos[] = { 50.0, 0.0, 0.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, pos );
I need to draw an object with triangles and a sphere. My object has its own material properties that I define them with glMaterialfv. Sphere is just a sphere with a color. However, some part of my object(it is one of its polygons) is colored with sphere's color. How can I solve this problem?
my object function
void drawObject()
{glDisable(GL_COLOR_MATERIAL);
for(int i=0;i<j;i++)
{ glBegin(GL_TRIANGLES);
glNormal3f(..);
glVertex3f(..);
glNormal3f(..);
glVertex3f(..);
glNormal3f(..);
glVertex3f(..);
GLfloat ambientValues[]={..};
GLfloat specularValues[]={..};
GLfloat diffuseValuse[]={..};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,ambientValues);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,diffuseValues);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,specularValues);
glEnd();
}
}
Two mistakes here: Materials muse be set before the drawing operation. And glMaterialfv is not valid within a glBegin/glEnd block. BTW, you shouldn't use immediate mode (glBegin/glEnd) in the first place. Its use has been discouraged for well over 15 years now.
For the lighting portion of an OpenGL project I'm doing this part for my team at the moment:
Define material properties for the models in Part 1. Make your material definitions easily
replaceable. Specifically, robot components and the remote control unit should be "shiny";
rubble piles should be defuse if various color shades; main platform tiles should be diffuse
gray. Select your own material properties and properly document them for the blocks, bases, factories, etc.
I've only been trying to apply the "shiny" effect on the control unit and it hasn't worked well. I tried putting in some sample lighting since we haven't put in any yet (or at least it's not in the repository) to test it out. The result is that the cube portions of the controller reflected (though way too white, no matter what I tried, the color of the cubes is grey) but not the cylinder antenna. (None of those tests are in the repository since I couldn't commit something that won't work.)
Basically I need help with material properties and setting up some basic lighting to test them (the test lighting is temporary since one of my teammates is working on lighting).
I would really appreciate if someone could help me out with doing this part.
Project info:
Repository for our project (a Visual Studio 2010 Project)
The map/grid lies along the xz plane with y being the height
Everything is done using either glCubes or glut shapes so no normals need to be defined for those, only some of the tiles and the numbers 4 everywhere are done using gl_quads
If I missed anything or if you need more info please ask!
I'll help you with the basics on lightning in OpenGL... first you need to enable and set your lights, so, here is some example:
void setlight(){
//here you set the lights and parameters, example with one light
float LightAmbient[] = { 0.1f, 0.1f, 0.05f, 1.0f };
float LightEmission[] = { 1.0f, 1.0f, 0.8f, 1.0f };
float LightDiffuse[] = { 1.0f, 1.0f, 0.8f, 1.0f };
float LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float LightDirection[]={-0.5f, -0.5f, -0.5f};
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, LightDirection);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void setmaterial(){
//here you set materials, you must declare each one of the colors global or locally like this:
float MatAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
float MatDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float MatSpecular[] = { 0.1f, 0.1f, 0.0f, 0.1f };
float MatShininess = 60;
float black[] = {0.0f,0.0f,0.0f,1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MatAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MatDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MatSpecular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, MatShininess);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
}
void render(){
//your render function
//clean buffers, set viewport, projection, lookat, etc...
. . .
//set light and materials
setlight();
setmaterial();
//draw your stuff
. . .
glutSwapBuffers();
}
Now, if you need to set different materials for differents object to draw you must set the materials for each object before you draw them... example:
for(int i=0; i<num_objetcs; i++){
setmaterial(i);
drawobject(i);
}
Of course, you have to modify what I wrote before... You just have to set the light and then for each object you set their material and then draw, one by one. You must modify the "setmaterial" function to take the material parameter and I suppose you know what to do for the rest... good luck!
How can I have separate material properties for different objects drawn in OpenGL?
I did the following code, which apparently only shows the later colour:
//************** Object 1 **************
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glColor4f(149.0/255.0, 78.0/255.0, 22.0/255.0, 1.0);
float mat_specular[] = {0.992157, 0.941176, 0.807843, 1.0};
float shininess = 10;
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
glPushMatrix();
glTranslatef(0, 3.0, 0);
drawSphere(0.1, 0.1, 0.1);
glRotatef(10, 1, 0, 0);
glDisable(GL_COLOR_MATERIAL);
//************** Object 2 *****************
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(48.0/255.0, 48.0/255.0, 48.0/255.0, 1.0);
float mat_specular_2[] = {0.992157, 0.941176, 0.807843, 1.0};
float shininess_2 = 10;
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_2);
glMaterialf(GL_FRONT, GL_SHININESS, shininess_2);
glPushMatrix();
glTranslatef(-0.6, 0.2, 1.6/2.0);
drawSphere(0.1, 0.1, 0.1);
glPopMatrix();
glDisable(GL_COLOR_MATERIAL);
When rendered, the colour set for the Object 2 is used for the entire scene. So the Object 1 is also rendered in Object 2's colour despite having its own colour set already.
How can I have the 2 objects to have separate material properties so that they can be displayed as different colours instead of just one colours in the whole scene?
You should put:
glEnable(GL_COLOR_MATERIAL);
As the first thing in your render function, then set the light parameters:
glDisable(GL_COLOR_MATERIAL);
glPushMatrix();
Then set the properties of the material and call the object. All the objects from now on will have this property, if you want to use another material on another object just type:
glDisable(GL_COLOR_MATERIAL);
again, before modeling the second object and so on. If you still have questions, just ask.
First, your example code looks reasonable and your objects should indeed have different materials.
But keep in mind that you only change the diffuse material color for your second object, as you set exactly the same specular colors and shininess values for both objects. And the ambient of the second object is also the same like for the first, as you only enable color material for the diffuse channel, so the ambient is unchanged from the first object, as OpenGL is a state machine.
So the only material difference between the objects is their diffuse color and this difference is (101, 30, 26). So can it be, that this difference is just outweighted by the ambient and specular terms that are completely equal and is therefore just too small for you to notice? Try completely different materials and see if there is really no difference.
It seems you have missed a glPopMatrix after drawing the first object. I don't know how that would change things.