오픈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 뒤에 놓아도 마찬가지인가요?
댓글 달기