General/Graphics / Vision
[컴퓨터그래픽스] 스탠드 그리기
croute
2010. 10. 19. 00:43
glu 파일에는 3d 물체를 그리는 함수들이 여럿있다.
이 함수들을 이용해서 스탠드를 그리려고 한다.
먼저 오브젝트 포인터가 필요해서 선언해주자.
GLUquadricObj *qobj; |
그리고 요놈들도 있어야 되니까. 선언해주고 설정한다.
qobj = gluNewQuadric(); // Quadric 객체 속성 설정 함수 gluQuadricDrawStyle(qobj, GLU_LINE); // 포인터랑 속성을 설정해줄 인자를 넘긴다. |
여기서 잠깐 gluQuadricDrawStyle() 함수에 대해 알아보자.
gluQuadricDrawStyle() 함수 원형 -
void gluQuadricDrawStyle(GLUquadricObj *obj, GLenum drawStyle); |
첫번째 인자 : Quadric에 대해 속성을 설정해줄 포인터 변수.
두번째 인자 : GLU_FILL | FLU_LINE | GLU_SILHOUETTE | GLU_POINT
GLU_LINE
Wire frame
GLU_FILL
Solid
GLU_POINT
point(점)
GLU_SILHOUETTE
외부모서리(선)만 그림
자 이제 할거 했으니,
여러 3D 물체를 그리는 함수들을 알아보자.
실린더
gluCylinder(포인터 변수, baseRadius, topRadius, Height, slices, stacks);
구
glutWireSphere(radius, slices, stack);
glutSolidSphere(radius, slices, stack);
원뿔
glutWireCone(base, height, slices, stacks);
glutSolidCone(base, height, slices, stacks);
: slices - wire 도형에서 세로로 그어지는 wire
: stacks - wire 도형에서 가로로 쌓이는 wire
토러스(이거 뭐랄까..... 도넛같이 생긴 그런거..)
glutWireTorus(innerRadius, outterRadius, sides, rings);
glutSolidTorus(innerRadius, outterRadius, sides, rings);
주전자
glutWireTeapot(size);
glutSolidTeapot(size);
그리려는 목표는 이런 모양의 스탠드이다.
뭐... 그림판으로 그려서 폼새가 안나긴 하지만... ㅡㅡ;;;;;
우선 세가지의 부분으로 나누었다.
윗부분, 몸통부분, 바닥부분.
몸통부터 그려보자.
void draw_body()
{
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_LINE);
gluCylinder(qobj, 100, 100, 300, 20, 20); // 실린더. 스탠드의 body.
} |
자 이렇게 몸통부분을 그렸다. 지금은 뭐 그냥 외형만 비슷하게 하려는 거라.
뚜껑의 구멍난 갓 부분을 그려보자.
원뿔을 이용할수도 있지만, 실린더를 이용해 윗부분의 너비를 작게해서 그렸다.
void draw_top()
{
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_LINE);
gluCylinder( qobj, 50, 300, 300, 20, 20); // 실린더, 위와 아래의 너비가 다름, 갓 부분.
} |
마지막으로 밑의 받침대는 토러스로 그려보았다.
위의 실린더는 여러 선언들이 필요하지만, 토러스는 숫자들만 있으면 되니깐.
void draw_bottom()
{
glutWireTorus(100, 200, 20,20); // (inner, outter, side, ring)
} |
자 이제 합쳐보자.
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(theta, 0.0, 1.0, 0.0);
glColor3f (1.0, 0.0, 1.0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_body();
glPopMatrix();
glPushMatrix();
glTranslated(0, 250, 0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_top();
glPopMatrix();
glPushMatrix();
glTranslated(0, -300, 0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_bottom();
glPopMatrix();
glFlush();
glutSwapBuffers();
} |
여기가 중요하다.
실제로 각 객체들을 출력해 줄때는,
glPushMatrix();를 해주고, 그 객체 그리기가 끝나면
glPopMatrix();를 해주어야 한다.
안 그러면 Rotation한 거나, Translation한거, Scaling한게, 다음 그릴 객체에까지 영향을 미친다.
중요한 포인트 또 하나는 푸시, 팝을 하고 나면, 객체는 처음 위치에 똑같이 그려진다는 것이다.
그래서 로테이트를 하고 트랜슬레이트를 해서 위치를 옮겨주어야 한다.
아래 실제 전체 코드가 있다.
// include 되있는 것중 안써도 되는것도 있다. 이런거 저런거 수업시간에 하던거 연결해서 하느라...
- 전체코드 -
#include <glut.h>
#include <glu.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
// 포인터변수필요
GLUquadricObj *qobj;
void draw_body()
{
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_LINE);
gluCylinder(qobj, 100, 100, 300, 20, 20); // 실린더. 스탠드의 body.
}
void draw_top()
{
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_LINE);
gluCylinder( qobj, 50, 300, 300, 20, 20); // 실린더, 위와 아래의 너비가 다름, 갓 부분.
//실린더( baseRadius, topRadius, height, slices, statck )
}
void draw_bottom()
{
glutWireTorus(100, 200, 20,20); // (inner, outter, side, ring)
}
//void draw_teapot()
//{
// glutWireTeapot(50);
//}
//=====================================
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(theta, 0.0, 1.0, 0.0);
glColor3f (1.0, 0.0, 1.0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_body();
glPopMatrix();
glPushMatrix();
glTranslated(0, 250, 0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_top();
glPopMatrix();
glPushMatrix();
glTranslated(0, -300, 0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_bottom();
glPopMatrix();
/*
glPushMatrix();
glTranslated(400, 200, 0);
glRotatef(90, 1.0, 0.0, 0.0);
draw_teapot();
glPopMatrix();
*/
glFlush();
glutSwapBuffers();
}
void init(void)
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.0,0.8,1.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-500.0, 700.0, -500.0, 700.0, 0.0, 1000.0);
gluLookAt(200, 200, 200,
0, 0, 0,
0, 1, 0);
}
int main(int argc , char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow(" 3D Objects");
init();
glutDisplayFunc(display);
//glutIdleFunc(rotate);
glutMainLoop();
return 0;
}
|
↑ 요렇게 해서 그리면 ↓ 이런 결과물이 나온다.