상태 관리 및 기하 오브젝트 그리기.

Slides:



Advertisements
Similar presentations
10-7 부동소수점 (Floating-Point) 계산  컴퓨터에서 숫자를 표기하는 방법  가수 (Fraction) : 부호화된 고정소수점 숫자 지수 (Exponent) : 소수점의 위치를 표시 ( 예 )10 진수 를 표기하면 Fraction Exponent.
Advertisements

1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
1. 도형의 연결 상태 2. 꼭지점과 변으로 이루어진 도형 Ⅷ. 도형의 관찰 도형의 연결상태 연결상태가 같은 도형 단일폐곡선의 성질 연결상태가 같은 입체도형 뫼비우스의 띠.
Chapter 3. 뷰잉(Viewing).
Chapter 4 컬러( COLOR ) 학기 가상현실.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
OpenGL 실습 1주차.
김태원 심재일 김상래 강신택. 김태원 심재일 김상래 강신택 인터넷 통신망의 정보를 제공하는 서비스 인터넷의 자원 및 정보는 NIC가 관리 IP주소 또는 도메인으로 정보 검색 이용자 및 통신망 관한 정보를 제공.
Chapter 5. 라이팅(Lighting)
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
7장 디스플레이 리스트.
Chap 9. 텍스쳐(Texture).
연결리스트(linked list).
제 9 장 구조체와 공용체.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
5장. 참조 타입.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
Error Detection and Correction
멀티미디어 시스템 (아날로그 이미지,신호를 디지털로 변환 방법) 이름 : 김대진 학번 :
23장. 구조체와 사용자 정의 자료형 2.
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
4. OpenGL 상태들과 기본 도형들.
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
C#.
JA A V W. 03.
프로그래밍 개요
Chapter03 캔버스(1) HTML5 Programming.
박성진 컴퓨터 프로그래밍 기초 [09] 배열 part 1 박성진
광원 제어 하기.
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
Draw the basic Geometry Objects
Java의 정석 제 5 장 배 열 Java 정석 남궁성 강의 의
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
Chapter 4 컬러( COLOR ).
3D 프린팅 프로그래밍 01 – 기본 명령어 강사: 김영준 목원대학교 겸임교수.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
Clipping 이진학.
다면체 다면체 다면체: 다각형인 면만으로 둘러싸인 입체도 형 면: 다면체를 둘러싸고 있는 다각형
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
Choi Seong Yun 컴퓨터 프로그래밍 기초 #03 : 변수와 자료형 Choi Seong Yun
Canary value 스택 가드(Stack Guard).
Teaming pms.
데이터 동적 할당 Collection class.
4장. 데이터 표현 방식의 이해. 4장. 데이터 표현 방식의 이해 4-1 컴퓨터의 데이터 표현 진법에 대한 이해 n 진수 표현 방식 : n개의 문자를 이용해서 데이터를 표현 그림 4-1.
Chapter 1 단위, 물리량, 벡터.
Chapter 1 단위, 물리량, 벡터.
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
세션에 대해 알아보고 HttpSession 에 대해 이해한다 세션 관리에 사용되는 요소들을 살펴본다
함수, 모듈.
Summary of Pointers and Arrays
9 브라우저 객체 모델.
컴퓨터공학과 손민정 Computer Graphics Lab 이승용 교수님
바이트 순서 변환 함수 주소 변환 함수 바이트 조작 함수 원격지 호스트 정보를 얻는 함수
제 4 장 Record.
어서와 C언어는 처음이지 제21장.
SEOUL NATIONAL UNIVERSITY OF SCIENCE & TECHNOLOGY
버스와 메모리 전송 버스 시스템 레지스터와 레지스터들 사이의 정보 전송을 위한 경로
13. 포인터와 배열! 함께 이해하기.
7 생성자 함수.
6 객체.
Lecture #6 제 4 장. 기하학적 객체와 변환 (1).
BoardGame 보드게임 따라가기.
20 XMLHttpRequest.
Presentation transcript:

상태 관리 및 기하 오브젝트 그리기

상태 관리 및 기하 오브젝트 그리기 드로잉 서바이벌 킷 점, 선, 폴리곤 표현하기 기본 상태 관리 점, 선, 폴리곤 디스플레이 하기 법선 벡터 정점 배열 속성 그룹 곡면을 폴리곤 모델로 만들 때 유용한 테크닉 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

드로잉 서바이벌 킷 윈도우 클리어, 오브젝트 컬러 설정, 드로잉 실행 방법 윈도우 클리어 하기 새로운 그림을 그리기 전에 반드시 원하는 배경색으로 화면을 클리어 해 야 한다. 간단한 예를 들면 다음과 같은 두 라인의 코드를 통해 RGBA 모드 윈도우 를 검은색으로 클리어 한다. glClearColor(0.0, 0.0, 0.0, 0.0); /*클리어 색을 검은색으로 지정*/ glClear(GL_COLOR_BUFFER_BIT); /*설정된 색으로 윈도우 클리어*/ glClear() 의 매개변수는 클리어할 버퍼를 가리킴 클리어 컬러는 상태변수로 관리되므로 매번 클리어 컬러를 지정하지 않아 도 됨 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

컬러버퍼 이외의 다른 버퍼도 클리어 할 수 있다. 컬러버퍼와 깊이버퍼 클리어 컬러버퍼 이외의 다른 버퍼도 클리어 할 수 있다. 컬러버퍼와 깊이버퍼 클리어 glClearColor (0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); /*깊이 버퍼의 모든 픽셀에 설정될 초기값 지정*/ glCear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

GL_STENCIL_BUFFER_BIT void glClearColor(GLclampf red, GLclampf green, GLclampf bule, GLclampf alpha); RGBA 모드의 컬러 버퍼를 클리어 하는데 사용. 각 인자 값은 [0 – 1]값을 가진다. 디폴트는(0, 0, 0, 0)인 검은색 void glClear(GLbitfield mask); 지정한 버퍼를 현재 클리어 값으로 클리어, OR 연산 가능 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 버퍼 이름 컬러 버퍼 GL_COLOR_BUFFER_BIT 깊이버퍼 GL_DEPTH_BUFFER_BIT 누적 버퍼 GL_ACCUM_BUFFER_BIT 스텐실 버퍼 GL_STENCIL_BUFFER_BIT 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

컬러 지정하기 특정한 기하 오브젝트를 그릴 때마다 현재 지정된 컬러를 사용, 지 정한 컬러를 변경하지 않는 한 모든 오브젝트들은 앞서 지정한 컬 러로 그려짐 set_current_color(red): draw_object( A ); draw_object( B ); set_current_color(green); set_current_color(blue); draw_object( C ); A 와 B는 빨간색으로 그림, C는 파란색으로 그림. 실제 4번째 라인은 아무런 영향을 주지 않는다. glColor3f()는 컬러를 지정할 때 사용 . 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glColor3f(0. 0, 0. 0, 0. 0); 검정색(black) glColor3f(1. 0, 0. 0, 0 glColor3f(0.0, 0.0, 0.0); 검정색(black) glColor3f(1.0, 0.0, 0.0); 빨간색(red) glColor3f(0.0, 1.0, 0.0); 초록색(green) glColor3f(1.0, 1.0, 0.0); 노란색(yellow) glColor3f(0.0, 0.0, 1.0); 파란색(blue) glColor3f(1.0, 0.0, 1.0); 자홍색(magenta) glColor3f(0.0, 1.0, 1.0); 청록색(cyan) glColor3f(1.0, 1.0, 1.0); 하얀색(white) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

드로잉 연산을 강제로 실행시키기 클라이언트로 하여금 패킷이 다 채워지지 않더라도 강제로 전송하는 glFlush()라는 커멘드 제공. glFlush()를 호출하면 드로잉이 끝날 때까지 기다리지 않는다. void glFlush(void); glFlush()만으로 부족할 경우 glFinish()를 사용 요청된 커맨드들을 네트워크로 전송한 다음에 그래픽 하드웨어나 네트워크로부터 요청한 그림을 프레임 버퍼에 다 그렸다는 확인 메 시지가 올 때까지 기다림. 이 커맨드를 호출 후에는 그래픽 하드웨어로 부터 모든 드로잉이 끝 났다는 응답을 받기 전까지 모든 그래픽스 프로세스들이 멈추게 된 다. void glFinish(void); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

좌표계 서바이벌 킷 윈도우의 위치나 크기를 변경할 때마다 glutReshapeFunc()로 등록한 루틴 실행 등록된 콜백 함수들은 다음 조건을 만족해야 한다. 새로운 렌더링 캔버스가 될 사각형 영역을 다시 설정 오브젝트를 그릴 때 사용할 좌표계 정의 ex ) glutReshapeFunc(reshape); reshape 콜백 함수 void reshape(int w, int h) { glViewport(0,0, (GLsizei) w, (GLsizei) h); //드로잉을 위한 픽셀 사각형 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); // 좌표축 지정, (0,0) ~ (w, h) } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glViewport()는 드로잉을 위한 픽셀 사각형을 새로운 윈도 우의 전체역영으로 설정, reshape()에 전달한 w와 h값은 모눈종이의 가로와 세로로 그려진 사각형의 개수, gluOrtho2D()는 가장 아래의 왼쪽 끝에 있는 사각형이 있 는 지점을 원점(0,0)으로 지정 (50,50) (0, 0) w = 50, h = 50으로 정의한 좌표계 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

점, 선, 폴리곤 표현하기 점 점은 정점(vertex, 점의 위치, 선분의 양 끝 점, 폴리곤의 모서리 등을 나타내는 좌표) 이라고 부르는 부동 소수점 수들의 집합으 로 표현 모든 내부 연산은 3차원으로 가정하기때문 에 2차원으로 표현하더라도 OpenGL에서 는 z=0으로 할당. 선 OpenGL에서 선(line)은 선분(segment)를 의미한다. 선은 양 끝점에 대한 정점으로 표현 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

폴리곤 폴리곤(polygon)은 여러 개의 선분들이 연 속적으로 이어진, 하나의 닫힌 루프 (closed loop)로 둘러싸인 영역이다. 폴리곤 제한 사항 폴리곤의 경계를 이루는 선분들이 서로 교차하지 않아야 한다. 폴리곤은 반드시 볼록(convex)해야 한다 폴리곤의 경계를 이루는 선분들의 수에는 제한이 없다. 내부에 구멍이 난 폴리곤은 표현할 수 없다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

사각형 OpenGL에서는 속이 채워진 사각형을 그리 는 glRect*()(*는 다른 여러 종류의 함수 포 함) 커맨드를 제공하고 있다. void glRect{sifd}(TYPE x1, TYPE y1, TYPE x2, TYPE y2); void glRect{sifd}v(TYPE *v1, TYPE *v2); 첫 번째 함수는 (x1,y1)과 (x2, y2)를 모서리 로 같은 사각형을 그린다. 두 번째 루틴은(x, y)좌표를 표현하는 배열 두 개에 대한 포인터를 인자로 넘긴다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

곡선과 곡면 모든 곡선과 곡면들은 임의의 정확도에 따 라 짧은 선분들이나 조그만 폴리곤들로 근 사치를 구하여 표현한다. 곡선이나 곡면은 OpenGL 기하 프리미티브 에 해당하지는 않지만 직접 그릴 수 있는 기능을 제공 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

모든 기하 오브젝트들은 정점들의 집합으로 표현. glVertex*()라는 커맨드 사용 정점 지정하기 모든 기하 오브젝트들은 정점들의 집합으로 표현. glVertex*()라는 커맨드 사용 glVertex{234}{sifd}[v](TYPE coords); glVertex*() 커맨드는 glBegin() 과 glEnd() 사이에서 호출할 때만 작동. 사용법 glVertex2s(2,3);                 /* (2,3,0) 좌표를 나타냄 */ glVertex3d(0.0, 0.0, 3.1415926535898);   /* 좌표값을 부동소수점으로 함 */ glVertex4f(2.3, 1.9, -2.2, 2.0);       /* 3차원 좌표를 동차좌표(homogeneous coordinates)로 표현 */ GLdouble dvect[3] = {5.0, 9.0, 1992.0}; glVertex3dv(dvect);            /* 세 개의 배정도 부동 소수점 수를 담고    /* 있는 배열에 대한 포인터 dvect 정점을 지정 */ 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

OpenGL 기하 드로잉 프리미티브 정점을 지정한 커맨드를 glBegin() 과 glEnd() 커맨드로 묶어줌 폴리곤 그리는 방법       glBegin(GL_POLYGON);         glVertex(0.0, 0.0);          glVertex(0.0, 3.0);         glVertex(4.0, 3.0);         glVertex(6.0, 1.5);         glVertex(4.0, 0.0); glEnd(); GL_POLYGON 대신 GL_POINTS를 입력하면 점만 찍히게 된다.                        GL_POLYGON            GL_POINTS 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glBegin(GLenum mode); 기하 프리미티브의 이름과 의미 값 의미 GL_POINTS 독립적인 점 GL_LINES 독립적이 선분으로 해석되는 두 개의 정점들의 쌍 GL_LINE_STRIP 연결된 선분 GL_LINE_LOOP 마지막 정점과 첫 번째 정점을 연결하는 선분이 추가된 GL_LINE_STRIP GL_TRIANGLES 삼각형으로 해석되는 세 개의 정점들의 쌍 GL_TRIANGLES_STRIP 연결된 삼각형 스트립 GL_TRIANGLE_FAN 연결된 삼각형 팬 GL_QUADS 네 개의 모서리를 가진 폴리곤으로 해석되는 네 개의 정점들의 쌍 GL_QUAD_STRIP 연결된 사변형 스트립 GL_POLYGON 단순, 볼록 폴리곤 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glBegin() 및 glEnd() 사용에 대한 제한 사항 void glEnd(void); 이 커맨드는 정점 데이터 리스트가 끝났다 는 것을 표시한다. glBegin() 및 glEnd() 사용에 대한 제한 사항 표2-3 에 나오지 않은 커맨드들이 glBegin() 과 glEnd()사이에 오면 에러가 발생, 그러나 OpenGL 커맨드가 아니면 사용가능. glEnableClientState()와 glVertexPointer() 등 과 같이 일부 정점 관련 커맨드는 에러는 발 생하지 않으나 제대로 작동하지 않음. OpenGL 커맨드 외에 다른 프로그래밍 언어 의 구문은 얼마든지 넣을 수 있음. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

표2-3 glBegin()과 glEnd() 사이에 나올 수 있는 커맨드들 커맨드 목적 glVertex*() 정점 좌표를 설정한다. glColor() 현재 컬러를 설정한다. glIndex() 현재 컬러 인덱스를 설정한다. glNormal*() 법선 벡터 좌표를 설정한다. glTexCoord*() 텍스처 좌표를 설정한다. glMultiTexCoord*ARB() 다중 텍스처를 위한 텍스처 좌표를 설정한다. glEdgeFlag*() 모서리 그리기를 제어한다. glMaterial*() 재질 속성을 설정한다. glArrayElement() 정점 배열 데이터를 얻는다. glEvalCoord*(), glEvalPoint*() 좌표를 생성한다 glCallList(), glCallLists() 디스플레이 리스트를 실행한다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

기본 상태 관리 상태 및 상태변수 void glEnable(GLenum cap); /* 지정한 기능을 켤 때 */ 물체를 렌더링 할 때 라이팅이나 텍스처링, 은면 제거, 안개 효과 등을 사용할지 여 부를 결정 void glEnable(GLenum cap); /* 지정한 기능을 켤 때 */ void glDisable(GLenum cap); /* 지정한 기능을 끌 때 */ 열거값의 종류(40가지 중) GL_BLEND(RGBA값의 블렌딩 제어), GL_DEPTH_TEST(깊이값 비교 연산을 제어, 깊이 버퍼를 갱신) GL_FOG(안개효과 제어) GL_LINE_STIPPLE(선을 패턴 형태로 표현) GL_LIGHTING 등. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

상태가 활성화 되어 있는지 비활성되어 있는지 체크, 활성화 여부에 따라 GL_TRUE 나 GL_FALSE를 반환. GLboolean glIsEnabled(GLenum capability) 좀더 복잡한 상태변수에 대해 특정한 값을 설정 가능 ex) glColor3f() 와 같은 루틴은 GL_CURRENT_COLOR상태를 구성 하는 세 개의 값을 설정. 설정 값 확인에는 다음과 같은 다섯 가지 루틴 사용 void glGetBooleanv(GLenum pname, GLboolean *params); void glGetIntegerv(GLenum pname, GLint *params); void glGetFloatv(GLenum pname, GLfloat *params); void glGetDoublev(GLenum pname, GLdouble *params); void glGetPointerv(GLenum pname, GLvoid **params); 각 루틴은 상태 변수의 불리언, 정수, 부동소수점, 배정도 부동소수 점, 포인터 타입값 반환 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

예 glGetIntegerv(GL_CURRENT_COLOR, params) glGetFloatv(GL_CURRENT_COLOR, params) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

점, 선, 폴리곤 디스플레이 하기 디폴트로 점은 스크린의 한 픽셀로, 선 은 한 픽셀 굵기의 솔리드 형태로 폴리 곤은 솔리드 방식의 속이 채워진 형태 로 그려짐. 점 점의 크기는 glPointSize()로 원하는 점의 크 기를 픽셀 단위로 전달해서 조절 void glPointSize(GLfloat size); size는 0.0보다 커야 하고 기본값은 1.0 안티앨리어스 활성화에 따라 점의 모양이 달라짐 디폴트는 비활성화되어 있어서 1.0이면 1x1픽셀 크기의 사각형, 2.0이면 2x2의 사각형이 그려짐 활성화되어 있으면 원형 그룹 형태의 픽셀이 그려짐 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

선 선의 폭 선의 폭과 스티플(stipple) 형태(점선, 대시, 안티앨리어싱된 점선 및 대시 등)를 다양하 게 지정 void glLineWidth(GLfloat width); 그릴 선의 굵기를 픽셀 단위로 지정한다. width는 반드시 0.0 보다 커야 하고, 기본값 은 1.0이다. 안티앨리어싱 모드에 영향을 받음 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

스티플 라인 스티플(점 또는 대시)형태의 선을 그리기 위해서는 먼저 glLineStipple() 커맨드로 스 티플 패턴을 지정한 후 glEnable()로 활성화 시켜주면 된다. glLineStipple(1, 0x3f07); // 0011111100000111 glEnable(GL_LINE_STIPPLE); void glLineStipple(GLint factor, GLushort pattern); 스티플 기능은 반드시 glEnable()에 GL_LINE_STIPPLE인자를 전달하여 활성화 시켜야만 동작한다. 사용할 패턴은 pattern 인자에 16비트 이진 수로 표현하여 그리게 될 선의 길이만큼 패 턴이 계속 반복됨. 1은 선이 그려지는 부분 을 0은 선이 그려지지 않는 부분을 픽셀 단 위로 나타냄 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

factor 인자는 지정한 패턴을 확장할 때 사용 패턴이 0x3F07의 경우 0011111100000111 에서 처음 3 픽셀이 그려지고 다음 5 픽셀은 안그려지고 그 다음 6 픽셀은 그려지고 그 다음 2 픽셀은 안그려짐 순서는 낮은 자리 부터 시작 factor 가 2의 경우엔 처음 6 픽셀이 그려지고 다음 10 픽셀은 안그려지고 그 다음 12 픽셀은 그려지고 그 다음 4 픽셀은 안그려짐 스티플 기능을 활성화하지 않을 경우에는 pattern 인자는 0xFFFF 이 고 factor 인자는 1 인 것처럼 그려짐 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

그림2-8 스티플 라인 PATTERN FACTOR 0x00FF 1 ------- -------- -------- ------- --------- 2 --------------- ---------------- --------- 0xC0FF ------ --- -------- --- -------- --- ---- 3 --------------- --------------- ------------ 0xAAAA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----- ----- ----- ----- ----- ----- ----- ----- 4 -------- -------- -------- -------- -------- 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

라인 스티플 패턴 #include <GL/glut.h> #include <stdlib.h> #define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES); glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd(); void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glClear (GL_COLOR_BUFFER_BIT); void display(void) { int i; glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); /* 모든 선의 색을 흰색으로 지정한다 */ glEnable (GL_LINE_STIPPLE); /* 첫 번째 행, 다른 스티플을 사용한 3개의 선 */ glLineStipple (1, 0x0101); /* dotted */ drawOneLine (50.0, 125.0, 150.0, 125.0); glLineStipple (1, 0x00FF); /* dash */ drawOneLine (150.0, 125.0, 250.0, 125.0); glLineStipple (1, 0x1C47); /* dash/dot/dash */ drawOneLine (250.0, 125.0, 350.0, 125.0); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glLineWidth (5. 0); /. 두 번째 행, 각기 다른 스티플을 사 용한 3개의 굵은 선 glLineWidth (5.0); /* 두 번째 행, 각기 다른 스티플을 사 용한 3개의 굵은 선*/ glLineStipple (1, 0x0101); /* dotted */ drawOneLine (50.0, 100.0, 150.0, 100.0); glLineStipple (1, 0x00FF); /* dashed */ drawOneLine (150.0, 100.0, 250.0, 100.0); glLineStipple (1, 0x1C47); /* dash/dot/dash */ drawOneLine (250.0, 100.0, 350.0, 100.0); glLineWidth (1.0); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

/. 세 번째 행, dash/gotted/dash/ 스티플로 그린 여섯 개의 선. / / /* 세 번째 행, dash/gotted/dash/ 스티플로 그린 여섯 개의 선 */ /* 이들을 하나의 연결된 라인 스트립으 로 그린다. */ glLineStipple (1, 0x1C47); /* dash/dot/dash */ glBegin (GL_LINE_STRIP); for (i = 0; i < 7; i++) glVertex2f (50.0 + ((GLfloat) i * 50.0), 75.0); glEnd (); /* 네 번째 행, 동일한 스티플로 그린 6개 의 독립적인 선 */ for (i = 0; i < 6; i++) { drawOneLine (50.0 + ((GLfloat) i * 50.0), 50.0, 50.0 + ((GLfloat)(i+1) * 50.0), 50.0); } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

/. 다섯번 째 행, dash/dot/sash/ 스티플을 사용하고 스티플 반복 팩터로 5를 지정 /* 다섯번 째 행, dash/dot/sash/ 스티플을 사용하고 스티플 반복 팩터로 5를 지정 */ glLineStipple (5, 0x1C47); /* dash/dot/dash */ drawOneLine (50.0, 25.0, 350.0, 25.0); glDisable (GL_LINE_STIPPLE); glFlush (); } void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

void keyboard(unsigned char key, int x, int y){ switch (key) case 27: exit(0); break; } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (400, 150); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

폴리곤의 세부사항 일반적으로 폴리곤은 안쪽이 픽셀들로 채워진 형태. 이것을 점 표현, 윤곽선만 그릴 수도 있으며 패턴 채우기 가능. 점이나 외곽선 또는 솔리드 형태의 폴리곤 폴리곤은 앞면과 뒷면의 두면으로 구성, 기본 설정으로는 앞면과 뒷면이 동일한 방식으로 그려짐 이를 변경하거나 윤곽, 정점만을 그릴 때 glPolygonMode() 설정 void glPolygonMode(GLenum face, GLenum mode); 폴리곤의 앞면과 뒷면을 그리는 모드를 제어 디폴트: 앞면과 뒷면이 채워진 형태 face : GL_FRONT_AND_BACK, GL_FRONT, GL_BACK 등 mode : GL_POINT, GL_LINE, GL_FILL 등 앞면은 채워진 형태로, 뒷면은 윤곽선 형태로 그릴 경우에는 glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_LINE); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

일반적으로 폴리곤의 정점들이 반시 계 방향으로 나타나 있을 때 앞을 향 하고 있다. 폴리곤 면 뒤집기 및 컬링 일반적으로 폴리곤의 정점들이 반시 계 방향으로 나타나 있을 때 앞을 향 하고 있다. 앞면을 향하는 폴리곤을 판단하는 방 법 제어 void glFrontFace(GLenum mode); mode : GL_CCW(반시계 방향), GL_CW(시 계 방향) 컬링(Culling) 뒷면에 해당하는 폴리곤들을 처리하지 않도록 컬링(culling)을 활성화. 뷰어가 항상 내부만 보는 경우에는 폴리 곤 뒷면만 보므로 앞면을 제거해줄 수도 있음 앞면을 향하는 폴리곤이나 뒷면을 향하 는 폴리곤을 제거하려면 glCullFace() 커맨드를 호출한 뒤 glEnable()로 컬링 기능 활성화 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glCullFace(GLenum mode); 스크린 좌표로 변환되기 전에 제거할 폴리 곤을 지정한다. mode : GL_FRONT(앞면을 향한 폴리곤) GL_BACK(뒷면을 향한 폴리곤) GL_FRONT_AND_BACK(모 든 폴리곤) 등이 있다. 실제로 동작하기 위해서는 glEnable()에 GL_CULL_FACE 인자를 주고 호출하여 컬링 기능을 활성화 컬링 비활성화는 glDisable()에 동일한 인자를 주고 호출하면 된다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

폴리곤 스티플링 채워진 폴리곤은 디폴트로 솔리드 패턴으로 그려지도록 설정 glPolygonStipple()을 사용하면 32 * 32 비트의 윈도우 정렬(window-aligned) 스 티플 패턴으로 채워넣을 수 있다. void glPolygonStipple(const GLubyte *mask); mask 는 비트맵에 대한 포인터로 0 과 1의 마스크로 사용된다. 1은 폴리곤의 해당 영역에 픽셀이 그려지는 것을 의미 0은 반대로 아무 것도 그려지지 않는 것을 의미 폴리곤 스티플링의 활성화 및 비활성화 glEnable() 과 glDisable()에 GL_POLYGON_STIPPLE을 인자로 주고 호출 폴리곤 스티플 패턴을 지정한 다음에는 반드시 다음과 같이 스티플 기능 을 활성화 해야 함. glEnable(GL_POLYGON_STIPPLE); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

폴리곤 스티플 패턴: poly.c void display(void){ GLubyte fly[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08;} 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

GLubyte halftone[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55;} 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glClear (GL_COLOR_BUFFER_BIT); glColor3f (1. 0, 1. 0, 1. 0); / glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); /* 솔리드 형태의 스티플이 적용되지 않 은 사각형 그림, 그런다음, 두 개의 스티 플 사각형을 그림 */ glRectf (25.0, 25.0, 125.0, 125.0); glEnable (GL_POLYGON_STIPPLE); glPolygonStipple (fly); glRectf (125.0, 25.0, 225.0, 125.0); glPolygonStipple (halftone); glRectf (225.0, 25.0, 325.0, 125.0); glDisable (GL_POLYGON_STIPPLE); glFlush (); } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

void init (void) { glClearColor (0. 0, 0. 0, 0. 0, 0 void init (void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

void keyboard(unsigned char key, int x, int y){ switch (key) case 27: exit(0); break; } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (350, 150); glutCreateWindow (argv[0]); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

폴리곤의 경계 모서리 표시하기 오목한 폴리곤은 볼록한 폴리곤으로 분할한 뒤에 각각 그리는데, 이 경우에는 삼각형 윤곽선들이 폴리곤 내부에 있어서 glPolygonMode() 를 사용하여 그릴 수 없다. 이 문제 해결을 위해 특정한 정점이 경계선에 놓여있는지 여부를 OpenGL에게 알려줄 수 있다. 이러한 상태에서 GL_LINE 모드로 그 림 디폴트로는 모든 정점들이 경계선에 놓여져 있다고 설정되어 있다. glEdgeFlag*() 커맨드로 이러한 엣지 플래그(edge flag) 설정을 직접 조 절할 수 있다. glBegin() 과 glEnd() 사이에서 사용, 폴리곤이나 삼각형, 사변형에 대한 정점에만 적용. void glEdgeFlag(GLboolean flag); void glEdgeFlag(const GLboolean *flag); flag를 GL_TRUE로 설정하면 GL_FALSE로 다시 호출 전까지 모든 정점 이 경계선에 놓여있다고 간주 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_POLYGON); glEdgeFlag(GL_TRUE); glVertex3fv(v0); glEdgeFlag(GL_FALSE); glVertex3fv(v1); glVertex3fv(v2); glEnd(); v2 v1 v0 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

법선 벡터(normal vertor) 법선 벡터(normal vector) 표면과 수직을 이루는 벡터 OpenGL 에서는 폴리곤이나 정점 단위로 법선을 지정할 수 있다. 법선은 반드시 정점에 대해서만 할당 오브젝트의 법선 벡터 표면의 방향을 나타냄(특히 광원에 대한 방향) 이 벡터를 이용하여 오브젝트의 각 정점이 받게 될 빛의 양 결정 법선의 설정 glNormal*()에 원하는 값은 인자로 주고 호출, 설정된 법선은 그 뒤에 나오는 glVertex*()로 지정된 정점에 할당. 법선은 각 정점마다 달라지기 때문에 glNormal*() 과 glVertex*()를 번갈아 호출 void glNormal3bsidf(TYPE nx, TYPE ny, TYPE nz); /* (nx, ny, nz). 백터 지정 */ void glNormal3{bsidf}v(const TYPE *v); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

각 정점에 대한 표면 법선 glBegin(GL_POLYGON); glNormal3fv(n0); glVertex3fv(v0); 각 정점에 대한 표면 법선 glBegin(GL_POLYGON); glNormal3fv(n0); glVertex3fv(v0); glNormal3fv(n1); glVertex3fv(v1); glNormal3fv(n2); glVertex3fv(v2); glNormal3fv(n3); glVertex3fv(v3); glEnd(); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

법선벡터 표면에 수직인 벡터 2 개 중에서 바깥 쪽을 향하는 것을 법선이라고 부른다. 법선은 어떠한 길이로 지정해도 무방 하며 라이팅 연산이 수행되기 전에 길 이가 1로 변환된다. => 단위 벡터 혹은 정규화된(normalized) 벡터라고 함 지정된 법선 벡터는 회전 변환이나 이 동 변환을 하더라도 변하지 않는다. 기울임 행렬로 곱하거나 크기 변환하 는 것과 같은 불규칙 변환을 수행하거 나 단위 길이를 가지지 않은 법선을 지 정할 경우, glEnable(GL_NORMALIZE)을 호출하여 변환을 수행한 후 OpenGL 에 서 자동으로 법선 벡터를 정규화하도 록 설정 단위 길이를 가진 법선을 지정하고 크 기 변환할 경우에는 glEnable(GL_RESCALE_NORMAL)을 사 용하여 변환을 수행한 후에 다시 단위 길이를 갖도록 모델뷰 변환으로부터 유도된 일정한 인자로 크기 변환해야 한다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

정점 배열 문제점 OpenGL에서 기하 프리미티브를 그리기 위 해서는 많은 함수를 호출해야 해서 오버헤 드 발생 인접한 폴리곤과 서로 공유하고 있는 정점 들이 중복되어 처리된다. 예 6개 면의 8개 정점 처리에 있어서 각 정점이 세번씩 지정되는 경우가 발생 8개 정점이 아니라 24개 정점 처리가 된다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

해결책: OpenGL 에서 제공하는 정점 배열 루틴 사용 많은 양의 정점 관련 데이터들을 단 몇 개의 배열에 저장 가능. 몇 번의 함수 호출만으로 이들 데이터에 접근할 수 있다. 정점 배열을 사용하여 오브젝트를 렌더링 하려면 세 단계를 거침. 배열을 활성화 한다. 배열의 각 원소로 정점 좌표, RGBA 컬러, 컬러인덱스, 표면법선, 텍스춰좌표, 폴리곤 엣지 플래그 등과 같은 다양한 타입의 데이터를 저장할 수 있다. 데이터를 배열에 저장. 배열의 원소는 포인터로 접근 가능. 킄라이언트 주소 공간에 저장. 저장된 데이터가 나타내는 기하 오브젝트를 그린다. 활성화된 배열에 대한 포인터 역참조를 통해 데이터를 얻는다. 이 데이터는 서버의 주소공간으로 전송됨. 각각의 배열 원소에 접근 각각의 배열 원소에 대한 리스트 작성 배열 원소들을 순차적으로 처리 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

1단계 - 배열 활성화 하기 배열을 활성화하기 위해 glEnableClientState()를 호출 void glEnableClientState(GLenum array); 활성화시킬 배열 저장 array 상수 GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_NORMAL_ARRAY, GL_TEXTURE_COORD_ARRAY, GL_EDGEFLAG_ARRAY 등 라이팅을 사용할 경우, 모든 정점에 대해 법선을 지정해야 한다. 이 때 정점 배열을 사용하려면 다음과 같이 표면 법선과 정점 좌표 배열 모두 활성화 glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

도중에 라이팅을 끄고 단일 컬러로 오 브젝트를 그릴 때 void glDisableClientState(GLenum array) 인자로 사용 가능한 상수는 glEnableClientState()와 같다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

2단계 - 배열에 저장할 데이터 지정하기 클라이언트는 하나의 배열을 하나의 커맨드로 직접 지정 가능. 클라이언트는 하나의 배열을 하나의 커맨드로 직접 지정 가능. OpenGL 에서는 배열을 지정하기 위한 6 가지 루틴 제공 void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer); void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer); void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

pointer 인자: 배열에 있는 첫 번째 정점의 첫 번째 좌표에 대한 메모리 주소를 가리킴 type 인자: 배열에 저장된 각 좌표의 데이 터 타입(GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE) size 인자: 하나의 정점에 사용할 좌표 수. 2, 3, 4 등 지정 stride 인자: 연속된 정점 사이의 바이트 오 프셋. 0이면 모든 정점들이 배열에 촘촘하 게 저장됨을 의미 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

정점 배열의 크기 및 데이터 타입 커맨드 크기 타입 glVertexPointer 2, 3, 4 GL_SHORT, GL_INT, GL_DOUBLE glNormalPointer 3 GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE glColorPointer 3, 4 GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, GL_DOUBLE glIndexPointer 1 GL_UNSIGNED_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE glTexCoordPointer 1, 2, 3, 4 GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE glEdgeFlagPointer type 인자를 사용하지 않음(데이터는 반드시 GLboolean 타입이어야 함) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

정점 배열 활성화 및 로딩: varray.c static GLint vertices[] = { 25, 25, 100, 325, 175, 25, 175, 325, 250, 25, 325, 325; } static GLfloat colors[] = { 1.0, 0.2, 0.2, 0.2, 0.2, 1.0, 0.8, 1.0, 0.2, 0.75, 0.75, 0.75, 0.35, 0.35, 0.35, 0.5, 0.5, 0.5; } 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_COLOR_ARRAY); glColorPointer (3, GL_FLOAT, 0, colors); glVertexPointer (2, GL_INT, 0, vertices); 클릭 전 클릭 후 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

간격 gl*Pointer() 루틴에서 사용하는 stride 매개 변수는 포인터 배열로 지정한 데이터를 OpenGL이 어떤 간격(stride)으로 접근해야 하는지를 지정. glColorPointer(3, GL_FLOAT, 6*sizeof(GLfloat), &intertwined[0]); 위의 예제에서는 배열의 첫부분에서(&inertwined[0])에서 시작해서 컬러 및 정점 좌표값의 크기인 6*sizeof(GLfloat)바이트 만큼 건너 뛰면서 참조하도록 지정 glVertexPointer(3,GL_FLOAT,6*sizeof(Glfloat) ,&interwined[3]) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

3단계 - 역참조 및 렌더링 하기 3단계에서는 배열의 내용을 얻은 후 이를 서버로 전송하고 렌더링을 위한 그래픽 프로세싱 파이프라인으로 넘어감. 이 때 데이터는 배열의 한 원소로부터 얻거나(인덱스로 지정), 배열의 원소에 대한 순서 리스트(전체 정점 배열 데이터의 일부분)로부터 얻 거나, 일련의 배열 원소로 부터 얻을 수 있다. 하나의 배열 원소에 대한 역참조 (1) void glArrayElement(GLint ith) 현재 활성화된 모든 배열의 ith 번째 정점에 대한 데이터를 얻는다. 정점 좌표 배열의 경우 glVertex[size][type]v() 커맨드에서 size: 2, 3, 4 중 하나 type: GLshort, GLint, GLfloat, GLdouble을 의미하는 s, i, f, d 중 하나 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glArrayElement()는 보통 glBegin()과 glEnd() 사이에서 호출한다. size 나 type은 glVertexPointer()로 지정 다른 활성화된 배열에 대해서는 glArrayElement(), glEdgeFlagv(), glTexCoord[size][type]v(), glColor[size][type]v(), glIndex[type]v(), glNormal[type]v() 등을 호출 glArrayElement()는 보통 glBegin()과 glEnd() 사이에서 호출한다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

예제 2-10 glArrayElement()로 컬러와 정점 지정하기 glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(3, GL_FLOAT, 0, colors); glVertexPointer(2, GL_INT, 0, vertices); glBegin(GL_TRIANGLES); glArrayElement(2); glArraryElement(3); glArrayElement(5); glEnd(); 위 코드는 다음과 동일한 효과: glColor3fv(colors + (2 * 3)); glVertex2iv(vertices + (2 * 2)); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glColor3fv(colors + (3. 3)); glVertex2iv(vertices + (3 glColor3fv(colors + (3 * 3)); glVertex2iv(vertices + (3 * 2)); glColor3fv(colors + (5 * 3)); glVertex2iv(vertices + (5 * 2)); glEnd() 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

배열 원소들의 리스트에 대한 역참조 (2) glDrawElements()나 glDrawRangeElements() 사용 배열 원소들의 리스트에 대한 역참조 (2) glDrawElements()나 glDrawRangeElements() 사용 일정한 규칙에 따라서 배열의 원소를 임 의로 접근할 때 유용. void glDrawElements(GLenum mode, GLsizei count, GLenum type, void *indices); count 인자: 기하 프리미티브 개수 지정 indices 인자: 기하 프리미티브의 인덱스 type 인자 : 지정한 배열의 데이터 타입을 가리키며 GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT 중에서 선택 mode 인자: 구성할 프리미티브의 종류, glBegin()이 받아들일 수 있는 값, 즉 GL_POLYGON, GL_LINE_LOOP, GL_POINTS 등과 같은 값에서 선택 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glDrawElements() 사용은 다음과 같은 효과를 얻음 int i; glBegin(mode); for (i = 0; i < count; i++) glArrayElement(indices[i]); glEnd(); glDrawElements()를 사용하면 육면체 각 면을 구성하는 정점들을 인덱스 배 열에 저장할 수 있다. 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

예제 2-11 glDrawElements() 사용법 1 static Glubyte frontIndices[] = {4, 5, 6, 7}; static Glubyte rightIndices[] = {1, 2, 6, 5}; static Glubyte bottomIndices[] = {0, 1, 5, 4}; static Glubyte backIndices[] = {0, 3, 2, 1}; static Glubyte leftIndices[] = {0, 4, 7, 3}; static Glubyte topIndices[] = {2, 3, 7, 6}; glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, frontIndices); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, rightIndices); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, bottomIndices); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, backIndices); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, leftIndices); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, topIndices); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

2 3 7 6 Front 5 4 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glDrawElements() 사용법 2 모든 인덱스를 한 큐에 처리할 수도 있 다 static Glubyte allIndices[] = {4, 5, 6, 7, 1, 2, 6, 5, 0, 1, 5, 4, 0, 3, 2, 1, 0, 4, 7, 3, 2, 3, 7, 6} glDrawElements(GL_QUADS, GL_UNSIGNED_BYTE, allIndices); glDrawElements() 를 glBegin() 과 glEnd() 사이에서 사용하면 에러 발생 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glDrawRangeElements() glDrawElements()와 마찬가지로 임의의 데이터 배열에 접근할 수 있다. 인덱스로 사용할 값의 범위를 지정 glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void *indices); mode: 프리미티브의 종류 count: 요소의 수 type: 데이터 타입 indices: 정점 데이터의 배열상의 위치 start, end: indices 로 허용된 값의 범위 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

연속된 배열에 대한 역참조 (3) glArrayElement(), glDrawElements(), glDrawRangeElements() 는 데이터 배 열의 원소를 임의로 접근. glDrawArrays()는 연속된 원소들에 대해 접근한다. void glDrawArrays(GLenum mode, GLint first, GLsizei count); 활성화된 배열의 first 번째 원소부터 first+count-1 번째 원소들을 사용하여 기하 프리미티브들을 구성 mode 인자: 구성할 프리미티브의 종류로 glBegin()의 인자로 허용된 값들로 GL_POLYGON, GL_LINE_LOOP, GL_LINES, GL_POINTS 등 이것은 다음과 동일한 효과를 가진다. int i; glBegin(mode); for(i = 0; I < count ; i++) glArrayElement(first + i); glEnd() 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

인터리브 배열 여러 개의 정점 배열을 한 큐에 지정 원하는 배열을 활성화/비활성화하는 기능도 포함 원하는 배열을 활성화/비활성화하는 기능도 포함 void glInterleavedArrays(GLenum format, GLsizei stride, void *pointer) 여섯 개의 배열을 초기화 format 으로 지정된 배열은 활성화하고 다 른 것은 비활성화한다. format 인자는 14가지 상수 중 하나(표2-5) stride 인자: 연속된 정점들 사이의 바이트 오프셋 pointer 인자: 배열의 첫 번째 정점에 대한 첫 번째 좌표의 메모리 주소 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

사용 예 static Glfloat intertwined[] = {1.0, 0.2, 1.0, 100.0, 100.0, 0.0 1.0, 0.2, 0.2, 0.0, 200.0, 0.0 1.0, 1.0, 0.2, 100.0, 300.0, 0.0 0.2, 1.0, 0.2, 200.0, 300.0, 0.0 0.2, 1.0, 1.0, 300.0, 200.0, 0.0 0.2, 0.2, 1.0, 200.0, 100.0, 0.0}; glInterleavedArrays(GL_C3F_V3F, 0, intertwined); GL_COLOR_ARRAY, GL_VERTEX_ARRAY 는 활성화되고 GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, GL_NORMAL_ARRAY, GL_EDGE_FLAG_ARRAY 는 비활성화된다. glColorPointer() 와 glVertexPointer() 로 여섯 개의 정점값을 각각의 배열에 지정한 것과 동일한 효과 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

속성 그룹 관련된 상태 변수들을 속성 그룹 (attribute group)으로 묶어서 관리 GL_LINE_BIT속성은 라인 폭, GL_LINE_STIPPLE 활성화 상태, 라인 스티 플 패턴, 라인 스티플 반복 카운터, GL_LINE_SMOOTH 활성화 상태 등과 같은 다섯 개의 상태 변수로 구성. glPushAttrib(), glPopAttrib() 커맨드를 사용 하여 속성그룹의 변수들을 한번에 저장하 거나 불러올 수 있다. OpenGL 1.1 부터 클라이언트 속성 스 택 추가 glPushClientAttrib(), glPopClientAttrib() 커 맨드 사용 20가지의 속성 그룹 제공하며 모두 glPushAttrib() 과 glPopAttrib()으로 저장 하거나 불러올 수 있다. void glPushAttrib(GLbitfield mask); void glPopAttrib(void); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

void glPushAttrib(GLbitfield mask); void glPopAttrib(void); glPushAttrib() 로 마지막에 저장된 상태 변 수들의 값을 불러온다. 표2-6 속성 그룹 void glPushClientAttrib(GLbitfield mask); mask로 지정된 모든 속성들을 해당 클라이 언트 속성 스택에 저장한다. void glPopAlientAttrib(void); glPushClientAttrib() 로 마지막에 저장한 상 태변수들의 값을 불러온다. 표2-7 클라이언트 속성 그룹 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

속성 그룹 마스크 비트 속성그룹 GL_ACCUM _BUFFER_BIT 누적버퍼(accum-buffer) GL_ALL_ATTRIB_BITS 모든 속성 그룹에 있는 상태변수들을 저장, 불러옴 GL_COLOR_BUFFER_BIT 컬러버퍼(color-buffer) GL_CURRENT_BIT 현재(current) GL_DEPTH_BUFFER_BIT 깊이버퍼(depth-buffer) GL_ENABLE_BIT 활성(enable) GL_EVAL_BIT 평가자(eval) GL_FOG_BIT 안개 효과(fog) GL_HINT_BIT 힌트(hint) GL_LIGHTING_BIT 라이팅(lighting) GL_LINE_BIT 선분(line) GL_LIST_BIT 리스트(list) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

속성 그룹 마스크 비트 속성그룹 GL_POINT_BIT 점 (point) GL_POLYGON_BIT 폴리곤 (polygon) GL_POLYGON_STIPPLE_BIT 폴리곤 스티플(polygon-stipple) GL_SCISSOR_BIT 편집(scissor) GL_STENCIL_BUFFER_BIT 스텐실 버퍼(stencil-buffer) GL_TEXTURE_BIT 텍스쳐(texture) GL_TRANSFORM_BIT 변환(transform) GL_VIEWPORT_BIT 뷰포트(viewport) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

glPushClientAttrib() mask로 지정한 모든 속성을 해당 클라이언 트 속성 스택에 저장 glPopClientAttrib() 마지막에 저장한 상태 변수들의 값을 불러 옴 void glPushClientAttrib(GLbitfield mask); void glPopClientAttrib(void); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

void glPushClientAttrib(GLbitfield mask); void glPopClientAttrib(void); 표2-7 클라이언트 속성그룹 마스크 비트 속성 그룹 GL_CLIENT_PIXEL_STORE_BIT 픽셀 저장(pixel-store) GL_CLIENT_VERTEX_ARRAY_BIT 정점 배열(vertex-array) GL_ALL_CLIENT_ATTRIB_BITS -- push 나 pop을 할 수 없다. 피드백(feedback) 선택(select) 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

곡면을 폴리곤 모델로 만들 때 유용한 테크닉 폴리곤의 방향(감기)을 일정하게 유지. 곡면을 구성하는 모든 폴리곤들이 같은 방향을 향하고 있어야 함. 모두 시계 방향이거나, 혹은 반시계 방향으로 감겨 있어야 함. 폴리곤 분할할 때 삼각형이 아닌 폴리곤이 있는 지를 살펴본다. 이미지의 품질과 디스플레이 속도는 항상 trade-off 관계. 매우 높은 품질의 이미지를 그릴 때는 곡면의 내부보다 실루엣 엣지 부분을 좀더 분할하는 것 이 좋다. 모델에서 T-교차점이 없도록 한다 닫힌 곡면(closed surface)를 만들 때는 닫힌 루프 의 시작 좌표와 끝 좌표의 값이 동일한지 반드 시 확인. B C 잘못된 모델 A OK 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

예제: 20면체 만들기 12개의 정점에 걸쳐 있는 이등변 삼각형 모 양의 면 20개로 구성된 솔리드 형태의 정20 면체 #define X .5257… #define Z .8506… static 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}, ……….}; int i; glBegin(GL_TRIANGLES); for (i = 0; i < 20; i++) { 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

} glEnd(); /* 이 부분에서 컬러 정보를 저장한다 */ glVertex3fv(&vdata[tindices[i][0]][0]); glVertex3fv(&vdata[tindices[i][1]][0]); glVertex3fv(&vdata[tindices[i][2]][0]); } glEnd(); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

곡면에 대한 법선 벡터 구하기 곡면의 법선 벡터는 정규화된 외적 (normalized cross product) 을 구하면 된 다. GLfloat d1[3], d2[3], norm[3]; for (j = 0; j < 3; j++) { d1[j] = vdata[tindices[i][0]][j] – vdata[tindices[i][1]][j]; d2[j] = vdata[tindices[i][I]][j] – vdata[tindices[i][2]][j]; } normcrossprod(d1, d2, norm); /* 두 벡터의 정규화된 외적을 구하는 함수 */ glNormal3fv(norm); 2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기

2012-2학기 Chapter 2 상태 관리 및 기하 오브젝트 그리기