제가 정리했던 파일도 올립니당ㅎㅎ
래스터 = 픽셀
변환 : 크기, 이동, 회전
크기 : 확대, 축소
이동: XYZ
구성
- 요구사항
- 분석
- 설계
- 구현
- 테스트
- 유지보수
그래픽 처리의 기본요소
- 점, 선, 다각형
- 모델링: 복잡한 물체를 설계하는
- 렌더링: 모델링된 물체를 화면에 그려내는 작업
1장 -2 그래픽 이론
1-2.1장 컴퓨터 그래픽스
- 캐드, 프레젠테이션 그래픽스, 가상현실,
- 미술: 무선 스타일러스 펜, 그래픽 소프트웨어
- 애니메이션, 게임
- 교육 및 훈련: CAI 학습 보조도구로서 컴퓨터 활용, 운전 시뮬레이션
- 과학 분야 가시화: SCI, VIS 대용량 정보분석
- 그래픽 사용자 인터페이스: GUI
1-2.2 컴퓨터 그래픽스 와 영상처리의 차이
- 컴퓨터 그래픽스
- 컴퓨터를 사용하여 그림을 생성하는 기술
- 영상처리
- 기존에 존재하는 그림을 개선하거나 인식하는 분야
1-2.3그래픽 이론 모델링과 렌더링
- 2가지 모델링(What to Draw), 렌더링(How to Draw)
- 모델링
- 무엇을 그릴지, 선분의 양 끝점 위치를 명시하는 작업
- 장면 내부의 물체를 정의하는 작업
- 렌더링
- 모델링에 의해 정의된 물체를 어떻게 그릴 것인지에 관련 된 것
- 화면에서 보는 모든 그림은 렌더링의 결과
- 모델링
1-3 pipeline 컴퓨터 그래픽스 제작단계
1-3.1 모델링
- 가상의 그래픽스 환경을 구성하는 각각의 물체를 컴퓨터가 처리할 수있는 방식으로 표현한 것을 모델(model) 이라고 한다
- 폴리곤(polygon mesh)들로 구성된다, 폴리곤으로 구성된 물체는 폴리곤 메시(polygon mesh)라고 불린다.
1-3.2 리깅(riging), 애니메이션(Animation)
- 애니메이션을 위해서 골격을 구성한 후, 각각의 뼈의 움직임이 야구선수의
- 폴리곤 메시에 어떻게 반영될 것인가를 정의
- 팔의 뼈가 움직일 때 그 주변의 폴리곤이 따라서 움직이도록 설정되어야 한다.
- 이런 과정을 리깅이라고 한다
- 폴리곤 메시가 어떻게 움직일지를 정의 하는것
1-3.3 애니메이터
- 캐릭터 골격을 움직여 캐릭터의 애니메이션을 정의 하면 런타임에 프레임 별로 재생
1-3.4 렌터딩(Rendering) = make
- 3차원 장면이 주어졌을때 이를 2차원 영상, 즉 프레임으로 만드는 작업을 렌더링이라 한다.
- 매우 복잡한 연산을 요구하는 단계
- 텍스처링(texturing): 텍스처를 물체 표면에 입힌다.
- 라이팅(lighting): 빛과 물체의 상호 작용을 처리한다.
1-3.5 후처리(post processing)
- 모션 블러(motion blur), 초점 심도(depth of field) 영역 바깥 부분을 흐릿하게 처리
1-4그래픽스 API
- 게임 엔진은 그래픽스 API를 기반으로 개발된다.
- 많이 쓰이는 2가지는 Direct3D와 OpenGL이다
- OpenGL ES: 모바일 기기를 위한 API이다. OpenGL 기능의 일부로 정의
- GPU 내에서 하드웨어로 구현되어 있다
- 그래픽스 API는 GPU에 대한 소프트 웨어 인터페이스라고 할 수 있다.
- 그래픽스 API는 그래픽스 응용 프로그램 혹은 게임 엔진에서 호출하는 함수를 GPU에서 실행 가능한 명령들로 바꿔주는 역할을 한다.
2장 그래픽 하드웨어
2장 -2 래스터 그래픽 장비
2-1 컬러 모니터
- 화소 = Picture Element = Pixel = Raster 픽셀
- 그림 기본 요소
- 인점
- RGB 색을 띤 점
- 한 화소의 색상으 세가지 인점의 밝기에 따라 결정
- 종횡비
- 화면의 세로 대 가로 길이 비율이다.
- 해상도
- 해상도란 이미지나 화면의 선명도를 결정하는 화소(Pixel)의 수를 의미합니다.
- 화소 수에 의해 결정된다.
- 도트 피치
- 동일 색상의 인점 사이의 거리
- 트라이어드 방식, 스트라이프 방식
- 트라이어드 방식
- 인점들이 서로 교대하면서 상하 좌우로 반복을 진행
- 스트라이프 방식
- 좌우로 나란한 3개의 인점이 모여서 한 화소를 구성
- 트라이어드 방식
2-1.1 화면 선명도-섀도우 마스크, 애퍼쳐 그릴
- 섀도우 마스크
- 화면의 선명도와 직결
- 트라이어드 방식일때 사용
- 애퍼쳐 그릴
- 스트라이프의 인점 방식일때
- 섀도우 마스크 VS 애퍼쳐 그릴
- 섀도 마스크은 마스크에서 많은 양의 빛을 차단하는 데 반해
- 애퍼쳐 그릴은 대량의 전자빔이 통과 할 수 있기 때문에 더욱 밝고 선명한 영상을 얻을수 있다.
4장 -1 그래픽스 표준
4-1.1 표준화
- 공유성과 재사용성을 높이기 위해 규정을 제정하는 것
4-1.1.1 그래픽스 표준 ISO/IEC JTC1/ SC24
- 하드웨어 구조
- 응용프로그램 인터페이스
- 메타파일 및 인터페이스
- 원본데이타
- data: 가공된 데이타
- 언어 수용
- 표준안의 타당성 검증 및 등록
4-1.1.2 그래픽 분야 표준의 목표
- 주 전산기 독립성
- 동일한 프로그램으로 다양한 모든 하드웨어에서 사용가능
- 장비 독립성
- 입출력 장비가 달라도 프로그램 명령은 동일해야한다
- 프로그램 언어 독립성
- 프로그램 작성에 어떠한 프로그램 언어를 사용해도 된다.
- 운영자 이식성
- 누구라도 쉽게 터득할 수 있어야한다.
4-1.2 그래픽 기본요소와 기본요소의 외양
4-1.2.1 기본요소 p110
- 점 (Point)
- 선 (Line)
- 면 (Fill Area)
- 꺽은선 (Poly Line)
- 표시 꺽은선 (Poly Marker)
- 문자 (Character)
4-1.2.1.2 기본요소 외양
패턴, 색상, 두께
- 실선 1번, 쇄선 2번, 점선 3번
- 프로그래머가 인덱스로 구분해야한다.
- 실선 ( ———, solid line) 1번
- 쇄선 ( — — —, Dashed line) 2번
- 점선 ( …….. , Dotted line) 3번
- 원형 캡(Round Cap), 버트 캡(Butt Cap), 확장 캡(Projection Cap)
- 원형 캡: 둥글게 처리
- 버트 캡: 선이 끝나는 지점에서 수직으로 잘라버리는 것
- 확장 캡: 선 두께의 반만큼 확장한 것
- 원형 연결(Round Join), 베벨 연결(Bevel Join), 마이터 연결(Miter Join)
- 원형 연결: 둥글게 처리
- 베벨 연결: 그림 2번
- 마이터 연결: 3번처럼 뾰족하게 처리한 것
- 채움 다각형(Filled Polygon), 점층적 변화(Gradation), 사선, 윤곽선 제거
- 채움 다각형: 다각형 내부를 어떤 색상으로 채워 넣는것
- 점층적 변화
- 사선 패턴
- 윤곽선 제거
4-1.3 GKS, PHIGS 표준 설명 ISO 그래픽 표준
4-1.3.1 그래픽스 표준은 4가지로 분류
- 응용프로그램 레벨 (Application Level)
- 응용 프로그램이 지켜야 할 표준을 추상적인 수준에서 서술
- 가상 레벨 (Virtual Level)
- 출력되어야 할 내용을 기본 요소를 사용하여 서술
- 논리적 레벨 (Logical Level)
- 장비에서 해당 기본 요소를 그리기 위해 필요한 과정을 서술
- 물리적 레벨 (Physical Level)
- 개별 입출력 장비에 관한 내용
4-1.3.2 GKS, PHIGS의 차이와 공통점
GKS (지케이에스)
- 유럽에 의해 주도
- 2차원 위주 이후 GKS-3D로 발전
- 파일 출력
- 가상 레벨 저장 (Virtual Level)
- 기본 요소의 위치, 속성, 가시성, 변환등의 정보까지 저장
- GKS메타 파일: 그림을 만들어 낼때 순차적인 명령어들을 저장
PHIGS (피그스)
- 미국에 의해 주도
- 3차원 모델링, 가시화, 시점 등에 표준화
- 상관관계를 포함한 물체의 집합 = 구조체(Structure)(물체의 집합을 다룸)
- 구조체 관통 (Traversal)에 의한 드로잉
- 로봇 팔을 예로 들면, 위쪽 팔이 움직일때 아래쪽 팔도 자동으로 따라서 움직여야한다.
- 계층 구조화된 구조체의 최상위 객체로부터 시작하여 계층구조의 위에서 아래로 관통하면서 해당 물체를 그린다.
- 현 변환 행렬 개념
- 구조체 관통 (Traversal)에 의한 드로잉
- 파일 출력
- 기본요소에 관한 정보 + 응용 프로그램 레벨에서 기본요소 사이의 관계
- CSG의 불리언 연산내용 저장 가능,
- 로봇팔의 계층구조 저장
4-1.4 언어 바인딩
- 언어가 지원하는 기능들을 모두 이용하여 코딩하면 되지만, 이 경우 표준화 측면에서 호환성과 이식성이 저해
- 그래픽 표준을 지켜라
- 그래픽 명령어 대한 표준정하고, 함수명과, 추상적인 수준에서 정의 한다.
- 심사표준: 심사에 의해 제정된 표준
- 사실표준: 표준이 아직 없지만 새로운 규칙들이 사실상 현재 표준처럼 인정
4장 -2 API
4-2.1 그래픽 API
- 응용프로그램 인터페이스
- 라이브러리 = API
- 응용 프로그램과 그래픽 하드웨어 사이에 존재한다.
- 그래픽 하드웨어란 그래픽 프로세서, 그래픽 메모리, 키보드 등 그래픽 처리에 관여하는 일체의 하드웨어
- 응용 프로그램과 그래픽 하드웨어 사이에 존재한다.
- PHIGS, GKS = 추상적 수준의 API
- API
- 라이브러리 = API
PDL
- 2차원 그래픽 API로
- 텍스트와 2차원 그래픽을 포함한 문서를 서술하는 함수
- 장점: 문서 이미지를 교환하는 대신 PDL 명령어만을 교환함으로써 문서의 송수신이 간편해진다.
X
- 윈도우에서 텍스트나 그래픽을 그리기 위한 함수
- 유닉스 워크스테이션의 2차원 그래픽 API
- 장점: 네트워크 활용
- 프로그램이 어떤 워크스테이션에서 돌아갈때
- 디스플에이는 다른 곳을 향하고
- 사용자 입력은 다른 워크스테이션에서 받아들이게 한다.
펙스
- 3차원 그래픽 API
- PHIGS에 ㄱ반을 두고 X를 확장
- X 윈도우에서만 돌아가기 때문에 범용성을 확보하기 어렵다
렌더맨 셰이딩 언어
- 장점: 다양한 물체의 모습을 정확하게 서술 가능
- 단점: 그래픽 보드의 가속 기능을 제대로 활용하기 어렵다
4-2.2 고수준 그래픽 API
- 고수준 API
- 물체를 정의하고 물체 사이의 관계를 묘사함으로 프로그램 작성
- 저수준 API
- 물체를 구성하는 기본 요소의 정의부터
- 실제 그림을 그리는 세부적인 과정에 이르기까지 일일이 명시
장면 그래프 -> 그룹 노드 -> 그룹 노드 -> 네스트 구조 가능
4-2.3 VRML
VRML의 장면 그래프는
- 셰이프 노드 : 물체를 정의한 노드
- 변환 노드 : 하위 노드에 가해질 변환을 정의
- 그룹 노드 : 셰이트 노드 또는 변환 노드를 한데 묶어 그룹 노드를 정의
4장 -3 OpneGL 개괄
4-3.1 API 레벨
CORE 기반으로 -> GKS 가 제정 -> PHIGS 가 제정
PHIGS는 계층구조에 의한 그룹화 개념 도입
GL -> OpenGL로 발전한다.
오픈 인벤터
- PHIGS와 오픈지엘을 기반으로
- 장면 그래프 개념
- 개체 지향 개념을 도입한 것이 오픈 인벤터이다.
4-3.1.1 오픈지엘 - 저수준 API 설명
- 장면을 묘사하는 것이 아니라 구체적 프러시져(함수)를 호출
- 고수준 API처럼 어떤 장면을 묘사하는 것이 아니라
- 묘사된 내용으로부터 그장면을 그려내기 위해 필요한 구체적인 프러시저(Procedure)에 해당한다.
- 하드웨어 성능을 최대한 발휘
- 지엘은 그래픽 메모리, 그래픽 가속 칩등 하드웨어와 매우 근접
- 직접 제어함으로써 하드웨어 성능을 최대한 발휘 가능
- Inventor, VRML, java3D 들 고수준 API의 기반
- 오픈지엘 인터페이스 함수를 내부적으로 호출하여 프로그램 실행
- 드라이버 스프트웨어에 비해서는 상대적으로 고수준 함수
- 오픈지엘 기본요소
- 점, 선, 다각형
- 복잡한 물체를 설계하는 모델링
- 모델링된 물체를 화면에 그려내는 렌더링 작업으로 나눌수 있다.
- 지엘은 렌더랑에 치중한다
- 점, 선, 다각형 수준의 기본 요소만을 이해한다.
- 물체를 설계하는 목적이 아닌 렌터딩(make)그리기 위해 만들어졌다.
- 구조 심사 위원회가 지엘 표준에 관한 내용 결정
4-3.2 오픈지엘 설계원리
- 범용성(Generality)
- 워크스테이션, 슈퍼컴퓨터나 개인용 컴퓨터 모두 실행 가능
- 소프트웨어 면에서 지엘은 운영체제와 무관하게 설계
- 효율성(Performance)
- 그래픽 하드웨어의 가속 기능을 최대한 발휘 하는것
- 호환성을 감안하여 공통적인 부분을 찾아 그성능을 극대화 하는 것이 중요
- 공통부분이 아닌것에 대해서는 활성화 또는 비활성화 할수 있도록 기능 모드를 제공
- 독립성(Orthogonality)
- 기능 간의 독립성이 최대한 보장되어야 한다.
- 기능끼리 서로 얽혀 발생하는 오류를 방지 하기 위함
- 완전성(Completeness)
- 공통된 기능이 아닌 특정 하드웨어 기능에 대해서는 ARB 확장 형태로 명령어를 제공
- 다수의 하드웨어가 확장 기능을 지원하면 표준기능으로 변경
- 하드웨어 적으로 해당 기능을 실행할 수 없다면 스프트웨어적으로라도 실행할 수 있도록 배려해야 한다.
- 상호 작업성(Interoperability)
- 그래픽 명령은 A 컴퓨터에서 실행은 B 컴퓨터에서
- 클라이언트 - 서버 모델 (Client-Server Model) 지원
- 지엘 프로그램이 클라이언트
- 그래픽 서버가 명령을 서비스한다
- 성능이 낮은 클라이언트 컴퓨터가 고성능 서버를 이용할 수 있다.
4-3.3 파이프라인과 상태 변수
4-3.3.1 파이프라인
GPU 설계원리
- CPU 파이프라인과 유사
- GPU읜 처리속도를 획기적으로 개선한 것이 파이프라인 구조
- 분업에 의한 동시 처리로 처리속도를 극대화
- 그래픽 처리 작업을 기능별로 세분하여 이를 순차적으로 배치
- 지엘의 입력은 기하 기본요소, 영상 기본요소로 구상
- 기하의 기본 요소: 점, 선, 다각형(면)
- 영상 기본 요소: 2차원, 비트맵, 영상
- 지엘의 출력
- 입력된 기하학적 기본요소로 구성된 물체를 렌더링한 모습
- 입력된 기본 요소가 렌더링에 반영된다.
4-3.3.2 상태변수 (GL의 역활)
지엘의 역활
- 서브 프로세서에 파라미터를 전달하는 일
- 거대한 상태 변수 기계
- 파이프 라인은 상태변수를 참조해서 자동으로 실행
상태 변수 (= 그래픽 콘테스트, 맥락, context)
- 물체가 어떻게 그려져야 할 것인지를 표현하는 변수
4-3.3.3 속성 할당 방법(파라미터 리스트, 시스템 테이블)
파라미터 리스트
- 해당 기본 요소가 지닌 모든 속성 값들을 반복해서 나열
- 하나만 변경을 해도 모든 속성 값또한 나열해야한다.
시스템 테이블
- 현제 지정된 모든 속성 값, 테이블 속성 값을 검색, 변경하는 함수 존제
- 모든 것들이 기본값 존제
4-3.3.4 상태 테이블
지엘의 상태 테이블은 ISO 표준의 시스템 테이블에 해당한다.
- 지엘 프로그램은 간접적으로 파이프라인에 작용한다.
- 지엘프로그램 상태 변수값 설정
- 테이블에 기록
- 개별 파이프라인 프로세서는 필요한 상태 변수 값을 테이블로 부터 읽어 프로세스를 실행
4장 -4 OpenGL 프그래밍
4-4.1 명령어
지엘의 특징
- 명령어 = 함수명
- 지엘은 비객체지향적
- 함수 오버로딩이 불가능
- 3차원 정점 glVertex3f(), 2차원 정점 glVertex2f() 이다.
- 처리속도를 향상시키기 위해
4-4.2 지엘 프로그램 구성 요소
- 지엘 라이브러리 (GL)
- 렌더링 기능을 제공 (make)
- 지엘 유틸리티 라이브러리 (GLU)
- 50여개의 함수, GL 라이브러리의 도우미
- 다각형 분할, 투상, 2차원 곡면, 너브스등 고급기능 ㅈ공
- GL 함수로 작성
- GLU는 GL의 일부
- glu는 gl에 포함되어있다.
- 지엘 유틸리티 툴 킷 (GLUT)
- 사용자 입력을 받아 들이거나
- 화면 윈도우를 제어하기 위한 함수
- 윈도우 운영체제 기능과의 인터페이스
4-4.2.1 GLUT 설명
- 입출력 관련된 명령 -> 입출력 컨트롤러 (I/O Controller)
- 렌더링 관련 명령 -> 그래픽 컨트롤러(CPU) 에 내리는 명령
- GLU 함수 호출은 GL함수 호출로 바뀐다
- GLUT 라이브러리는 입출력 및 윈도우를 제어하기 위해 운영체제를 호출
- GLUT함수의 일부는 GLU 또는 GL 함수를 호출한다.
- GLUT는 지엘GL과는 별도로 작성한 프리웨어
- GL과 같이 GLUT API도 자체 상태 변수, 상태변수 테이블을 사용한다
- 명령어에 의해 기본 상태 변수 변경 및 검색 가능
- 지엘 프로그램과 프로그램이 돌아가는 윈도우 운영체제 사이의 인터페이스 역활
- GLUT는 운영체제의 독립적인 프로그래밍 가능
- GLUT는 추상적 명령으로 구성되어 있기 때문에 프로그래밍이 쉽다.
- 매우 제한된 GUI 인터페이스만 가능
- 복잡한 이터페이스 기능이 필요한다면 윈도우 API을 사용하자.
- 윈도우 기능 : 프로그램의 실행에 필요한 창을 관리하는 기능
- 콜백 기능: 지엘 프로그램 실행 중에 발생하는 사용자 입력을 처리하는 기능
- p141
함수명 | 기능 설명 | |
---|---|---|
윈도우 초기화 | glutInit(int argcp, char*argv) | 윈도우 운영체제와 세션 연결 |
glutInitWindowPosition(int x, int y) | 윈도우 위치 설정 | |
glutInitWindowSize(int x, int y) | 윈도우 크기 설정 | |
glutInitDisplayMode(unsigned int mode) | 디스플레이 모드 설정 | |
윈도우 관리 | glutSetWindowTitle(String title) | 윈도우 타이틀 설정 |
glutCreateWindow("title") | 새로운 윈도우 생성 | |
glutReshapeWindow(int, x, int y) | 크기 변경에 따른 윈도우 조정 | |
glutPostRedisplay() | 현 윈도우가 재생되어야 함을 표시 | |
glutSwapBuffers() | 현 프레임 버퍼 변경 |
4장 연습문제
- 그래픽 분야의 ISO 표준 중 하나인 PHIGS에는 구조체 개념이 포함되어 있다. (True/False)
- API는 프로그램 언어다. (True/False)
- 고수준 API는 장면 묘사 위주로, 구체적 렌더링 방식이 포함되어 있지 않다. (True/False)
- 파라미터 리스트를 사용할 경우 시스템 테이블은 불필요하다. (True/False)
- 파이프라인 구조에서 서브 프로세서의 논리는 하드웨어적으로 고정되어 있다. (True/False)
- 지엘이 C 함수에 대한 호출이라면 GLU는 지엘에 대한 호출이다. (True/False)
- 점, 선, 삼각형 등 렌더링의 최소 단위를 그래픽 (기본요소)이라 한다.
- 심사 표준이 제정되지 않는 상태에서 현실 시장에서 통용되는 표준을 (사실표준)이라고한다
- ISO에서 시스템 테이블은 지엘의 (상태 변수 테이블)에 해당한다.
- GLUT는 지엘과 (윈도우) 운영체제 사이의 인터페이스다.
- 장면 묘사 API에서 (group) 노드는 2개 이상의 노드로 구성된다.
- 윈도우 좌상단을 화면 좌표 (30, 10)에 위치시키기 위한 GLUT 함수는 (glutInitwindowPosition(30, 10))
- C 언어의 부동 소수 타입인 float에 해당하는 지엘 타입은 (GLfloat)이다.
- 어떤 모드를 활성화하기 위한 지엘 함수는 (glEnabled() )
5장- 1 그래픽 입력장치
5-1.1 물리적 입력장치
마우스, 조이스틱, 트랙볼, 스페이스 볼
- 포인팅 장치: 입력 장치는 키보드와 달리 커서를 사용하여 화면의 일정 위치를 가리킨다는 의미
- 자유도: 커서 이동 방향의 가지 수
-
입력 장치 자유도 입력 장치 자유도 조이스틱, 트랙 볼 4 스페이스 볼 6 - 물리적 입력 장치
- 상대 입력
- 마우스, 조이스틱, 트랙볼
- 상대 입력 장치에서 입력 위치의 변화량이 입력된다.
- 절대 입력
- 태블릿
- 절대적인 입력 위치가 그대로 입력된다.
- 상대 입력
타블렛, 스타일러스 팬
- 디지타이징: 컴퓨터가 그림을 처리할 수 있도록 디지털 정보로 바꾼다는 의미
- 스라일러스: 그림가 같은 펜모양의 입력 장치
- 이 펜을 사용하여 쓰인 글씨나 그림은 컴퓨터에 그대로 입력된다.
터치 패널 또는 터치 스크린
- 광학 패널
- 누르지 않아도 된다
- 여러 열(Column)의 빛이 발사된다. 빛이 전달되지 않는 손가락 위치는 X 좌표
- 여러 행(Row)의 빛이 발사된다. 빛이 전달되지 않는 손가락 위치는 Y 좌표
- 전기 패널
- 외부 막을 누르면 누른 곳만 내피에 닿고 여기서 전류가 발생한다.
- 위치를 추적함으로써 눌러진 곳의 좌표가 입력된다.
- 손가락을 이용하기 때문에 정확한 위치 입력은 어렵다.
3D 스캐너
- 광원에서 나온 레이저 빔은 거울에 반사되어 물체 표면을 향한다.
- 표면에서 반사된 빔은 우측 거울에 반사 되어 CCD화면에 맺히게 된다.
버튼 박스
- 마우스나 키보드 움직임을 매크로 로 정의 하여 개별 키에 할당할 수 있다.
다이얼 박스
- 자유도가 8인 장치
- 8개의 다이얼로 별도의 기능을 수행할 수 있으므로
- 회전, 확대, 피닝, xyz축 방향별 이동 등을 위한 것이다.
- 일종의 아날로그 장치로, 매우 빠른 실시간대 디스플레이 기능을 갖추고 있다.
5-1.2 논리적 입력 장치
입력을 논리적 으로 취급
- 소스 코드 내에서 물리적 입력 장치의 종류를 구체적으로 지정하는 대신
- 입력 기능에 바탕을 둔 논리적 입력 장치를 지정하도록 하는 것이다.
- 좌표 입력기
- 절대 좌표, 상대 좌표를 입력하는 장치
- 물리적으로는 마우스, 키보드의 화살표, 트랙볼 들이 해당
- 연속 좌표 입력기
- 일련의 연속된 좌표를 입력하는 장치
- 좌표 입력기를 여러 번 호출하는 것과 동일한 기능을 가지고 있다.
- 물리적으로는 마우스나 테블릿 커서등이 해당한다.
- 문자열 입력기
- 문자열을 입력하는 장치
- 물리적으로는 키보드 문자판이 해당한다.
- 스칼라 입력기
- 회전각이나 크기조절 비율 등 스칼라 값을 입력하는 장치다.
- 물리적으로는 키보드로 값을 쳐 넣거나, 마우스로 슬라이드 바를 오르내리는 것에 해당
- 메뉴 선택 입력기
- 메뉴, 서브 메뉴, 메뉴 옵션 등을 선택
- 물리적으로는 마우스, 키보드 커서, 터치 패널, 음성이 있다.
- 물체 선택 입력기
- 화면 내부의 물체 또는 물체 일부를 선택하는 장치
- 물리적으로는 마우스나 터치 패널 장치등이 해당
5-1.3 물체 선택
- 물체를 선택하기 위한 논리적인 물체 선택 입력기는 고려가 필요하다.
- 여러 층으로 된 화면에서 두 물체가 중첩된 부분을 클릭하였을때
물체를 선택하는 방법
- 클릭한 곳에서 가장 가까운 물체를 선택
- 클릭 위치를 중심으로 픽 윈도우를 보여주는 것
- 커서 중심으로 정 사각형 윈도우를 보여주고
- 윈도우와 교차하는 변을 지닌 물체가 선택되도록 한다
- 클릭된 부분에 중첩된 모든 물체를 순차적으로 보여주면서 사용자 선택
- 그너나 너무 여러 물체가 중첩되어 있으면 이 방법은 선택에 걸리는 시간이 문제가 된다.
- 사용자가 선택할 물체명을 키보드로 입력 OR 미리 입력된 물체명 목록 중에 선택하는 것
- 사용자는 모델링시에 물체명을 입력하고
- 또 이를 기억하고 있어야 한다는 부담을 안게 된다.
5장- 2 입력 모드
메저와 트리거
- 메저
- 입력장치가 응용프로그램에 넘겨주는 값
- 트리거
- 전달하라는 신호
- DIR DIR는 메저, 는 트리거
메저 프로세스
- 운영체제 초기화시에 실행
- 항상 시스템 버퍼에 메저값이 저장 되어있음
- EX) 윈도우 시스템에서 처음 시스템을 켜서 마우스를 초기화한 이후에는 응용 프로그램이 그 값을 요구하든 말든 항상 현재의 마우스 위치 좌표가 추적되어 시스템 버퍼에 저장된다.
5-2.1 리퀘스트 모드
리퀘스트 모드
- 프로그램이 실행 중에 메저를 요구하는 방식
- 프로그램이 메저 프로세스에 값을 요구한다.
- 트러거가 일어날 때까지 대기상태
- EX
- 프로그램이 메저 프로세스에 값을 요구한다.
- 이 경우 메저 프로세스는 자신이 인식한 메저 값을 프로그램에 전달한다.
- 이러한 전달은 트리거 신호가 프로세서로부터 자신에게 들어오는 순간에 이루어진다.
Request_Locator (Device_ID, &Measure);
Device_ID: 물리적 장치
1번 마우스
2번 키보드
논리적 장치와 물리적 장치를 분리함으로써 주어진 논리적 입력 작업에
사용되는 물리적 장치를 쉽게 변경할 수 있다.
&Measure: 가져온 메저를 저장
5-2.2 샘플 모드 (= 직접 모드)
샘플모드 또는 직접모드
- 사용자 트리거가 불필요
- 프로그램이 메저를 요구하면 메저 프로세서는 무조건 현재의 메저를 제공한다.
- 사용자는 프로그램의 해당 함수가 실행되기 전에 이미 필요한 메저 데이터를 입력한 상태여야 한다.
- 이미 필요한 메저가 준비된 상태
리퀘스트 모드와 샘플모드의 차이
리퀘스트 | 샘플, 직접 |
---|---|
회전 메뉴를 선택 | 회전될 물체를 미리 마우스로 눌러 선택 |
어떤 물체를 회전하는지 선택 | 회전 메뉴를 선택하면 |
사용자가 원하는 물체 위로 마우스를 가져가면 메저 프로세스는 일단 해당 물체의 ID를 인식 | 프로그램이 자동으로 이미 들어와 있는 메저를 가져온다 |
마우스를 누르는 순간 (물체위로 마우스를 가져가) (트리거가 일어나는 순간) | |
메저가 프로그램에 전달 | |
둘다 Device_ID로 지정된 요구 장치에서만 입력을 받는다. |
5-2.3 이벤트 모드
이벤트 모드
- 사용자가 선택한 입력 장치가 우선권을 가진다.
- 사용자가 임의로 선택한 입력 장치를 사용하여 입력 데이터를 프로그램에 전달할 수 있다.
- 프로그램은 이러한 요구에 맞추어 해당 작업을 수행해야한다.
*이벤트 큐 *
- 입력 장치별로 여러 개의 이벤트가 발생
- 이벤트가 발생한 순서대로 순차적으로 처리하기 위해 이벤트 큐 사용
- 트라이버에게 이벤트 리쿠스트,
- 그라이버가 큐 프런트 레코드를 전달
- 큐가 비어있으면 응용 프로그램은 다른 일을 수행
이벤트 구동 시스템
- 이번트 모드를 사용하는 시스템
이벤트 레코드
- 이벤트 타입, 이벤트를 발생시킨 장치의 아이디, 메저 등으로 구성
마우스, 키보드, 트랙 볼에 각각 이벤트를 발생 |
---|
이벤트 레코드가 이벤트 큐에 삽입 |
응용 프로그램은 주기적으로 이벤트 큐를 검사한다. |
드라이버로서 큐가 비어 있지 않으면 XX | 드라이버로서 큐가 비어있으면 OO |
---|---|
큐 프론트 레코드를 응용프로그램에 전달 | 새로운 래코드가 들어올때 까지 기다린다. |
5-2.4 콜백 함수
콜백 함수 = 이벤트 처리기
- 응용 프로그램이 이벤트를 처리하는 방법을 말한다.
- 이벤트 타입별로 프로그램이 수행해야 할 내용을 함수로 나타낸것
- EX)
- ESC 키 이벤트 루프를 빠져나가라는 키라고 가정
- 이벤트 모드에서 입을 처리
MS 윈도우 운영체제
- 일종의 이벤트 구동 시스템
- 윈도우 프로그램의 시작점은 (Entry Point) 은 WinMain() 이라 불리는 함수로
- 새로운 윈도우를 만드시는 즉시, 이벤트를 처리하는 루프로 들어간다.
- 윈도우의 이벤트 레코드
- 이벤트 메시지 형식으로 처리
- 윈도우 핸들: 입력이 화면의 어느 윈도우를 향한 것인지 식별
- 메시지 타입: 어떤 종류의 입력 장치인지를 나타낸다
- 파라미터들의 메저 정보: 어느 버튼이 눌러진 상태인지, 마우스 위치를 나타내는 파라미터
- 윈도우의 이벤트 처리는 응용 프로그램에 의해 직접 실행가능
- 하지만 GLUT API를 이용하면 편리하다.
5장- 3 지엘 프로그램의 예
5-3.1 간단한 지엘 프로그램
지엘 프로그램은 3가지 요소로 구성
- 지엘 라이브러리 (GL : OpenGl Core Library)
- 지엘 유틸리티 라이브러리 (GLU : OpenGL Utility Library)
- 지엘 유틸리티 툴 킷 (GLUT : OpenGl Utility Toolkit)
- GLU 호출은 결국 GL 함수 호출로 바뀐다.
- GLUT 라이브러리는 입출력 및 윈도우를 제어하기 위한 것이므로 운영 체제를 호출
- GLUT 함수는 명령어의 번역이 운영체제 마다 달라서 프로그래머가 신경쓸 이유가 없고,
- 호환성 좋음
- GLUT의 기능 중 가장 중요한 것 중의 하나가 콜백 함수
- GLUT에는 프로그램 제어 상태 변수 와 시스템 고정 상태 변수
프로그램 제어 상태 변수
전역/ 메뉴/ 윈도우 변수
상태 변수명 | 타입 | 설정 함수 | 초기값 |
---|---|---|---|
GLUT_INT_WINDOW_X | integer | glutinitWindowPosition | -1 |
GLUT_INT_WINDOW_Y | integer | glutInitWindowSize | -1 |
GLUT_INT_WINDOW_WIDTH | integer | glutInitWindowSize | 300 |
GLUT_INT_WINDOW_HEIGHT | Integer | glutInitWindowSize | 300 |
GLUT_INT_DISPLAY_MODE | Bitmask | glutInitDisplayMode | GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH |
시스템 고정 상태 변수
그래픽 하드웨어에 따라 결정된다.
상태 변수명 | 타입 | 의미 |
---|---|---|
GLUT_SCREEN_WIDTH | integer | 모니터 화면 폭 |
GLUT_SCREEN_HEIGHT | integer | 모니터 화면 높이 |
GLUT_HAS_KEYBOARD | Boolean | 키보드 유무 |
GLUT_HAS_MOUSE | Boolean | 마우스 유무 |
GLUT_NUM_MOUSE_BUTTONS | Integer | 마우스 버튼 수 |
5-3.2 입력 콜백과 GLUT
콜백함수 실행 동작 순서 | |
---|---|
1. | 프로그래머가 콜백 함수를 등록 |
2. | 해당 콜백 함수에 원하는 내용을 채워 넣기만 하면 |
3. | 호출은 GLUT가 알아서 처리한다 |
4. | GLUT는 프로그래머가 등록한 함수를 콜백 테이블 형태로 저장 |
( 이 테이블은 이벤트 타입별로 불러야 할 콜백 함수명이 저장 ) | |
5. | GLUT는 드라이버에서 온 이벤트 레코드를 참고 |
6. | 이벤트 타입을 판단 |
7. | 그에 맞는 콜백 함수를 호출 |
( 이때 이벤트 레코드의 메저는 파라미터 형태로 콜백 함수에 전달 ) |
GLUT 콜백 처리
GLUT 콜백 처리 | |
---|---|
만약 큐에 이벤트가 있으면 | |
첫 번째 이벤트를 가져와서 해당 타입에 맞는 콜백 함수를 호출 | |
다시 루프로 들어가 다음 이벤트가 있는지를 검사한다. | |
큐에 이벤트 없을시 | |
운영체제는 현재 프로그램 외에 다른 일을 실행 | |
아이들 콜백 함수(Idle Callback Function)를 정의하면 아이들 콜백 함수가 자동 호출 |
*타입별 콜백 함수 *
이벤트 타입 | 콜백 함수명(예) |
---|---|
DISPLAY | MyDisplay() |
RESHAPE | MyReshape() |
KEYBOARD | MyKeyboard() |
MOUSE | MyMouse() |
IDLE | MyIdle() |
아이틀 콜백 함수(Idle Callback Function) 를 정의 하면 아이들 콜백 함수가 자동으로 호출 실행
아이들 콜백
- 다른 모든 이벤트가 없는 시간을 활용하여 필요한 계산을 한다.
- 정의 되어있지 않으면 운영체제는 다른 일을 수행
5-3.3 프로그램 기본 구조
int main() {
1. 윈도우 타입을 설정하고 초기화
GLUT의 윈도우 관련 상태 변수 값을 설정하는 작업을 하게 되는 곳
2. 배경화면의 색, 광원의 위치 등 지엘의 상태변수 중 전체 프로그램을 통해서 그 값이 변하지 않을 상태변수 값을 설정
3. 콜백 함수 등록
4. 이벤트 처리 루프로 들어간다.
}
5장- 4 윈도우와 뷰 포트
*GLUT, GL, 화면 좌표계 *
화면 좌표계 = 장치 좌표계 = 윈도우 좌표계
5-4.1 정규 좌표와 화면 좌표
- 지엘 프로그램이 실행되면서 입력 기본요소인 정점에 일련의 변환이 가해진다
- 이 변환을 대변하는 것이 좌표계이다.
- 파이프라인 변환 프로세스를 따라가면
- 기준 좌표계가 바뀌고
- 그때마다 새로운 좌표계를 기준으로 정점 좌표가 바뀐다.
3-> 2차원 좌표로 변환이 필요하다
- 이변환은 절단 좌표계에서 정규 좌표계로 넘어 오면서 이루어진다.
시험.
- 모델 좌표
- 물체 별로 모델링에 편하게 설정된 좌표계
- 전역 좌표
- 개별 물체를 모았을 때 한꺼번에 아우를 수 있는 좌표계
- 시점 좌표
- 물체를 바라보는 시점을 기준으로 표현
- 정규 좌표 & 화면 좌표
- 최종적으로 그림을 화면에 뿌리는 단계
- 모든 3차원 물체는 렌더링 결과 2차원 화면에 그려져야 한다.
- 3차원 좌표에서 2차원 변환이 필요하다.
- 먼저 정규 좌표로 변환을 한뒤, 화면 좌표로 변환된다.
- 정규 좌표는 1을 기준으로 하는 2차원 좌표이다.
5-4.1.1 정규 좌표
*정규좌표(NDC: Normalized Device Coordinate *
- 1을 기준으로 하는 2차원 좌표
- 어떤 값을 1을 기준으로 하여 상대적으로 표시하는 행위
- 정규화를 거치면서 모든 정점 좌표는 1보다 작은 값으로 바뀐다.
- 정규 좌표계의 원점은 화면의 정중앙에 위치
5-4.1.2 화면 좌표
화면 좌표 (SCS : Screen Coordinate System)
- = 장치 좌표 (DCS: Device Coordinate System), 윈도우 좌표(Window Coordinate System)
- 화소 단위로 좌표를 표시
- 1024 X 768 이면 x 좌표는 ( 0 ~ 1023 ), y 좌표는 ( 0 ~ 767 )
왜 절단 -> 정규 -> 화면 좌표 인가요?
- 정규좌표를 사용하면 해상도에 따른 화면 좌표 계산이 단순화 된다.
- EX
1,023 * ( (정규 좌표 ) + 1.0 ) * 0.5 ( (정규 좌표 ) + 1.0 ) * 0.5 가 먼저 계산되면, 이후 그려지는 화면의 해상도만 곱해지면 화면 좌표로 계산된다. -> 정규화로 정규좌표를 계산한뒤, 빠르게 출력장치의 화면 해상도에 적응하기 위함.
5-4.2 윈도우와 뷰포트, GLUT 모델링
윈도우를 분할
- 그리기가 뷰포트 내부로 제한됨
왜곡
- 뷰포트 미 설정시 윈도우 전체가 하나의 뷰 포트로 간주한다.
- 뷰포트 (윈도우 내부에 설정한 작은 창)
- 윈도우 크기 조절에 따라 뷰포트 내부 그림도 자동으로 크기조절
- 별도 뷰포트 설정에 의해 왜곡 방지
- 뷰포트의 종횡비가 안맞아서 꺠지는 현상
- 종횡비가 유지가 되지 않았기 때문
왜곡 해결법
- 사용자가 윈도우 크기를 조절하는 데 있어서
- 종횡비를 원래 장면의 종횡비와 반드시 일치
- 윈도우 내부에 별도의 뷰 포트를 열되
- 이 뷰 포트의 종횡비가 원래 장면의 종횡비와 일치되도록 프로그램을 작성
5-4.3 GLUT의 윈도우와 뷰 포트
P179 확인
정규 좌표 (NDC : Normalized Devie Coordinate)
- 각 좌표값의 최대값이 1이 되는 좌표임.
- 변환을 하는 목적은 새상도에 따른 계산을 단순화 시켜주기 위함
- 해상도 변화에 강해짐 (적응을 빠르기한다)
화면 좌표 (SCS : Screen coordinate System)
- 장치 좌표계, 윈도우 좌표계 이라고 하기도 하는데
- 화소 단위의 좌표이다
- 교차축(좌표가 0,0)인 지점은 좌상단에 위치함
뷰 포트 (Viewport)
- 윈도우 내부에 있는 작은 창
- 위 그림처럼 여러개의 뷰포트를 만드는 것도 가능
- 뷰 포트를 별도로 정의를 하지 않으면
- 현재 인도우 전체가 하나의 뷰 포트로 간주
- 윈도우 크기를 변형할 경우
- 왜곡이 일어난다
- 뷰 포트의 좌표는 좌하단이 원점(0,0)으로 정의 된다.
뷰포트(view port) 좌표계
GLUT의 윈도우
- Glut 에서는 윈도우 좌표와 동일한 좌표공간을 가지고 있음.
- Glut의 목적은 윈도우 에 관련된 것을 모아 놓은 것이다.
- 이로 인해 독립적으로 운영체제의 영향을 적게 받게됨
GLUT좌표계 (윈도우 좌표계)
화면 좌표계
- 특별히 ViewPort등 지정하지 않으면 중앙이 원점
- X 축의 범위는 -1 ~ 1까지
- y 축의 범위는 -1 ~ 1 까지
ViewPort 화면좌표계
5-4.4 GLUT 모델링
- 정육면체
void glutSolidCube(GLdouble size); void glutWireCube(GLdouble size);
- 원구
void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); slices : 경도(가로); stacks : 위도(세로);
- 원환체
void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); innerRadius : 안쪽 반지름; outRadius : 바깥쪽 반지름; nsides : 안쪽원 단면의 선 수; Rings : 튜브 윤곽 수 (안쪽 원의 개수);
- 원뿔
void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); base : 밑원의 반지름; slices : 밑원을 만드는 표면을 감싸는 선의 수; stacks : Z 축에 따라 올라 가는 선의 수
- 정4면체
void glutSolidCone (GLdouble base, Gldouble height, GLint slices, GLint stacks); void glutWireCone (GLdouble base, Gldouble height, GLint slices, GLint stacks);
- 정20면체
void glutSolidIcosahedron(void); void glutWireIcosahedron(void);
- 차 주전자
void glutSolidTeapot(GLdoouble size); void glutWireTeapot(GLdoouble size);
5장- 5 GLUT 콜백(Callback)
함수명 | 설명 |
---|---|
glutDisplayFunc() | 현재 윈도우에 Display 처리를 위한 콜백 설정 |
glutMouseFunc() | 현재 윈도우에 Mouse 클릭 처리를 위한 콜백 설정 |
glutMotionFunc() | 현재 윈도우에 Mouse 이동 처리를 위한 콜백 설정(마우스 이동시 발생) |
glutKeyboardFunc() | 현재 윈도우에 keyboard 입력 처리를 위한 콜백 설정 |
glutSpecialFunc() | 현재 윈도우에 특수 Keyboard 입력 처리를 위한 콜백 설정 |
glutReshapeFunc() | 현재 윈도우의 크기 변경에 대한 Reshape 콜백 설정 |
glutIdleFunc() | 현재 윈도우에Idle 상태 처리를 위한 콜백 설정 (Idle 상태 처리) |
glutIdleFunc() | 현재 윈도우에 Idle 상태 처리를 위한 콜백 설정 (Idle 상태 처리) |
glutEntryFuc() | 현재 윈도우에 Mouse Enter / Leave 처리를 위한 콜백 설정 |
glutTimerFunc() | 현재 윈도우에 타이머 처리를 위한 콜백 설정 |
5-5.1 리셰이프 콜백
GLUT 다음 세가지 경우 리셰이프 이벤트 발생
- 처음 위도우를 열때
- 윈도우 위치를 옮길 떄
- 위도우 크기를 조절할 때
void glutReshapeFunc(void(*func)(int width, int height));
윈도우의 width 와 height 가 파라미터를 통해 콜백 함수에 넘겨준다.
- 리셰이프 콜백 사용시 왜곡 방지
glMatrixMode(GL_PROJECTION); // 투상 행렬(GL_PROJECTION)을 변환 대상으로 설정하라는 명령 glLoadIdentity(); // 행렬에 항등 행렬을 실으라는 명령이다. glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); // 종단 횡비율을 조정하는 것이다.
- glOrtho()
- 평행 투상의 일종으로 , 육면체 형태의 가시 부피(View Volume)를 설정함으로써 정의 된다.
- 가시 부피 란 '화면에 보이고자 하는 물체의 범위'
- 전방 절단면: 투상면에 나란하면서 관찰자에 가까운 면
- 후방 절단면: 투상면에 나란하며서 관찰자에 먼 면
가시 부피의 설정 void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); parameter{left: 왼쪽 면의 x좌표, right: 오른쪽 면의 x좌표, bottom: 아랫면의 y좌표, top: 윗면의 y좌표, near: 전면(전방 절단면), far: 후면(후방 전단면)}
- 투상면의 종횡비와 뷰 포트의 종횡비는 직결되어 있다.
- 투상면에 맺힌 영상이 정규 좌표 -> 화면 좌표 통해 최종적으로 화면에 뿌려진다.
5장 미쳐 하지 못한 곳
러버밴딩 : 처음 마우스를 누를 곳을 사각형의 좌상단으로 하고, 마우스를 내리며 그리면 전에 있던 그림들의 배경을 지워야한다.
glClear(GL_COLOR_BUFFER_BIT);
러버 밴딩 (glClear) 적용을 하지 않고 이동을 하였을때
glClear(GL_COLOR_BUFFER_BIT)을 적용하였을떄
5장 과제
// 주전자모델_ex5_15_20161822_박승찬
// 이름: 박승찬
// 날짜: 4월 3일
// 제목: 주전자 모델링설정
// 소스 코드 순서 : 프로그램 실행 -> 마우스 쿨릭후 마우스 이동 -> 's', 'w' 토글모드 확인
// -> 키보드 왼쪽, 오른쪽키를 눌르기 -> 윈도우 화면 조정
// 소스 코드 순서 : 1 절차적으로 main 함수에서 프로그램 시작 및 기본 윈도우 와 GLUT 설정
// 소스 코드 순서 : 2 윈도우창 생성
// 소스 코드 순서 : 3 배경화면 초기화, 빛의 방향 관련 함수 호출
// 소스 코드 순서 : 4 디스프레이, 키보드, 마우스 모션, Reshape 이벤트 콜백 함수 등록
// 소스 코드 순서 : 5 이벤트 콜백함수 호출및 디스플레이 콜백함수 실행
// 소스 코드 순서 : 6 이벤트 루프에 의한 MyDisplay 화면 콜백함수 실행
// 소스 코드 순서 : 7 프레임 버퍼 초기화 및 깊이 버퍼에 대한 명확한 값 지정
// 소스 코드 순서 : 8 투상, 절단 좌표계 설정및, 단위 행렬 좌표 초기화 실행
// 소스 코드 순서 : 9 teapotSize의 사이즈값에 따른 주전자 모양 사상
// 소스 코드 순서 : 10 마우스 클릭수, 마우스 모션 이동
// 소스 코드 순서 : 11 마우스 모션 이동중 glutPostRedisplay함수에 의해 Display함수 호출
// 소스 코드 순서 : 12 마우스 모션의 glutPostRedisplay()함수에 의해 디스플레이 화면 호출
// 소스 코드 순서 : 13 's', 'w'키보드 입력시 토글모드 확인
// 소스 코드 순서 : 14 's', 'w'키보드 입력시 토글모드 상태변수 변경후 glutPostRedisplay()함수에 의해 display호출
// 소스 코드 순서 : 15 키보드 's', 'w'키보드 콜백함수의 glutPostRedisplay()함수에 의해 display호출 상태변경을 확인후 적용
// 소스 코드 순서 : 16 키보드 오른쪽, 왼쪽을 push한다.
// 소스 코드 순서 : 17 키보드 오른쪽, 왼쪽을 push한후 새로운 상태값 변수에 할당(적용)
// 소스 코드 순서 : 18 오른쪽, 왼쪽 키보드 입력후 시점에대한 상태값 변경이후 glutPostRedisplay() 함수 호출
// 소스 코드 순서 : 19 오른쪽, 왼쪽키보드를 누른후 상태값 적용한 Display를 호출하기 위해 MyDisplay()호출
// 소스 코드 순서 : 20 윈도우 Reshape()함수로 화면 크기의 상태값을 이용해 Display 화면을 재조정한다.
// 소스 코드 순서 : 21 윈도우 화면 크기재조정시 호출해는 Reshape 함수을 맞침과 동시에 Display함수를 호출한다.
// 소스 코드 순서 : 22 윈도우 Reshape()함수로 화면 크기의 상태값을 이용해 Display 화면을 재조정한다.
#include <glut.h>
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
// flatshading, wireframe을 토글링하기 위한 부울변수
int FlatShaded = 0;
int Wireframed = 0;
GLfloat teapotSize = 0.2; // 주전자 크기의 변수
// 마우스 움직임에 따라 시점을 바꾸기 위한 변수
int WIDTH, HIGHT = 400;
int ViewX = WIDTH / 2, ViewY = HIGHT / 2; // 마우스 모션 초기 좌표를 넓이의 /2 로 설정
GLfloat XKeyBordLeftRight; // 키보드 LEFT, RIGHT 입력시 반영 변수
void InitLight()
{
GLfloat mat_diffuse[] = {0.5, 0.4, 0.3, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat mat_ambient[] = {0.5, 0.4, 0.3, 1.0};
GLfloat mat_shininess[] = {15.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_diffuse[] = {0.8, 0.8, 0.8, 1.0};
GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0};
GLfloat light_position[] = {-3, 6, 3.0, 0.0};
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}
// 소스 코드 순서 : 10 마우스 클릭수, 마우스 모션 이동
// 마우스 모션 콜백 함수
// Parameter { X, Y : 마우스 움직임에따른 x, y 값 }
void MyMousMove(GLint X, GLint Y)
{
ViewX = X, ViewY = Y; // 마우스 움직임X, Y를 전역 변수인 ViewX, ViewY에 할당
// 소스 코드 순서 : 11 마우스 모션 이동중 glutPostRedisplay함수에 의해 Display함수 호출
glutPostRedisplay(); // 모션 움직임 이후 Display 함수 호출
}
// 소스 코드 순서 : 13 's', 'w'키보드 입력시 토글모드 확인
// 키보드에 이벤트 콜백 함수
void MyKeyboard(unsigned char KeyPressed, int X, int Y)
{
switch (KeyPressed)
{
case 'Q': // "Q"가 입력되면 시스템 종료
exit(0);
break;
case 'q': // "q"가 입력되면 시스템 종료
exit(0);
break;
case 's': // "s" 입력시 glShadeModel의 토글 모드
if (FlatShaded)
{
FlatShaded = 0;
glShadeModel(GL_SMOOTH);
}
else
{
FlatShaded = 1;
glShadeModel(GL_FLAT);
}
// 소스 코드 순서 : 14 's', 'w'키보드 입력시 토글모드 상태변수 변경후 glutPostRedisplay()함수에 의해 display호출
glutPostRedisplay(); // 's'입력 이벤트 종료휴 디스플레이 함수 호출
break;
case 'w': // "w" 입력시 glPolygonMode 폴리곤 모드 토글모드
if (Wireframed)
{
Wireframed = 0;
glPolygonMode(GL_FRONT, GL_FILL); // 폴리곤 모드로 전환 GL_FILL : 가득채우는 초기모습
glPolygonMode(GL_BACK, GL_FILL);
}
else
{
Wireframed = 1;
glPolygonMode(GL_FRONT, GL_LINE); // 폴리곤 모드로 전환 GL_LINE : 선의 모양의 폴리건 모드
glPolygonMode(GL_BACK, GL_LINE);
}
glutPostRedisplay(); // 'w'입력 이벤트 종료휴 디스플레이 함수 호출
break;
}
}
// 소스 코드 순서 : 16 키보드 오른쪽, 왼쪽을 push한다.
// 특수키입력 키보드에 이벤트 콜백 함수
// parameter { key: 특수키입력의 상수값, x,y : 키입력당시 마우스의 x, y 값 }
void MySpecialKeyboard(int key, int x, int y)
{
switch (key)
{
// 소스 코드 순서 : 17 키보드 오른쪽, 왼쪽을 push한후 새로운 상태값 변수에 할당(적용)
case GLUT_KEY_LEFT: // 왼쪽 방향키 누를시 주전자의 방향이 왼쪽으로 회전
XKeyBordLeftRight += 0.1;
// 소스 코드 순서 : 18 오른쪽, 왼쪽 키보드 입력후 시점에대한 상태값 변경이후 glutPostRedisplay() 함수 호출
glutPostRedisplay(); // 'GLUT_KEY_LEFT'입력 이벤트 종료후 디스플레이 함수 호출
break;
case GLUT_KEY_RIGHT: // 오른쪽 방향키 누를시 주전자의 방향이 오른쪽으로 회전
XKeyBordLeftRight -= 0.1;
glutPostRedisplay(); // 'GLUT_KEY_RIGHT'입력 이벤트 종료후 디스플레이 함수 호출
break;
}
}
// 소스 코드 순서 : 6 이벤트 루프에 의한 MyDisplay 화면 콜백함수 실행
// 소스 코드 순서 : 12 마우스 모션의 glutPostRedisplay()함수에 의해 디스플레이 화면 호출
// 소스 코드 순서 : 15 키보드 's', 'w'키보드 콜백함수의 glutPostRedisplay()함수에 의해 display호출 상태변경을 확인후 적용
// 소스 코드 순서 : 19 오른쪽, 왼쪽키보드를 누른후 상태값 적용한 Display를 호출하기 위해 MyDisplay()호출
// 소스 코드 순서 : 22 윈도우 Reshape()함수로 화면 크기의 상태값을 이용해 Display 화면을 재조정한다.
// 디스플레이 화면 이벤트 함수
void MyDisplay()
{
// 소스 코드 순서 : 7 프레임 버퍼 초기화 및 깊이 버퍼에 대한 명확한 값 지정
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 프레임 버퍼 초기화 및 깊이 버퍼에 대한 명확한 값지정
// 소스 코드 순서 : 8 투상, 절단 좌표계 설정및, 단위 행렬 좌표 초기화 실행
glMatrixMode(GL_MODELVIEW); // 투상, 절단 좌표계 설정
glLoadIdentity(); // 두번째 그림을 위한 단위 행렬 좌표 초기화
int x = (ViewX - (WIDTH / 2)); // 마우스 모션에 따른 X좌표의 재조정한 값
int y = -(ViewY - (HIGHT / 2)); // 마우스 모션에 따른 Y좌표의 재조정한 값
gluLookAt(0.0, 0.0, 0.0, x + XKeyBordLeftRight, y, -1.0, 0.0, 1.0, 0.0); // 주전자의 카메라 시점 변화
// 소스 코드 순서 : 9 teapotSize의 사이즈값에 따른 주전자 모양 사상
glutSolidTeapot(teapotSize); // teapotSize의 사이즈값에 따른 주전자 모양 사상
glFlush(); // 현재 명령어를 쌓지 말고 현재까지 쌓인 명령어 모두를 무조건 프로세서에 전달하도록 강제하는 명령어
}
// 소스 코드 순서 : 20 윈도우 화면 크기재조정시 호출해는 Reshape 함수을 맞침과 동시에 Display함수를 호출한다.
// 윈도우 화면 크기재조정시 호출해는 Reshape 함수
void MyReshape(int w, int h)
{
// 소스 코드 순서 : 21 윈도우창에 맞는 상태변수 수정한후 Reshape()함수 종료
glViewport(0, 0, (GLsizei)w, ((GLsizei)h)); // 윈도우 화면 조정시 주전자 width, hight의 크기 조정
glMatrixMode(GL_PROJECTION); // // 투상, 절단 좌표계 설정
glLoadIdentity(); // 두번째 그림을 위한 단위 행렬 좌표 초기화
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); // 정규좌표계 설정
}
int main(int argc, char *argv[])
{
// 소스 코드 순서 : 1 절차적으로 main 함수에서 프로그램 시작 및 기본 윈도우 와 GLUT 설정
glutInit(&argc, argv); // 윈도우 초기화
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); // 디스플레이 모드 SINGLE, RGB, 깊이 버퍼 설정
glutInitWindowSize(WIDTH, HIGHT); // 윈도우 화면 사이즈
glutInitWindowPosition(0, 0); // 윈도우 창의 위치
// 소스 코드 순서 : 2 윈도우창 생성
glutCreateWindow("OpenGl Drawing Example"); // 윈도우창 생성, TITLE BAR 설정
// 소스 코드 순서 : 3 배경화면 초기화, 빛의 방향 관련 함수 호출
glClearColor(0.4, 0.4, 0.4, 0.0); // 배경화면 초기화 색 설정
InitLight(); // 빛의 관련 함수 호출
// 소스 코드 순서 : 4 디스프레이, 키보드, 마우스 모션, Reshape 이벤트 콜백 함수 등록
glutDisplayFunc(MyDisplay); // 디스플레이 등록 콜백함수 등록
glutKeyboardFunc(MyKeyboard); // 키보드 입력 키보드 콜백함수 등록
glutSpecialFunc(MySpecialKeyboard); // 특수키 키보드 입력 키보드 콜백함수 등록
glutMotionFunc(MyMousMove); // 마우스 모션에 관한 콜백함수 등록
glutReshapeFunc(MyReshape); // 윈도우 크기 변경시 호출되는 Reshape 함수 등록
// 소스 코드 순서 : 5 이벤트 콜백함수 호출및 디스플레이 콜백함수 실행
glutMainLoop(); // 이벤트 콜백함수 호출 루프실행
return 0;
}
6장 모델 변환과 시점 변환
벡터의 내적
벡터의 외적
6.1 좌표계
6.1.1 3차원 물체의 표현
- 3차원 물체를 표현하는 방법은
- 물체 표면만 표현하는 방법
- 물체 내부까지 포함하여 표현
- 그래픽스에서는 물체 표면만 표현하는 방법
- 경계면 표현이라 하며
- 물체면을 평면 다각형의 집합으로 나타낸다
- 경계만의 표현의 기본틀은 다각형이다.
- 곡면을 표현하기 위해 필요한 다각형의 수는 곡면의 곡률에 정비례한다
- 곡면을 표현하는 방법
- 메시
- 표면메시
- 다각형 메시
- 표면 다각형
- 다각형
사각형 메시 | 평면 보장을 못한다. |
---|---|
삼각형 메시 | 평면보장. 2배의 드로잉 속도 (연산속도가 느리다) |
6.1.1.1 와이어 프레임과 솔리드 렌더링
와이어 프레임 렌더링 | 점, 선, 빠르다 |
---|---|
솔리드 렌더링 | 면, 느리다. |
- 다각형은 여러개의 정점(Vertex)으로 구성
- 모델링 작업은 정점의 위치를 정의하는 작업이다.
6.1.2 벡터공간
벡터 공간 : 주어진 벡터로부터 파생되는 모든 벡터의 집합
벡터 공간 | 주어진 벡터로부터 파생되는 모든 벡터의 집합 |
---|---|
처럼 주어진 벡터들에 스칼라를 곱하거나 벡터끼리의 합성에 의해 만들어지는 모든 벡터의 집합을 "벡터 공간"이라고 한다. | |
벡터의 위치와 무관하게 크기와 방향만 같으면 동일한 벡터로 처리 | |
위치를 중요하게 생각하는 기하학 표현이 어려움 |
- 스칼라와 벡터의 정의
스칼라 | 크기만 있고, 방향이 없다 | 실수는 스칼라다 |
---|---|---|
벡터 | 크기와 방향이 있다 | 시속 100km로 동쪽을 향한다. |
스칼라 법칙 | |
---|---|
교환법칙 | AB = BA |
결합법칙 | ABC = (AB)C = A(BC) |
역원 법칙 | AB = 1 이 되는 항등원이 존제한다. |
벡터 법칙 | |
---|---|
모든 벡터에는 역 벡터가 존재한다 | 모든 벡터에는 역벡터가 존제한다 |
스칼라를 벡터에 곱할 수 있다. | 벡터에 스칼라 2를 곱하면 2배가 되는 벡터가 생긴다. |
벡터의 합은 벡터이다 | V = A + B 이면 A로 갔다가 B로 가면 결국 V로 가는 것과 같다. |
6.1.3 어파인 공간 p240
- 어파인 공간
어파인 공간 | 점을 마치 벡터의 동족처럼 취급함으로써 벡터 공간을 확장한것 |
---|---|
점이라는 개념을 벡터공간에 추가하여, 방향과 위치도 표시할 수 있게 된다. | |
위치 표현을 위해 점(Point)를 추가 => 벡터의 크기, 방향, 위치 모두 고려 |
- 연산
종류 | 연산 | 결과 |
---|---|---|
벡터 + 점 | 덧셈, 뺄셈 | 점 |
벡터 + 벡터 | 덧셈, 뺄셈 | 벡터 |
스칼라 * 벡터 | 곱셈, 나눗셈 | 벡터 |
점 - 점 | 뺄셈 | 벡터 |
V = P + (1/2) (Q - P) |
---|
V = P + t (Q - P) = (1 - t) P + (t)Q |
어파인 합 : 점이 몇 개가 되든지 각 점 앞의 계수 합이 1이 되는 경우
6.1.4 좌표축과 좌표계
기반벡터 | 그들끼리 선형 독립이여야한다. |
---|---|
어떤 벡터가 다른 벡터의 선형 조합으로 표현 된다면 이는 선형 독립이 아니다 | |
V3 = 2V1 + 3V2 | V3는 선형 독립이 아니다. |
차원 | 점의 위치를 표현하기 위한 기반 벡터의 수 |
---|---|
좌표 | 각각의 기반 벡터에 곱해지는 계수 |
**추가 *: 좌표를 기반 벡터의 계수만으로 표현하는 데는 무리가 따른다
- 왜냐하면
- P와 P^ 는 크기와 방향이 같으면 동일한 벡터로 취급하기 때문에
- 벡터에 점을 추가한 것이 "어파인 공간"이다
- 임의의 점을 원점(Origin)으로 표시를 하여 한 점에 고정가능.
좌표를 기반 | v = 4V1 + 2V2 + V3 |
---|---|
어파인 공간 (위치, 크기, 방향) | P = r +4V1 + 2V2 + V3 |
6.1.5 동차 좌표
v = 4V1 + 2V2 V3 |
---|
P = r + 4V1 + 2V2 + V3 |
이 두개의 식은 r만 없애면 (4, 2, 1)로 같아 진다 => 동차 좌표를 적용한다
v = 4V1 + 2V2 V3 + 0*r |
---|
P = 4V1 + 2V2 + V3 + 1*r |
이런 식으로 정의를 하면 v (4, 2, 1, 0) 이고 p (4, 2, 1, 1)로 표현이 가능하다.
마지막 좌표가 0이면 벡터를 1이면 점을 의미한다.
동차 좌표 | 원점에서 출발하여 (1, 2, 1)을 통과하는 직선상에 놓은 모든 3차원 좌표가 동일한 2차원 점 (1, 2)를 의미한다 |
---|---|
(1, 2, 1) = (3, 6, 3) = (4, 8, 4)..... 이 된다 | |
(x, y, z, w) 좌표로 하면 (x/w, y/w, z/w) 가된다. |
6.2 기하 변환 P245 이동, 회전, 크기
6.2.0 모델 변환: 2차원
- 이동 변환 (Translation)
- 크기 변환 (Scaling)
- 회전 변환 (Rotation)
- 다양한 변환을 동시에 수행
- 각 변환마다 계산하는 방법이 다름
- 물체의 모든 점들에 대하여 필요한 계산 횟수가 많음
- 적용하는 변환의 수에 비례하여 계산 횟수가 증가함
- 이동 후 크기 변환 후 회전
기하 변환 | 물체의 이동, 회전, 크기 |
---|---|
t | 전치를 의미, 행과 열을 바꾸라는 것이다. |
6.2.1 이동 기하 변환 p246
- 물체 모습 및 시점에 대한 변환
- 물체를 투상하기 위한 변환
- 물체 표면에 입힐 텍스처 영상에 대한 변환,ㅏ
이동 변환 | 설될 회전, 크기, 조절 등의 모든 종류의 변환은 행렬의 곱셈으로 표시된다. |
---|
6.2.2 회전 변환
6.2.2.1 2차원 회전 변환
6.2.2.2 3차원 회전 변환
6.2.3 회전 변환 (Rotation) X, Y, Z 축회전
6.2.3 크기 조절 (균등 크기 조절 vs 차등 크기 조절)
균등 크기 조절 | 모든 배율이 같은 경우 |
---|---|
차등 크기 조절 | 모든 배율이 하나라도 다르면 |
6.2.4 전단
전단 | 물체를 한쪽 방향으로 밀어낸 모습 |
---|---|
디동이나 회전 등 강체의 변환과는 달리 물체 자체를 변형 시킨다 | |
Shx, Shy | x, y방향의 전단 인수를 말한다. |
---|
6.2.5 복합변환
참고: "복합 변환 행렬 C" 를 미리 계산하면 물체의 모든 점에대한 연산 횟수는 동일함.
*복합 행렬: 형렬 C(S2 * R1 * s1) 와 같이 연속된 변환 행렬을 모두 곱하여 하나의 행렬로 표시 한것 *
크기조절 (S1) 후 | 결과 물체를 회전 (R1) 한 후 | 다시 크기 조절(S2) |
---|---|---|
p | ( S2 * R1 * S1 ) * P | 역순으로 행렬이 곱해진다. |
중심점 기준 회전 : 원점 중심의 회전
중심점 기준 회전 : 피벗을 중심으로 회전
피벗 중심의 회전
a. 피벗이 좌표계 원점에 일치하도록 물체를 이동한다.
b. 물체를 원점 중심으로 기준 축 주위로 회전한다.
c 회전된 물체를 a. 번에서 이동한 반대 방향으로 이동한다.
복합 행렬에는 교환법칙적용 안된다.
인스턴스
라이브러리에서 가져온 하나하나를 인스턴스라 한다.
- 크기 조절, 회전
- 이동
6.2.6 반사
반사 변환 | 축을 기준으로 대칭 반사시키는 것 |
---|
x축 반사 : y * (-1)
y축 반사 : x * (-1)
원점 반사 : x * (-1) , y * (-1)
y = x 축 반사
45도 이동 -> y축 기준 반사 -> 45도 이동
6.2.7 구조 왜곡 변환
구조 왜곡 변환 | x, y, z 좌표에 상수 값의 크기 조절 인수를 곱하는 것이 보통이지만 이값에 다양한 함수를 할당함으로써 여러 가지 효과를 시도 |
---|
이름 | 그림 | 특징 |
---|---|---|
테이퍼링 | (b) | 원기둥에 따라서, z 좌표에 따라서 x, y 값의 크기 조절 비율을 달리한것, z가 커질수록 x, y값의 축소 비율이 커지기 때문에 위로 갈수록 점차 가늘게 된다. |
휨 (Bending) | (c) | 원기둥 높이 방향인 z축을 따라 휜다, 곡률 반지름 , 휨 중심, 휨 영역, 휨 각도등 여러가지 변수 값을 조절함으로써 다양한 모습을 얻을수 있다. |
비틀림 | (e) | z축을 기준으로 시계 방향의 회전각이 증가하게 한 것이다. z값에 따라 회전각을 차등화 한것 |
6.2.8 변환의 종류
강체 변환 | 이동 변환 + 회전 변환 | 물체 자체의 모습을 변형하는 것이 아니라, 변환 전후에 내부 정점 간의 거리가 그대로 유지된다는 특성 |
---|---|---|
유사 변환 | 조절 변환 + 반사 변환 | 변환 전후에 물체면 사이의 각이 유지되고, 물체 내부 정점간의 거리도 일정한 비율로 유지 |
어파인 변환 | 유사 변환 + 차등 크기 조절 변환 + 전단 변환 | 모든 변환이 어파인 변환, 유사 변환 보다 넓은 범주, 물체의 타입이 유지 된다는 특성, 행렬의 마지막 행이 항상 (0, 0, 0, 1) 이라는 점이다. |
원근 변환 | 직선이 직선으로 변환 | 변환 전에 평행했던 선분이 변환 결과 만나는 경우 , 직선이 직선으로 변환된다는 정도의 속성만 유지, 마지막행은 (0, 0, 0, 1)이 아니다. |
선형 변환 (선형 조합) | 어파인 변환 + 원근 변환 | 회전과 전단을 표시하는 다음 변환은 선형 변환 |
- 어파인 변환이나 원근 변환 등과 같은 선형 변환 에서 직선이 직선으로 유지되는 이유를 증명해보자.
V = P + tR ; P는 점, t는 스칼라, R은 벡터
T(V) = T(P+tR)
= T(P) + tT(R) ;
** T(P) = 점 P * T()변환은 => 점이다
tT(R) = t * R * T() => 스칼라 * 벡터 * 변환 은 벡터
6.2.8.1 강체 변환 (Rigid Body Transformation)
이동변환, 회전변환 |
---|
물체 자체의 모습은 불변 |
6.2.8.2 유사변환 (Similarity Transformation)
강체변환 + 균등 크기조절 변환, 반사 변환 |
---|
물체면 사이의 각이 유지됨 |
물체 내부 정점간의 거리가 일정한 비율로 유지됨 |
6.2.8.3 어파인변환 (Affine Transformation)
유사변환 + 차등 크기조절 변환, 전단변환 |
---|
물체의 타입이 유지 |
직선은 직선으로, 다각형은 다각형으로, 곡면은 곡면으로 |
평행선이 보존 |
변환 행렬의 마지막 행이 항상 (0, 0, 0, 1) |
6.2.8.4 원근변환 (Perspective Transformation)
평행선이 만남. |
---|
직선이 직선으로 유지 |
변환행렬의 마지막 행이 (0, 0, 0, 1) 아님 |
6.2.8.5 선형변환 (Linear Transformation)
어파인 변환 + 원근 변환 |
---|
선형 조합 으로 표시되는 변환 |
x = ax + by + cz 에서는 x, y, z 라는 변수를 각각 상수 배한것 |
6.3 지엘의 모델 변환 p261
6.3.1 모델 좌표계와 전역 좌표계
- 좌표계 변환
그래픽 파이프 라인에서 중요한 개념은 "좌표계 변환"이다. |
---|
- 물체 정점
물체 정점은 |
---|
물체 하나를 설계할 때의 좌표계 |
한 장면에 여러 물체를 모아놓았을 때의 좌표계 |
장면을 바라보는 시점에 따른 좌표계 |
수많은 좌표계를 거치면서 최종적으로 화면에 그려진다. |
- 그래픽에서의 모델링
그래픽에서의 모델링 | 물체 정점을 결정하는 작업을 말한다. |
---|---|
정점을 조합하여 | 다각형 메시를 만들고 |
다각형 메시를 조합하여 | 물체를 만들고 |
물체를 조합하여 | 장면을 구성할수있다. |
- 물체공간
물체공간 | 물체공간은 모델링될 물체를 표시하기 편리한 좌표 공간 |
---|---|
이 단계에서의 좌표는 일반적으로 부동 소수 정밀도를 지닌다. |
6.3.1.1 모델좌표계
모델 좌표계 OR 지역 좌표계 | 각 물체별로 설계상의 편의를 위주로 설정된 좌표계 |
---|
6.3.1.2 전역 좌표계 (WCS)
- 전역 좌표계
전역 좌표계는 장면 내 어느 곳에라도 설정할 수 있다. |
---|
표시된 물체 좌표가 전역 좌표계를 기준으로 바뀌어 물체 간의 상대적인 위치가 명확해짐 |
표시된 물체 좌표가 전역 좌표계를 기준으로 바뀌어 물체 간의 상대적인 위치가 명확해진다. |
임의 위치에 선정 |
일률적으로 어우를 수 있는 기준 좌표계 |
6.3.1.3 시점 좌표계
- 시점 좌표계
시점 좌표계 |
---|
보는 사람의 위치와 바라보는 방향에 따라서 물체 모습이 서로 다르다. |
전역 좌표계 기준의 물체 좌표는 다시 시점 좌표계를 기준으로 바뀐다. |
일련의 좌표계를 거치면서 변환 되어 최종적으로 화면에 뿌려진다. |
6.3.1.4 지엘에서 전역, 모델 좌표
지엘의 전역 좌표, 모델좌표 는 초기에는 일치가 되어있다. |
---|
- 전역 좌표계와 모델 좌표계의 분리
- 모델 좌표계를 기준으로 표시된 물체 정점의 좌표는 변하지 않는다.모델 좌표계 기준 : MCS(2, 2, 0)
- 전역 좌표계 기준: WCS (5, 4, 0)
변환은
- 물체에 가할수 있고
- 전역 좌표계를 모델 좌표계로 일치할수있다. P265 변환의 이유
x축 방향으로 3만큼, y축 방향으로 2만큼 이동 |
---|
변환이 지니는 가장 큰 의미는 전역좌표계와 모델 좌표계의 분리다 |
이동과 동시에 전역 좌표계와 모델 좌표계는 (C) 처럼 별개의 좌표계로 분리된다. |
이렇게 하면 모델 좌표계 기준으로 표시된 오른쪽 모서리 정점 좌표는 (2, 2, 0) 그대로 유지 |
모델 좌표계를 기준으로 표시된 물체 정점의 좌표는 변하지 않는다 |
변확이 가해진다고 해서 그즉시 정점 좌표가 전역 좌표계 기준으로 대체되지는 않는다 |
변환 행렬식을 동차 좌표로 표현한고 |
변환 행렬식 T는 물체 정점을 (3, 2, 0)만큼 이동하는 것을 의미한다. |
전역 좌표계를 (3, 2, 0)만큼 이동하면서 모텔 좌표계와 일치된다는 점에서 |
지엘은 "전역 좌표계를 모델 좌표계로 일치시키기 위한 것이 변환 행렬이다" 라는 식으로 생각 |
6.3.1.5 변환 행렬의 의미
회전 (a, b)
- 물처와 함께 MCS도 회전.
- MCS 기준의 물체 좌표는 불변
- 회전변환 행렬 T를 (a)의 WCS를 45(b)의 MCS로 일치시키는데 사용, 이후 이를 MCS 기준으로 물체를 렌더링
크기조절 : X축으로 2배
- MCS x축 눈금의 절대 길이가 바뀜
- MCS 기준의 물체 좌표는 불변 (EX, (2, 2, 0))
6.3.2 지엘 파이프 라인
- 기하의 변환은 여러 목적으로 사용된다
- 물체 모습 및 시점에 대한 변환
- 물체를 투상하기 위한 변환
- 물체 표면에 입힐 텍스처 영상에 대한 변환
- 저장된 값에 따라 최종적인 기하 변환을 가하는 것은 지엘 파이프라인 프로세서의 몫이다.
6.3.2.1 모델 변환
물체에 대해 이동, 회전, 크기 조절 등의 기하 변환 |
---|
모델 행렬로 대변됨 |
모델 좌표에서 모델 행렬을 곱하면 전역 좌표 |
6.3.2.2 시점변환 또는 뷰변환
변화된 물체를 관찰하기 위해 카메라를 이동하고 회전함으로써 카메라 위치와 방향을 설정하는 작업 |
---|
시점변환을 뷰변환이라고함 |
뷰 행렬을 전역 좌표에 곱하면 시점 좌표가 된다. |
6.3.2.3 투상변환
카메라의 렌즐르 선택하고 촬영하여 물체의 2차원 영상을 필름에 맺히게 하는 작업 |
---|
6.3.2.4 뷰 포트 변환
찍은 사진의 크기를 줄이거나 늘리는 작업 |
---|
6.3.2.5 모델 뷰 변환
지엘에서 모델 변환과 뷰 변환을 합쳐서 |
---|
카메라을 뒤로 빼는 대신 물체를 앞으로 밀어도물체의 모습은 완전히 같기 때문 |
모델 뷰 행렬 |
- 모델 좌표 * 모델 행렬을 = 전역 좌표
- 뷰 행렬 * 전역 좌표에 = 시점 좌표
- (모델 좌표로 표시된) 물체 좌표 * 모델 뷰 행렬 = 시점 기준의 좌표
6.3.3 지엘 모델 변환 p267
6.3.3.1 행렬 모드 설정
변환의 종류를 명시를 하자 | ||
---|---|---|
모델 뷰 행렬 - GL_MODELVIEW | 투상 행렬 - GL_PROJECTION | 텍스처 행렬 - GL_TEXTURE |
행렬 모드를 성절하는 것은 일종의 스위치 행위.
만약 모델 뷰 행렬에 붙으면 이후 나오는 모든 변환 명령은
모델 뷰행렬에 가해진다.
glMatrixMode 행렬 모드 설정
void glMatrixMode(GLenum mode);
mode 에는
모델 뷰 행렬 - GL_MODELVIEW
투상 행렬 - GL_PROJECTION
텍스처 행렬 - GL_TEXTURE
6.3.3.2 현 변환 행렬 (CTM)
스택의 맨위에 있는 현 변환 행렬로 |
---|
바로 이 행렬 값이 물체 정점에 곱해 진다. |
CTM: Current Transformation Matrix |
6.3.3.2.1 glLoadIdentity 현 변환 행렬을 I(항등 행렬)로 초기화
void glLoadIdentity(); // 현 변환 행렬을 항등 행렬도 (CTM을 I로 초기화)
- CTM 현 변환행렬을 항등 행렬로 초기화
- 초기화 결과
- 모델 좌표계 = 전역 좌표계 = 시점 좌표계
6.3.3.2.2 초기화 를 하였을 때 왜 모델 좌표계 = 전역 = 시점 인가
P^ = CTM * P = I * P = P
- CTM이 모델 뷰 행렬의 현 변환 행렬이면
- 모델 뷰 행렬 * (모델 좌표로 표시된) 물체 좌표 = 시점 좌표
- 그러니 모델 = 전역 = 시점 좌표이다.
6.3.3.2.3 기하 변환을 명시해주는 함수
- 후위 곱셈, 연산이다.
void glTranslatef(GLfloat dx, GLfloat dy, GLfloat dz);
x, y, z축 방향으로 dx, dy, dz 만큼 이동
void glScalef(GLfloat sx, GLfloat sy, GLfloat sz);
모델 좌표계 x, y, z축의 눈금이 전역 좌표계 눈금의 sx, sy, sz배가 되도록
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
모델 좌표계를 전역 좌표계로 부터 변수 angle에 제시된 각도만큼 반시계 방향으로 회전시킨다.
angle: 각도 변환
(1, 0, 0)이면 x축으로 회전
6.3.4 복합 변환에 의한 모델링 - p270
변환 행렬은 지엘의 상태 변수 이므로 선언된 이후의 작업에만 영향을 끼친다.
glMatrixMode(GL_MODEVIEW); // 모델 뷰 모데 설정
glLoadIdentity(); CTM (현 변환 행렬)을 항등행렬로 만듬
glScalef(sx, sy, sz); // 전역 좌표계 눈금의 sx, sy, sz배가 되도록
glRotatef(theta, vx, vy, vz); // theta만큼 회전
glBegin(GL_POINTS);
glVertex3f(px, py, pz);
glEnd();
함수 종류 | 지엘 함수 | 행렬 연산 |
---|---|---|
행렬 초기화 | glLoadIdentity(); | CTM = I |
크기 조절 | glScalef(); | CTM = CTM * S = (I )* S |
회전 | glRotatef(); | CTM = CTM * R = (I * S) * R |
정점 선언 | glVertex3f(); | P^ = CTM * P = (I * S * R) * P |
6.3.4.1 전연좌표 기준으로 물체 변환
6.3.4.2 전연좌표 기준으로 모델 좌표계 이동 변환
6.3.5 행렬 스택 활용
모델의 좌표계의 변화 과정을 역추적하는 것을 가능하도록 하는 것이 행렬 스택이다. |
---|
지금 상태의 현 변환 행렬을 저장하고 싶다면 푸쉬 |
이전에 저장된 변환 행렬을 복원하고 싶다면 팝을 사용 |
호출 함수 | 현 변환 행렬 | 작업 |
---|---|---|
glMatrixMode(GL_MODELVIEW) | CTM <= ModelView CTM | 모델 뷰 행렬 선택 |
glLoadIdentity() | CTM = I | 초기화 |
Draw_Orange() | P^ = CTM * P | (a)의 오렌지 그리기 |
glTranslatef(4, 4, 0) | CTM = CTM * T1 | 좌표계 이동 |
Draw_Orange() | P^ = CTM * P | (b)의 오렌지 그리기 |
glTranslate ( 6, -2, 0) | CTM = CTM * T2 | 좌표계 이동 |
glRotatef(45, 0, 1) | CTM = CTM * R | 좌표계ghlwjs |
glScalef(2, 2, 2) | CTM = CTM * S | 좌표계 눈금 크기 조절 |
Draw_Orange() | P^ = CTM * P | (c)의 오렌지 그리기 |
6.3.5.1 glPushMatrix || glPopMatrix
void glPushMatrix();
void glPopMatrix();
6.3.5.2 행렬 스택
... // 1
glPushMatrix(); // 2
glTranslatef();
glRotatef();
glScalef();
glPopMatrix(); // 3
... // 4