I am creating a sphere. The light source (ambient and diffuse lighting) works well. Only the specular light that doesn't show up in any part of the sphere.
The material code seems not working. I deleted the line and the result is also the same.
The result I want is the sphere rotates with white spot on it in order to look real.
Am I missing any required configuration for lighting?
Is there any solution?
Thanks.
float angle = 0.0f;
void initRendering(){
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
}
void draw(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glRotatef(angle, 0.0, 1.0, 0.0);
glutSolidSphere(0.5, 20, 20);
glPopMatrix();
GLfloat ambientColor[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat diffuseColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specularColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat lightPosition[] = {0.0f, 5.0f, -3.0f, 0.0f};
GLfloat mat_specular[] = { 0.8f, 0.8f, 0.8f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMateriali(GL_FRONT, GL_SHININESS, 100);
angle+=0.1f;
glutPostRedisplay();
glutSwapBuffers();
}
main(){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(600, 600);
glutCreateWindow("Sphere");
glClearColor(1.0, 1.0, 1.0, 1.0);
initRendering();
glutDisplayFunc(draw);
glutMainLoop();
}
The default for specular light is to add to the colour evaulated in the diffuse illumination step. The specular intensity is modulated by the specular set. You've set this colour to "black", so it adds literally zero.
GLfloat mat_specular[] = { 0.8f, 0.8f, 0.8f, 1.0f };
// …
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
I'd start by actually not inhibiting the specular term.
Related
So I have drawn 5 tori on my scene and a cube behind them and besides LIGHT0 I also have LIGHT1 enabled on click. I need to create two different materials where when I press on number 1 material 1 turns on, and when I press 2 material two turns on instead of material one. But what happens is, those materials get turned on only for tori, not the cube behind them. Here is everything in the code explained:
void light_1() {
GLfloat light_position[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 5.0f};
glLightfv(GL_LIGHT1, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
}
Cube and tori have same exact properties.
void drawCube() {
GLfloat mat_diffuse[] = {0.3, 0.0, 0.7, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glutSolidCube(7.5);
}
void greenTorus() {
GLfloat mat_diffuse[] = {0.0, 1.0, 0.0, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glutSolidTorus(0.08, 0.8, 30, 30);
}
Here is my display function. Ignore the variables, they are controled by different stuff and are irrelevant.
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75.0, 4.0/3.0, 1.0, 200.0);
light_1();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0+LR, 0.0+UD, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glTranslatef(0.0+tyg/2, 0.0-tbr/2, -5.0);
glRotated(a, 0, 0, 1);
glScaled(0.5+s, 0.5+s, 0.5+s);
greenTorus();
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, -0.5, -9.0);
drawCube();
glPopMatrix();
glFlush();
glutPostRedisplay();
}
Here is the material that is used for bottom image.
void material_1() {
GLfloat m_ambient[] = {0.33f, 0.23f, 0.03f, 1.0f};
GLfloat m_diffuse[] = {0.8f, 0.6f, 0.1f, 1.0f};
GLfloat m_specular[] = {2.0f, 2.0f, 2.0f, 1.0f};
GLfloat m_shininess = 128.0f;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_shininess);
}
Does anyone see the issue? Here is a screenshot of the scene whole program renders when lights 0 and 1 are both turned on and material_1 is turned on. Why isn't the cube also highlighted? Why does LIGHT0 light on all objects, but LIGHT1 only on tori?
I am trying to implement the bottom subwindow with three torus, but failed to display anything on the subwindow..
main function for subwindow:
instrument_window = glutCreateSubWindow(main_window, GAP, view_height + 3*GAP, 2*(view_width+GAP), INSTRUMENT_HEIGHT);
glutDisplayFunc(display);
//lighting
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 600, 1200, 1200, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
//glClearColor(0.33,0.33,0.33,0.33);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
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);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
//end of lighting
glutMainLoop();
for display function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float width = 2*(GAP+view_width);
float height = INSTRUMENT_HEIGHT;
const float ar = (float) width / (float) height;
//glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(width/4.0, width*3.0/4.0, height*3.0/4.0, height/4.0, 2.0, 100.0);
//gluPerspective (160.0, 2*view_width/INSTRUMENT_HEIGHT, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
/*
glMatrixMode(GL_PROJECTION);
// Reset transformations
glLoadIdentity();
gluPerspective (160.0, 2*view_width/INSTRUMENT_HEIGHT, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Draw first
draw (view_width+GAP-400, INSTRUMENT_HEIGHT/2);
// Draw second
draw (view_width+GAP-150, INSTRUMENT_HEIGHT/2);
// Draw third
draw (view_width+GAP+100, INSTRUMENT_HEIGHT/2);
for draw function:
void draw(double cx,double cf)
glColor3f(0.34f,0.34f,0.34f);
glPushMatrix();
glTranslated(0.0, cx, cy);
glRotated(-10, 1.0, 0.0, 0.0);
glutSolidTorus(OUTER_DIAL_RADIUS, OUTER_DIAL_RADIUS+30, 100, 200);
glPopMatrix();
end
really frustrating since it just display nothing and don't know how to debug. Any hints are highly appreciate!!!!
To be honest, its difficult to answer this question from the code example supplied. Half of the 'displayFunction' is commented out from the /* so nothing below it will get called. Even then its difficult to deduce the problem since there is little code relating to multiple viewports here. Since you are using fixed pipeline GL look at NeHe which has a good tutorial on employing multiple viewports.
http://nehe.gamedev.net/tutorial/multiple_viewports/20002/
Debugging is the single most important tool a developer has in their arsenal to resolve problems. It would be wise to learn how to do this as it would certainly save you time in the long run and you will find the answers to most (if not all) of your coding problems!
I wanted to ask you about texture and lighting.
I am using a 3ds Object in OpenGL, and a BITMAP texture. It is working perfectly. When I use lighting it didn't reflect the light. While I was searching I just commented the line: glEnable(GL_TEXTURE_2D); and the Texture was gone but lighting works!
Is there any opportunity that I can leave TEXTURE and also add lighting? Why is this happening? Anyone any idea?
EDITED
this is in INIT() function
void initialize(){
glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
glEnable(GL_TEXTURE_2D); // This Enable the Texture mapping
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
// Light model parameters:
// -------------------------------------------
GLfloat lmKa[] = {0.0, 0.0, 0.0, 0.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmKa);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 0.0);
// -------------------------------------------
// Spotlight Attenuation
GLfloat spot_direction[] = {1.0, -1.0, -1.0 };
GLint spot_exponent = 30;
GLint spot_cutoff = 180;
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, spot_exponent);
glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, spot_cutoff);
GLfloat Kc = 1.0;
GLfloat Kl = 0.0;
GLfloat Kq = 0.0;
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,Kc);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq);
// -------------------------------------------
// Lighting parameters:
GLfloat light_pos[] = {0.0f, 5.0f, 5.0f, 1.0f};
GLfloat light_Ka[] = {1.0f, 0.5f, 0.5f, 1.0f};
GLfloat light_Kd[] = {1.0f, 0.1f, 0.1f, 1.0f};
GLfloat light_Ks[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_Ka);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_Kd);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks);
// -------------------------------------------
// Material parameters:
GLfloat material_Ka[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat material_Kd[] = {0.4f, 0.4f, 0.5f, 1.0f};
GLfloat material_Ks[] = {0.8f, 0.8f, 0.0f, 1.0f};
GLfloat material_Ke[] = {0.1f, 0.0f, 0.0f, 0.0f};
GLfloat material_Se = 20.0f;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_Ka);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_Ks);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_Ke);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material_Se);
}
this is the DISPLAY() function (I am using QT)
void pointGL(){
if(change)
{
ThreeDModels objectClass;
objectClass.SpaceShip();
change = false;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glScalef(0.05, 0.05, 0.05);
ThreeDModels objectiModel;
objectiModel.objectCreation(l_index);
glPopMatrix();
}
Method which other method for Loading 3ds object and add Texture
void ThreeDModels::SpaceShip()
{
Load3DS(&objecti, "C:/Users/Documents/3DModelRendering/3DModels/Spaceship/spaceship.3ds");
int a = LoadBitmap2("C:/Users/Documents/3DModelRendering/3DModels/Spaceship/spaceshiptexture.bmp");
}
void ThreeDModels::objectCreation(int l_index)
{
glBegin(GL_TRIANGLES); // glBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
for (l_index = 0; l_index<objecti.polygons_qty; l_index++)
{
//----------------- FIRST VERTEX -----------------
// Texture coordinates of the first vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].a].u,
objecti.mapcoord[objecti.polygon[l_index].a].v);
// Coordinates of the first vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].a].x,
objecti.vertex[objecti.polygon[l_index].a].y,
objecti.vertex[objecti.polygon[l_index].a].z); //Vertex definition
//----------------- SECOND VERTEX -----------------
// Texture coordinates of the second vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].b].u,
objecti.mapcoord[objecti.polygon[l_index].b].v);
// Coordinates of the second vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].b].x,
objecti.vertex[objecti.polygon[l_index].b].y,
objecti.vertex[objecti.polygon[l_index].b].z);
//----------------- THIRD VERTEX -----------------
// Texture coordinates of the third vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].c].u,
objecti.mapcoord[objecti.polygon[l_index].c].v);
// Coordinates of the Third vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].c].x,
objecti.vertex[objecti.polygon[l_index].c].y,
objecti.vertex[objecti.polygon[l_index].c].z);
}
glEnd();
}
I found the Answer guys:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); was in the LoadBitmap() method, just removing this one, and it worked ;D
Problem: Objects aren't rendering correctly.
What I tried to do: Searched Stack Overflow. Read that I needed to enable Depth_Test and did so. Still doesn't work. Read that I possibly needed glDepthFunc(GL_LEQUAL);, did not work. Is there something in the way I wrote reshape/initscene/myDisplay that causes these common approaches not to work?
Code below.
void reshape (int w, int h)
{
viewport.w = w;
viewport.h = h;
glViewport(0,0,viewport.w,viewport.h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h) {
glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
}
else {
glOrtho (-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the color buffer
glMatrixMode(GL_MODELVIEW); // indicate we are specifying camera transformations
glLoadIdentity(); // make sure transformation is "zero'd"
glScalef(zoom, zoom, zoom);
gluLookAt(0.0, -9.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0);
glRotatef(y_rotation, 0.0, 1.0, 0.0);
glRotatef(x_rotation, 1.0, 0.0, 0.0);
renderObjects();
glFlush();
glutSwapBuffers(); // swap buffers (we earlier set double buffer)
}
void initScene(){
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
reshape(viewport.w, viewport.h);
glShadeModel(GL_FLAT);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
GLfloat red[] = {1.0f, 0.2f, 0.2f, 1.0f};
GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat gray[] = {0.5f, 0.5f, 0.5f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gray);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gray);
GLfloat lightPos[] = {0.0f, 0.0f, -10.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
}
I'd like to enable lighting in my openGL program, i already works for objects drawn with GLUT.
but when i draw my cuuboid
glBegin(5);
glVertex3f((x_+(b/2)),y_,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_,(z_+(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_+(l/2)));
glVertex3f((x_+(b/2)),y_,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_,(z_+(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_t,(z_+(l/2)));
glVertex3f((x_+(b/2)),y_,(z_+(l/2)));
glVertex3f((x_+(b/2)),y_t,(z_+(l/2)));
glEnd();
with
glColor3f(6,0,0);
lightning isn't applied on its surfaces. (the cuboid is drawn correct)
my lighning is set up like this:
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 1.0, 1.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
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);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
does anyone know the flaw i make?
You didn't give it any normals. You need to use glNormal3f to specify the normals.
glBegin(GL_TRIANGLE_STRIP);
glNormal3f(0,1,0);
glVertex3f((x_+(b/2)),y_,(z_-(l/2)));
glVertex3f((x_+(b/2)),y_,(z_+(l/2)));
glVertex3f((x_-(b/2)),y_,(z_-(l/2)));
glVertex3f((x_-(b/2)),y_,(z_+(l/2)));
glNormal3f(-1,0,0);
// etc.