Not all objects with same material look the same - Open GL/C++ - c++

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?

Related

How to fix bitmap lighting in openGL?

I need help with my code in C++ using the OpenGL API. I have written a program that draws 4 3D cubes and text (using bitmap) onto the screen. Now I want to add lighting.
I have added glMaterial code to give a description of the material for the cubes. I do not want the material properties to be applied to the bitmap text. Therefore, I placed the code for the material before drawing the cube and I also placed the code for drawing the cube and the material between a pushMatrix and popMatrix pair. However, when I run the code, I find the text changes color.
Below is some of the code that I am using:
void init() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ligAmb);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lig[0][0]);
glLightfv(GL_LIGHT0, GL_SPECULAR, lig[0][1]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligDir);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exp_one);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lig[1][0]);
glLightfv(GL_LIGHT1, GL_SPECULAR, lig[1][1]);
glEnable(GL_LIGHT1);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void drawCube(Point3D colors[], Point3D vertices[]) {
glBegin(GL_QUADS);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glEnd();
}
void displayObject() {
glPushMatrix();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, ligPos[0]);
glLightfv(GL_LIGHT1, GL_POSITION, ligPos[1]);
typedef GLint vertex3[3];
Point3D vertices[8] = { {-1.0, -1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, 1.0, -1.0},
{-1.0, 1.0, 1.0},
{ 1.0, -1.0, -1.0},
{ 1.0, -1.0, 1.0},
{ 1.0, 1.0, -1.0},
{ 1.0, 1.0, 1.0} };
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_INT, 0, vertices);
GLubyte vertIndex[] = { 6,2,3,7,5,1,0,4,7,3,1,5,4,0,2,6,2,0,1,3,7,5,4,6
};
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, vertIndex);
glPopMatrix();
Point3D colorsb[8] = { {0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.},
{0.,0.,1.} };
Point3D colorsg[8] = { {0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.},
{0.,1.,0.} };
Point3D colorsr[8] = { {1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.},
{1.,0.,0.} };
Point3D colorsy[8] = { {1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.},
{1.,1.,0.} };
glPushMatrix();
glTranslatef(-0.5f, 4.0f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[0][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[0][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[0][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[0]);
drawCube(colorsb, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[1][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[1][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[1][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[1]);
drawCube(colorsg, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(-0.5f, -4.5f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[2][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[2][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[2][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[2]);
drawCube(colorsr, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(-6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[3][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[3][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[3][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[3]);
drawCube(colorsy, vertices);
glPopMatrix();
}
void display() {
displayObject();
wordColor = "green";
char str[] = { "Red" };
glColor3f(0.0, 1.0, 0.0);
glRasterPos2f(-0.5, 0.0);
for (int i = 0; i < strlen(str); i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, str[i]);
}
glPopMatrix();
loop += 0.05;
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
OpenGL is a state machine, which means that it keeps a state around until you explicitly change it again. So when you take care to set the illumination only after drawing the text during drawing one frame, it will have happened before drawing the text of the next frame.
The solution is, that you always set every relevant state for whatever it is you're drawing, right before you draw it. In case of the text, it's as simple as disable lighting, right before drawing the text (actually before calling glRasterPos).

How to display specular spot in an object in OpenGL

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.

Problems with camera view and lighting (openGL & GLUT)

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!

Spotlight issue OpenGL

I have a problem with spotlight in OpenGL library. A scene is black, light is unseen if the GL_SPOT_CUTOFF is less than 125. I supposed that issue concerns direction of the light source but I have tried plenty of options both for position and direction of spotlight. Here is my code:
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 };
glPushMatrix();
glLoadIdentity();
GLfloat spot_direction[] = { 0.0, -1.0, 0.0 ,0.0};
GLfloat spot_position[] = { 1.0,1.0,0.0,1.0 };
glLightfv(GL_LIGHT1, GL_POSITION, spot_position);
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 60);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 100);
glPopMatrix();
glEnable(GL_LIGHT1);
Solved. Problem was with too high GL_SPOT_EXPONENT factor (light was too much focused) and with direction of the light stream.

OpenGL Object Rendering Order

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);
}