I'm having trouble being able to see objects I've created when I have enabled lighting in OpenGL. I have an object that is imported from 3D Max that the lighting works correctly on but the rest of my scene does not. I know that I need to specify normals but this hasn't seemed to have helped. Although if I create a simple polygon in my display() function that works correctly but other polygons that have been created in methods of a class and called in the display() function are not showing up
Here is my lighting code
glewInit();
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT)
glShadeModel(GL_SMOOTH);
//light position and colour
GLfloat light_position[] = { 0.0, 0.0, 20.0,0.0 };
GLfloat white_light[] = {0.8,0.8,0.8,0.0};
GLfloat diff_light[] = {1.0,1.0,1.0,0.0};
GLfloat spec_light[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diff_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
//ambient light
GLfloat ambient[] = {0.3,0.3,0.3};
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
//diffuse material component
GLfloat diff[] = {0.6,0.6,0.6};
glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
//specular material component
GLfloat WhiteSpec[] = {1,1,1};
glMaterialfv(GL_FRONT, GL_SPECULAR, WhiteSpec);
GLfloat shininess = 50;
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
//ENABLE LIGHTING AND DEPTH TEST
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
This is my class method that is creating my sea
glColor3f(0,0,1);
glPushMatrix();
//enable texturing
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, seaTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for(int i = 0, k = 0; i < (getWidth()/10); i++){
for(int j = 0; j < (getLength()/10); j++){
if(i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength){
int nextK = k+1;
if(nextK == Sea::sinArrayLength){
nextK = 0;
}
if(i == Sea::waveLoc1+Sea::sinArrayLength){
//front of wave
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[nextK], Sea::seaGrid[i][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y , Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
glEnd();
}else{
//rest of wave
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[k], Sea::seaGrid[i][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[k], Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j].z);
glEnd();
}
}else{
//draw flat sea
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y, Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::seaGrid[i][j+1].y, Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::seaGrid[i][j].y, Sea::seaGrid[i][j].z);
glEnd();
}
}
//increment k if i is in the area of the wave
if(k < Sea::sinArrayLength-1 && (i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength)){
k++;
}else if(k == Sea::sinArrayLength){
k = 0;
}
}
if(Sea::waveLoc1 < 100 && Sea::waveInc == Sea::waveSpeedLimiter){
Sea::waveLoc1 +=1;
}else if(Sea::waveLoc1 >= 100){
Sea::waveLoc1 = 0;
}
//limits speed of wave
if(Sea::waveInc < Sea::waveSpeedLimiter){
Sea::waveInc++;
}else{
Sea::waveInc = 0;
}
//disable texturing
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
This is then called in my display() function as below
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)screenWidth/(GLfloat)screenHeight,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.updateCameraPosition(mouse_x,mouse_y,screenWidth,screenHeight);
sea.buildSeaPlane();
scene.buildEdges();
glPushMatrix();
glColor3f(0,1,0);
glTranslatef(0, 20, 200);
model.speedDisplayFaceNormals();
glPopMatrix();
glPushMatrix();
plane.updatePlanePosition();
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(0, 25, 10);
glVertex3f(2, 25, 10);
glVertex3f(2, 25, 20);
glVertex3f(0, 25, 20);
glEnd();
glPopMatrix();
glFlush();
Any idea why I can't see any of this?
UPDATE:
I can see my sea if I disable texturing. How can I fix it so I can use textures and lighting?
UPDATE 2:
Have changed texturing to GL_MODULATE but I also had to remove the blending to make it work. Do I need blending enabled?
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
says to replace the lighting computation with the result of texturing. If you want lighting to affect texturing, us GL_MODULATE instead of GL_REPLACE.
Edit to add:
You only need blending if you want your geometry to be translucent (that's what blending is typically for). In your case, there are a number of issues in the code:
your light colors are fully transparent (all have 0. as the 4th component). So your light is making everything invisible. change it to 1.
your materials don't have a 4th component. That's even worse, as glMaterialfv expects 4 floats. That could even crash your app or reformat your disk. Add a forth component, preferably to 1. to make it fully opaque.
Try adding an ambient light for the whole scene. Something like:
GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightColor);
In your glMaterialfv calls, the color parameter should have 4 values, not 3. Normally the 4th value is an alpha of 1.0. I'm not sure if it's OK to pass 0.0 as the 4th value for glLightfv either.
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 reviving some openGL/glutcode from over 10 years ago. It looks like freeglut has taken over from glut, and something is not quite the same. This code used to color the sphere:
void DrawRider() {
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glColor4f(1.0, 0.6, 0.4, 0.5);
glutSolidSphere(0.5, 12, 6);
}
Now the sphere is black, though it shows some signs of lighting.
Here is the set up code:
void init (void) {
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glShadeModel(GL_SMOOTH);
glFrontFace(GL_CCW);
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
if (transparent) glEnable(GL_BLEND);
glColor3f(1.0,1.0,1.0);
gCameraReset();
glPolygonOffset (1.0, 1.0);
SetLighting(4);
glEnable(GL_LIGHTING);
}
void SetLighting(unsigned int mode)
{
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat mat_shininess[] = {90.0};
GLfloat position[4] = {7.0,-7.0,12.0,0.0};
GLfloat ambient[4] = {0.2,0.2,0.2,1.0};
GLfloat diffuse[4] = {1.0,1.0,1.0,1.0};
GLfloat specular[4] = {1.0,1.0,1.0,1.0};
glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
switch (mode) {
// OTHER CASES ELIDED FOR POSTING TO StackOverflow
case 4:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);
break;
}
glLightfv(GL_LIGHT0,GL_POSITION,position);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glEnable(GL_LIGHT0);
}
And here is the display code that calls DrawRider:
void maindisplay(void)
{
if (textured) glEnable(GL_TEXTURE_2D);
else glDisable(GL_TEXTURE_2D);
if (transparent) glDepthMask(0);
else glDepthMask(1);
if (!riding) {
// track ball rotation
glRotatef (gTrackBallRotation[0], gTrackBallRotation[1], gTrackBallRotation[2], gTrackBallRotation[3]);
glRotatef (gWorldRotation[0], gWorldRotation[1], gWorldRotation[2], gWorldRotation[3]);
}
glClearColor (0.2f, 0.2f, 0.2f, 1.0f); // defines the "background" color
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the surface
if (!riding) DrawRider();
glutSwapBuffers();
}
I am trying to draw a sphere and a rotating cube around it. I am able to draw both of them perfectly seperately. Nevertheless once I draw both together I get strange results.
my sphere gets disformed.
when I change the angle of my cubeon purpose (by pressing on a button) it just dissapears from my screen.
when I only draw the cube and theng change the angle everything works fine.
Why please?
image: http://imgur.com/dIngayh (the cube looks ok, but the sphere is too stretched)
My code:
void MyGLWidget::paintGL()
{
glScalef(1,1,1);
setLight();
drawSun();
drawCube();
}
void MyGLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
}
void MyGLWidget::drawSun()
{
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glScalef(1,1,1);
glLoadIdentity();
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
glColor3f(1,1,0);
gluSphere(quadric, 0.25, 360,360);
gluDeleteQuadric(quadric);
glPopMatrix();
}
void MyGLWidget::drawCube()
{
glTranslatef(0, 0, 0);
glRotatef(getCubeAngle(), 1.0f, 0.0f, 0.0f);
glRotatef(0, 0.0f, 1.0f, 0.0f);
glRotatef(0, 0.0f, 0.0f, 1.0f);
glTranslatef( 0.5, 0, 0);
glBegin(GL_QUADS);
//back side of cube
glColor3f(255,0,0);
glVertex3f(-0.1, 0.1,-0.1 );//upper left corner
glVertex3f(0.1, 0.1,-0.1); //uper right
glVertex3f(0.1,-0.1,-0.1 ); // down left
glVertex3f(-0.1,-0.1,-0.1); // down right
/*draws other parts of the cube in the same way*/
glEnd();
glFlush();
}
/**/
void MyGLWidget::setLight()
{
// Prepare light parameters.
float SHINE_ALL_DIRECTIONS = 1;
float lightPos[4] = {-30, 0, 0, SHINE_ALL_DIRECTIONS};
float lightColorAmbient[4] = {50, 50, 0.1, 1};
float lightColorSpecular[4] = {150, 150, 0.5, 1};
// Set light parameters.
glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
glLightfv(GL_LIGHT1, GL_AMBIENT, lightColorAmbient);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightColorSpecular);
// Enable lighting in GL.
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
// Set material properties.
float rgba[3] = {0.3, 0.5, 1};
glMaterialfv(GL_FRONT, GL_AMBIENT, rgba);
glMaterialfv(GL_FRONT, GL_SPECULAR, rgba);
glMaterialf(GL_FRONT, GL_SHININESS, 0.5f);
}
try to add this one:
void MyGLWidget::resizeGL(int width, int height);
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(height *1./width, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
and more read here (rus)
I am working on a background texture. What I want to do is that I want to set a background image. For that in my code I used switch to ortho, draw a square full of window size, texture it. Then switch back to 3d and draw 3d images. It draw the background texture and snowman but they all disappear in a sec. I have no idea where the error code is. gotta have something to do with pushing and popping the matrix I think. Below is the code of my InitGl, draw() and drawsnowman(), main and reshape(). I think the problem is in draw() function during the swithc between 3D to 2d. Advice?
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutKeyboardFunc(key);
if( !initGL() ) { // NEW (16)
printf( "Unable to initialize graphics library!\n" );
return 1;
}
glutDisplayFunc (display);
// glutIdleFunc (display);
glutIdleFunc(idle);
glutReshapeFunc (reshape);
//Load our texture
texture = LoadTexture( "texture.bmp", 256, 256 );
glutMainLoop ();
//Free our texture
FreeTexture( texture );
return 0;
}
void drawSnowMan(void)
{
GLUquadricObj *pObj;
//glDisable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// save the world matrix
glPushMatrix();
glTranslatef(xpos, -0.5, -5.0);
glRotated(rotX,1,0,0); // ******** NEW (11)
glRotated(rotY,0,1,0);
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
//glRotated(rotZ,0,0,1);
glPushMatrix();
//setting up light effect for base, mid and head spheres. all red!
ambient[0] = 1.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glTranslatef(0.0 ,0.75f, 0.0f);
//bottom sphere. dont need to gltranslate again because it will use the previous gltranslate
//which is declared outside
glutSolidSphere(0.70f,20,20);
//mid sphere
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.45f,20,20);
//top sphere
glTranslatef(0.0f, 0.6f, 0.0f);
glutSolidSphere(0.30f,20,20);
//eyes
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
//drawing hat
glPushMatrix();
//black color. move it 1.85 in y position because thats where the head is
//rotate the cylinder and draw cylinder
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 1.85f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.17f, 0.17f, 0.4f, 26, 13);
//drawing brim. disable cull_face. draw disk, so front part. disabl
glDisable(GL_CULL_FACE);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glEnable(GL_CULL_FACE);
glTranslatef(0.0f, 0.0f, 0.40f);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glPopMatrix();
glPushMatrix();
glPushMatrix();
glColor3f(1.0,1.0,1.0);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(90.0,0.0, 0.0,-5.0);
glScalef (0.01, 0.2, 0.06); /* modeling transformation */
//glutSolidCone(0.1, 0.1, 10.0, 14.0);
glutSolidCube(1.5);
glPopMatrix();
glPushMatrix();
glTranslatef(2.0f, 0.8f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.04f, 0.04f, 0.2f, 26, 13);
glPopMatrix();
//blade
glPushMatrix();
ambient[0] = 0.0; ambient[1] = 1.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.03f, 0.03f, 1.1f, 26, 13);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
glPopMatrix();
//big push matrix for eyes, and nose
glPushMatrix();
//eyes color = black light. set defuse all 0, ambient = black. turns the eyes black
/*ambient[0] = 0.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 0.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);*/
glColor3f(0.0, 0.0, 0.0);
//left eye
glPushMatrix();
glTranslatef(-0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//right eye
glPushMatrix();
glTranslatef(0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//drawing nose
glPushMatrix();
glTranslatef(0.0, 1.6, 0.25 );
glutSolidCone(0.08f,0.5f,10,2);
glPopMatrix();
glPopMatrix(); // end big push matrix for eyes and nose
glPopMatrix();
} // end of drawsnowman()
void display (void) {
glClearColor(0.25f, 0.25f, 0.50f, 1.0f ); // blueish color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glLoadIdentity();
// MODEL VIEW is set up in IniitGL
//so save it
glPushMatrix();
//switch to projection matrix
//swithc to ortho.
//draw texture
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glPopMatrix();// pop the 3d model view
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
// You can ignore this. just a different of way drawing texture and still does not work
/* glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glDepthMask( false );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 800 / 600, 1.0, 100.0);;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, // Where would the camera be?
0.0, 0.0,-1.0, // Where would it be looking?
0.0, 1.0, 0.0); // What would be the "up" vector?fa*/
/* glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//gluPerspective (45, SCREEN_WIDTH / SCREEN_HEIGHT, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();*/
drawSnowMan(); // draw snow man
glutSwapBuffers();
angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
bool initGL (void) {
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Switch to the "camera" mode
glMatrixMode(GL_PROJECTION); // Camera
glLoadIdentity();
// Change the camera to a 3D view
glFrustum( -1 * (float) SCREEN_WIDTH / SCREEN_HEIGHT,
(float) SCREEN_WIDTH / SCREEN_HEIGHT,
-1.0,
1.0,
1.5,
1000.0);
glClearColor(0.25f, 0.25f, 0.50f, 1.0f );
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // NEW (5)
glEnable(GL_LINE_SMOOTH); // NEW (6)
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // NEW (7)
glEnable(GL_POLYGON_SMOOTH); // NEW (8)
// this is a specular light
GLfloat mat_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 }; // Color of a "shiny material
GLfloat mat_shininess[] = { 50.0 }; // How shiny is it?
// GLfloat mat_ambient_and_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; // Infinitely far away. Direction light
GLfloat light_position1[] = {2.0,1.5,0.0,1.0}; // saber light
// How to calculate the surface normal for pixels
glShadeModel(GL_SMOOTH); // Try this as well GL_FLAT
// Setup up some material reflective properties
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
// glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_and_diffuse);
//glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient_and_diffuse);
// Finally actually make the light
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
//Check for error
GLenum error = glGetError(); // NEW (9)
if( error != GL_NO_ERROR ) {
printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
return false;
}
return true;
}
void idle(void) {
glutPostRedisplay();
}
Reoccuring newbie misconception: OpenGL "initialization".
OpenGL is not initialized! All the code you have in initGL and reshape belongs into display.
In the case of calls glLight… those must be placed in display, after setting the modelview matrix into the space you want the lights to be in. Also OpenGL is not a library; yes originally the 'L' in OpenGL did mean library, but I backronymed it to Layer, because that's what it is on most modern graphics systems: A layer between a end user program and the GPU and its drivers.
I think once you moved the code from initGL and reshape to display, the solution should become clear: You can change, reset and modify the projection and modelview matrix whenever you like. To have the window width and height available in display either store them in global variables in reshape, or, the preferred solution, use glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) to query the window dimensions in the display function.
You want to draw things in a orthographic projection? Then setup projection and modelview appropriately. Switching to a perspective? Just do it.
I think I kinda figure out why my background texture keep disappearing. I had Cullface and depth something turned on. I turned it off befor popping the last matrix and it works.
However, there is one problem. The texture image is snowy background, but it turns into all red. So first I thought it was due to the reflection of the lighting from the snowgirl. I turned off all the light and still red. Can't figure out why. Could it be, the texture color blending in with the original color of the snowman?
Im a bit stuck with my lighting. My light can light up meshes but it does not light up my ground.
Here is some of my code
The light:
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0f);
glEnable(GL_COLOR_MATERIAL);
GLfloat ambient_light0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position_light0[] = { 0.0f, 8.0f, 0.0f, 0.9f };
GLfloat spotDirection_light0[] = {0.0, -1.0, 0.0 };
GLfloat specularLightcolor[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, position_light0 );
glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection_light0 );
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5);
glLightfv( GL_LIGHT0, GL_AMBIENT, ambient_light0 );
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLightcolor);
glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 60.0f );
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 50.0f );
The ground:
void drawGround(int id) {
glEnable(GL_TEXTURE_2D);
glEnable(GL_COLOR_MATERIAL);
getTexture(id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLfloat material_diffuse[] = {0.9, 0.9, 0.9, 1.0 };
GLfloat material_specular[] = { 1, 1, 1, 1 };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
glBegin(GL_QUADS);
for(int i = 0; i<3; i++){
for(int j= 0; j<3; j++){
glNormal3f(0.0f, 1.0f, 0.0f);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 80.0);
glTexCoord2f(1, 1);
glVertex3f(-floorSize +((j)*(2*floorSize)/3), 0 ,-floorSize +((i)*(2*floorSize)/3));
glTexCoord2f(1, 0);
glVertex3f(-floorSize +((j)*(2*floorSize)/3), 0 ,-floorSize +((i+1)*(2*floorSize)/3));
glTexCoord2f(0,0);
glVertex3f(-floorSize +((j+1)*(2*floorSize)/3), 0 ,-floorSize +((i+1)*(2*floorSize)/3));
glTexCoord2f(0, 1);
glVertex3f(-floorSize +((j+1)*(2*floorSize)/3), 0 ,-floorSize +((i)*(2*floorSize)/3));
}
}
glDepthMask( 1.0 );
glDisable(GL_TEXTURE_2D);
glEnd();
}
Drawing of the ground happens after the light is called.
Has anyone any idea why my ground is not lighting up?
here is a screen shot of my problem --->
The problem is, that default fixed function OpenGL lighting does the illumination at the vertices only, and then just interpolates the resulting color. Since all the 4 vertices of the ground are dimly lit, the whole quad gets dim.
Solutions:
further subdivide your ground, so that there are more light sampling points. So far you've got only 3×3 points, which is not nearly sufficient. Think 100×100 or even more, to get a nice illumination effect.
or
use a fragment shader to implement per pixel lighting.
You're running into a typical OpenGL newbie pitfall there, BTW.
Update:
On a side note: You also did not supply normals for the plane. Therefore lighting will not work at all.