오픈GL 질감및 간단한 빛 설정 ....
글쓴이: Sailor_moon / 작성시간: 일, 2011/04/03 - 12:41오후
아이고 ... 저에겐 이런 것 조차 쉽지 않네요 .
// This program shows a simple tracball control #include <math.h> #include <iostream> #include <GL/glut.h> //for texture mapping //#include <GL/glext.h> #ifndef M_PI #define M_PI 3.14159 #endif int winWidth, winHeight; float trans[] = {0, 0, 0}; float rot_x = 0, rot_y = 0; int last_x = 0, last_y = 0; // draw a unit sphere GLfloat s_red = 1.0, s_green = 1.0, s_blue = 1.0; // 빛의 광원의 색 결정 GLfloat d_red = 1.0, d_green = 1.0, d_blue = 1.0; //물체의 색 결정 GLfloat a_red = 1.0, a_green = 1.0, a_blue = 1.0; // // MENU CONSTRUCTION int menu; // for menu int menu_parameter; // sphere can be considered as a surface of revolution void draw_sphere() { const int ntheta = 40; const int nphi = 20; double delta_theta = 2.0 * M_PI / (ntheta-1); double delta_phi = M_PI / (nphi-1); double theta = 0, phi = 0; glBegin(GL_QUADS); for(int i=0; i<nphi-1; i++, phi += delta_phi) { for(int j=0; j<ntheta-1; j++, theta+=delta_theta) { float x1 = cos(theta)*sin(phi); float y1 = sin(theta)*sin(phi); float z1 = cos(phi); float x2 = cos(theta)*sin(phi+delta_phi); float y2 = sin(theta)*sin(phi+delta_phi); float z2 = cos(phi+delta_phi); float x3 = cos(theta+delta_theta)*sin(phi+delta_phi); float y3 = sin(theta+delta_theta)*sin(phi+delta_phi); float z3 = cos(phi+delta_phi); float x4 = cos(theta+delta_theta)*sin(phi); float y4 = sin(theta+delta_theta)*sin(phi); float z4 = cos(phi); float nx = (y3-y2)*(z1-z2) - (y1-y2)*(z3-z2); float ny = (x1-x2)*(z3-z2) - (x3-x2)*(z1-z2); float nz = (x3-x2)*(y1-y2) - (x1-x2)*(y3-y2); float mag = sqrtf(nx*nx+ny*ny+nz*nz); glNormal3f(nx/mag, ny/mag, nz/mag); glVertex3f(x1,y1,z1); glVertex3f(x2,y2,z2); glVertex3f(x3,y3,z3); glVertex3f(x4,y4,z4); } } glEnd(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); // Holds current coordinates system glTranslatef(trans[0],trans[1],-4+trans[2]); glRotatef(rot_x, 1, 0, 0); glRotatef(rot_y, 0, 1, 0); draw_sphere(); glPopMatrix(); // Set original coordinate system glutSwapBuffers(); } void mouseButton(int button, int state, int x, int y) { if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) { last_x = x; last_y = y; } } void mouseMotion(int x, int y) { int dx = x - last_x; int dy = y - last_y; last_x = x, last_y = y; rot_x += dy * 180.0f / winHeight; rot_y += dx * 180.0f / winWidth; if( rot_x > 360 ) rot_x -= 360; if( rot_y > 360 ) rot_y -= 360; glutPostRedisplay(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case '.': // for zoom control trans[2] += 0.1; break; case ',': trans[2] -= 0.1; break; case 27: exit(0); break; } glutPostRedisplay(); } void special(int key, int x, int y) { switch(key) { case GLUT_KEY_LEFT: trans[0] -= 0.1; break; case GLUT_KEY_RIGHT: trans[0] += 0.1; break; case GLUT_KEY_UP: trans[1] += 0.1; break; case GLUT_KEY_DOWN: trans[1] -= 0.1; break; } glutPostRedisplay(); } void myReshape(int w, int h) { glViewport(0, 0, w, h); winWidth = w; winHeight = h; } void menu_selected(int entry) { switch(entry) { case 1: // Yellow Plastic Mode printf("yellow plastic\n"); glDisable(GL_LIGHTING); glEnable(GL_LIGHTING); d_red = 1.0; d_green = 1.0; d_blue = 1.0; //물체의 색 결정 draw_sphere(); //re-draw sphere //glDisable(GL_LIGHTING); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; case 2: glEnable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case 6: // QUIT case exit(0); break; } glutPostRedisplay(); } void init(void) { //GLfloat red = 1.0, green = 1.0, blue = 1.0; //Define parameters for the material GLfloat mat_specular[]={s_red, s_green, s_blue, 1.0}; // 반사에 대한 반사값 GLfloat mat_diffuse[]={d_red, d_green, d_blue, 1.0}; // 분산광에 대한 반사값 GLfloat mat_ambient[]={a_red, a_green, a_blue, 1.0}; //주변광에 대한 반사값 GLfloat mat_shininess={100.0}; // 광택 //Define parameters for the light GLfloat light_ambient[]={0.0, 0.0, 0.0, 1.0}; //주변광의 강도 GLfloat light_diffuse[]={0.5, 0.5, 0.5, 1.0}; // 분산광의 강도 GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0}; // 반사광의 강도 //Not used yet //GLfloat lit_pos[4]={6.0, 6.0, -9.0, 1.0};// 광원의 위치 //Set ambient, diffuse, and specular components for light 0 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); // Position of GL LIGHT //glLightfv(GL_LIGHT0, GL_POSITION, lit_pos); //Set material proerties for front face of all polygons glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); //Enable the various shading features glEnable(GL_FLAT); // enable smooth shading glEnable(GL_LIGHTING); // enable lighting glEnable(GL_LIGHT0); // enable light 0 glEnable(GL_DEPTH_TEST); // enable z buffer glEnable(GL_CULL_FACE); glMatrixMode(GL_PROJECTION); gluPerspective(50, 1, 0.1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //build a submenu glutCreateMenu(menu_selected); glutAddMenuEntry("PARAMETER",0); glutAddMenuEntry("YELLOW PLASTIC",1); glutAddMenuEntry("BRASS METAL",2); glutAddMenuEntry("Texture Map",3); glutAddMenuEntry("Environment Map",4); glutAddMenuEntry("MOVE EYE/LIGHT",5); glutAddMenuEntry("QUIT",6); glutAttachMenu(GLUT_RIGHT_BUTTON); //Build a submenu : Parameter } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("simple tracball demo"); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMouseFunc(mouseButton); glutMotionFunc(mouseMotion); glutKeyboardFunc(keyboard); glutSpecialFunc(special); init(); glutMainLoop(); }
대충 이렇게 됩니다.
사실 이제 저 위에서 , 마우스 우 클릭을 하면 , 메뉴가 여러개 나타나는데요 , 그중에서 특히 옐로우 플라스틱을 고르면
노란 플라스틱 공의 느낌이 , 브래스 메탈을 고르면 청동의 느낌이 나게 구를 바꾸려고 합니다.
원래 생각은 그냥 라이트 소스를 바꾸면되겠지 했는데 , 화면을 갱신해줄 함수를 어디서 콜 해야할지 모르겠습니다.
도와주셔요 ! 제가 하려던 방식은 저 위에서 해당 메뉴가 눌러지면 , 그냥 값만 바꿔서 갱신하려했는데 ,
화면갱신이 전혀 안되네요.
Visual studio 2008과 glut 을 사용해서 하고있습니다.
Forums:
.
.
display 함수가
glutDisplayFunc() 을 init 뒤에 놓아도 마찬가지인가요?
댓글 달기