I have a small program below that draws an Icosahedron. I’m supposed to have controls that can enable lighting, backface culling, change the field of view, and polygon mode. I can’t seem to get the backface culling or field of view to work. When I click the backface culling checkbox, nothing happens. It’s a toggle so it should enable/disable it. Also, the field of view does not change gradually. Changing by 10 degrees has no effect but changing by 30 does. Any help is greatly appreciated.
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
#include “glui.h”#pragma comment( linker, “/subsystem:"windows" /entry:"mainCRTStartup"” )
#define X .525731112119133606
#define Z .850650808352039932static GLfloat vdata[12][3] = {
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};static GLuint tindices[20][3] = {
{1,4,0}, {4,9,0}, {4,5,9}, {8,5,4}, {1,8,4},
{1,10,8}, {10,3,8}, {8,3,5}, {3,2,5}, {3,7,2},
{3,10,7}, {10,6,7}, {6,11,7}, {6,0,11}, {6,1,0},
{10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7}
};struct CameraPosition {
float x;
float y;
float z;};
int vfov = 60;
int hfov = 60;
float Znear = 0.1;
float Zfar = 1000.0;
CameraPosition cam_pos;
GLenum renderMode;
int window_id;
int totaldepth = 0;
int lighting = 1;
int obj = 2;
int backface_culling = 1;
float viewpoint_x = 0;
float viewpoint_y = 0;
float viewpoint_z = 0;void openglReshape(int w, int h)
{glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(vfov, hfov/vfov, Znear, Zfar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();}
void control_cb(int control)
{}
void normalize(float v[3])
{GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0){
cout << “zero length vector”;
return;
}
v[0] /= d;
v[1] /= d;
v[2] /= d;}
void drawtriangle(float *v1, float *v2, float *v3)
{glColor3f(0.5, 1.0, 0.5);
glBegin(GL_TRIANGLES);
glNormal3fv(v1);
glVertex3fv(v1);
glNormal3fv(v2);
glVertex3fv(v2);
glNormal3fv(v3);
glVertex3fv(v3);
glEnd();}
void subdivide(float *v1, float *v2, float *v3, long depth)
{GLfloat v12[3], v23[3], v31[3];
GLint i;if (depth == 0){
drawtriangle(v1, v2, v3);
return;
}
for(i=0; i < 3; i++){
v12[i] = (v1[i]+v2[i])/2.0;
v23[i] = (v2[i]+v3[i])/2.0;
v31[i] = (v3[i]+v1[i])/2.0;
}
normalize(v12);
normalize(v23);
normalize(v31);
subdivide(v1, v12, v31, depth-1);
subdivide(v2, v23, v12, depth-1);
subdivide(v3, v31, v23, depth-1);
subdivide(v12, v23, v31, depth-1);}
void drawIcosahedron(void)
{switch(obj){
case 0:
renderMode = GL_POINT;
break;
case 1:
renderMode = GL_LINE;
break;
case 2:
renderMode = GL_FILL;
break;
}
glPolygonMode(GL_FRONT_AND_BACK, renderMode);if (lighting == 1){
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
else{
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
}if (backface_culling = 1){
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}
else{
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}int i;
for (i=0; i < 20; i++){
subdivide(&vdata[tindices[i][0]][0],
&vdata[tindices[i][1]][0],
&vdata[tindices[i][2]][0], totaldepth);}
//gluPerspective(vfov, hfov/vfov, Znear, Zfar);
glFlush();
}void openglDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(vfov, hfov/vfov, Znear, Zfar);
glMatrixMode(GL_MODELVIEW);glCullFace(GL_BACK);
glColor3f(0.5, 1.0, 0.5);
glLoadIdentity();
gluLookAt(cam_pos.x, cam_pos.y, cam_pos.z, viewpoint_x, viewpoint_y, viewpoint_z, 0.0, 1.0, 0.0);drawIcosahedron();
glutSwapBuffers();}
void changeCameraPosition(int key, int x, int y)
{switch(key) {
case GLUT_KEY_UP :
cam_pos.y -= 0.25;
viewpoint_y -= 0.25;
openglDisplay();
break;
case GLUT_KEY_DOWN :
cam_pos.y += 0.25;
viewpoint_y += 0.25;
openglDisplay();
break;
case GLUT_KEY_RIGHT :
cam_pos.x -= 0.25;
viewpoint_x -= 0.25;
openglDisplay();
break;
case GLUT_KEY_LEFT :
cam_pos.x += 0.25;
viewpoint_x += 0.25;
openglDisplay();
break;
case GLUT_KEY_PAGE_UP :
cam_pos.z -= 0.25;
viewpoint_z -= 0.25;
openglDisplay();
break;
case GLUT_KEY_PAGE_DOWN :
cam_pos.z += 0.25;
viewpoint_z += 0.25;
openglDisplay();
break;
}}
void myGlutIdle( void )
{
/* According to the GLUT specification, the current window is
undefined during an idle callback. So we need to explicitly change
it if necessary */
if ( glutGetWindow() != window_id )
glutSetWindow(window_id);glutPostRedisplay();
}int main(int argc, char *argv)
{glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(400, 400);
window_id = glutCreateWindow(“Assignment 1”);
glutDisplayFunc(openglDisplay);
glutReshapeFunc(openglReshape);
// glutMouseFunc(Mouse);
// glutMotionFunc(worldMotion);
glutSpecialFunc(changeCameraPosition);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glClearColor(0.0, 0.0, 0.0, 0.0);cam_pos.x = 0;
cam_pos.y = 0;
cam_pos.z = 2.5;GLUI *glui = GLUI_Master.create_glui(“Controls”,1, 412, 0);
glui->add_checkbox(“Lighting”, &lighting);
GLUI_Spinner *depth_spinner = glui->add_spinner(“Depth:”, GLUI_SPINNER_INT, &totaldepth);
depth_spinner->set_int_limits(0, 5);GLUI_Panel *obj_panel = glui->add_panel (“Object Type”);
GLUI_RadioGroup *group1 = glui->add_radiogroup_to_panel(obj_panel,&obj,4,control_cb);
glui->add_radiobutton_to_group(group1, “Points”);
glui->add_radiobutton_to_group(group1, “Wireframe”);
glui->add_radiobutton_to_group(group1, “Solid”);GLUI_Spinner *hfov_spinner = glui->add_spinner(“Horizontal FOV:”, GLUI_SPINNER_INT, &hfov);
hfov_spinner->set_int_limits(1, 180);GLUI_Spinner *vfov_spinner = glui->add_spinner(“Vertical FOV:”, GLUI_SPINNER_INT, &vfov);
vfov_spinner->set_int_limits(1, 180);glui->add_checkbox(“Backface Culling”, &backface_culling);
glui->set_main_gfx_window(window_id);
GLUI_Master.set_glutIdleFunc(myGlutIdle);glutMainLoop();
return 0;}