OpenGL 실습 12 로봇
GLU Library를 이용한 이차곡면 렌더링 절차 GLUquadricObj* gluNewQuadric (); 새로운 이차곡면 객체를 만들고 객체의 포인터를 반환한다. This object must be referred to when calling quadrics rendering and control functions. A return value of 0 means that there is not enough memory to allocate the object.
void gluQuadricDrawStyle (GLUquadricObj *quad , GLenum drawStyle ); drawStyle을 사용하여 이차원 곡면 quad의 제작 스타일을 조절한다. quad : quadrics object (created with gluNewQuadric). drawStyle : the desired draw style. Valid values are GLU_FILL, GLU_LINE, GLU_SILHOUETTE, and GLU_POINT. GLU_FILL : Quadrics are rendered with polygon primitives. GLU_LINE : rendered as a set of lines. GLU_SILHOUETTE : rendered as a set of lines, except that edges separating coplanar faces will not be drawn. GLU_POINT ; rendered as a set of points.
void gluCylinder (GLUquadricObj void gluCylinder (GLUquadricObj* quad , GLdouble base , GLdouble top , GLdouble height , GLint slices , GLint stacks ); draw a cylinder quad : the quadrics object (created with gluNewQuadric). base :the radius of the cylinder at z=0. top : the radius of the cylinder at z=height. height : the height of the cylinder. slices : the number of subdivisions around the z axis. stacks : the number of subdivisions along the z axis.
gluCylinder draws a cylinder oriented along the z axis gluCylinder draws a cylinder oriented along the z axis. The base of the cylinder is placed at z=0, and the top at z=height. Like a sphere, a cylinder is subdivided around the z axis into slices, and along the z axis into stacks. Note that if top is set to 0.0, this routine generates a cone.
gluDisk (quad , inner , outer , slices , loops ) renders a disk on the z = 0 plane. The disk has a radius of outer, and contains a concentric circular hole with a radius of inner. gluSphere (quad , radius , slices , stacks ) draws a sphere of the given radius centered around the origin. gluPartialDisk (quad , inner , outer , slices , loops , start , sweep ) renders a partial disk on the z=0 plane. A partial disk is similar to a full disk, except that only the subset of the disk from start through start + sweep is included.
로봇 팔 메뉴에서 마우스로 선택한 부분이 키보드에서 p를 입력하면 양의 방향, n을 입력하면 음의 방향으로 회전하도록 프로그램 하라. Base는 y축을 중심으로 회전, ARM은 z축을 중심으로 회전함 BASE_HEIGHT 2.0 BASE_RADIUS 1.0 LOWER_ARM_HEIGHT 5.0 LOWER_ARM_WIDTH 0.5 UPPER_ARM_HEIGHT 3.0 UPPER_ARM_WIDTH 0.5
#include <gl/glut.h> #include <iostream> static GLfloat theta[] = {0.0,0.0,0.0}; static GLint axis = 0; GLUquadricObj *p; /* pointer to quadric object */ /* Define the three parts */ void base(){ // gluCylinder(…)을 이용해서 이곳에서 모델링 } void upper_arm(){ //glutWireCube(1.0);을 이용해서 작성 void lower_arm(){ //glutWireCube(1.0); 을 이용해서 작성
void base(){ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); gluCylinder(p, BASE_RADIUS, BASE_RADIUS, BASE_HEIGHT, 5, 5); glPopMatrix(); } void upper_arm(){ glPushMatrix(); glTranslatef(0.0, 0.5*UPPER_ARM_HEIGHT, 0.0); glScalef(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); } void lower_arm() 작성할 것
glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); void display(void){ /* Accumulate ModelView Matrix as we traverse tree */ glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glColor3f(1.0, 0.0, 0.0); //base의 모델-관측 행렬 base(); // lower_arm 의 모델-관측 행렬 lower_arm(); // upper_arm 의 모델-관측 행렬 upper_arm(); glutSwapBuffers(); }
void myinit() { glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(1.0, 0.0, 0.0); /* allocate quadric object */ p=gluNewQuadric(); /* render it as wireframe */ gluQuadricDrawStyle(p, GLU_LINE); }
void menu(int id){ if(id == 1 ) axis=0; if(id == 2) axis=1; if(id == 3 ) axis=2; if(id ==4 ) exit(0); } void myReshape(int w, int h){ glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-10.0, 10.0, -5.0 * (GLfloat) h / (GLfloat) w, 15.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-10.0 * (GLfloat) w / (GLfloat) h, 10.0 * (GLfloat) w / (GLfloat) h, -5.0, 15.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);
//p: 양의 방향으로 5도 회전 n 음의 방향으로 5도 회전 void keyboard(unsigned char key, int x, int y) { switch(key){ case 'p': theta[axis] += 5.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; } break; case 'n': theta[axis] -= 5.0; if( theta[axis] <- 360.0 ) theta[axis] += 360.0; display();
void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("robot"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutCreateMenu(menu); glutAddMenuEntry("base", 1); glutAddMenuEntry("lower arm", 2); glutAddMenuEntry("upper arm", 3); glutAddMenuEntry("quit", 4); glutAttachMenu(GLUT_MIDDLE_BUTTON); glutMainLoop(); }
로봇 TORSO_HEIGHT 5.0 UPPER_ARM_RADIUS 0.5 LOWER_ARM_RADIUS 0.3 UPPER_ARM_HEIGHT 3.0 LOWER_ARM_HEIGHT 2.0 UPPER_LEG_RADIUS 0.5 LOWER_LEG_RADIUS 0.3 UPPER_LEG_HEIGHT 3.0 LOWER_LEG_HEIGHT 2.0 TORSO_RADIUS 1.0 HEAD_HEIGHT 1.5 HEAD_RADIUS 1.0
프로그램 figure.cpp 참조 각 부분의 동작 동작제어 torso: y축을 중심으로 좌우로 5도씩 회전 head: 1) x축 중심으로 앞뒤로 5도씩 회전 2) y축 중심으로 좌우로 5도씩 회전 나머지 부분은 x축 중심으로 앞뒤로 5도씩 회전 동작제어 메뉴로 동작할 부분 선택 p는 +방향, n은 –방향으로 회전하도록
로봇 애니메이션
동작제어 마우스 왼쪽버튼=> x의 양의 방향으로 이동 마우스 오른쪽 버튼=> 이동을 멈춘다. 윈도우 오른쪽으로 사라지면 윈도우 왼쪽으로 다시 나타나도록 팔과 다리는 좌우로 30도씩 움직이도록
TORSO_HEIGHT 5.0 UPPER_ARM_HEIGHT 2.5 LOWER_ARM_HEIGHT 2.0 UPPER_LEG_RADIUS 0.5 LOWER_LEG_RADIUS 0.3 UPPER_LEG_HEIGHT 3.0 LOWER_LEG_HEIGHT 2.0 TORSO_RADIUS 1.0 UPPER_ARM_RADIUS 0.5 LOWER_ARM_RADIUS 0.3 HEAD_HEIGHT 1.5 HEAD_RADIUS 1.0
static GLfloat theta[11] = { 70.0, 0.0, 0.0, 180.0, 0.0, 180.0, 0.0, 180.0, 0.0, 180.0, 0.0}; static GLfloat posx=0; float chain=0; void idle(void){ if(chain==0) //플래그를 두어 양다리를 번갈아 가게 구현 // 이동에 대하여 생각해 작성할 것 display(); } void mouse(int btn, int state, int x, int y){ if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) //작성할 것