Chapter 4 컬러( COLOR ) 2011-2학기 가상현실
이 장의 내용 컬러 인식 눈으로 컬러를 인지하는 과정 컴퓨터 컬러 픽셀과 컬러와의 관계 RGBA 모드와 컬러 인덱스 모드 각 모드들이 그래픽 하드웨어에서 작동하는 방법 사용할 모드를 결정하는 방법 컬러와 쉐이딩 모델 지정하기 컬러와 쉐이딩 모델을 지정하는 커맨드 2011-2학기 가상현실
컬러 인식 빛은 광자(photon)로 구성 광자: 일정한 경로를 따라 돌아다니거나 자체적인 주파수 혹은 파장이나 에너지에 따라 진동하는 빛을 구성하는 입자 우리 눈에 보이는 것들은 다양한 주파수를 가진 광자들이 혼합된 것 사람의 눈은 광자가 망막의 추상체라는 특정한 세포를 자극할 때 빛을 인식한다. 사람의 눈은 광자에 대한 추상체의 자극 정도를 기록하고 있기 때문에 가시광선 영역에 없는 빛도 인식할 수 있다. 예를 들어 빨강과 파랑으로부터 심홍색 인식. 컴퓨터 모니터는 빨간색(R), 초록색(G), 파란색(B)으로 구성된 픽셀에 빛을 밝힘으로써 가시광선을 표현 2011-2학기 가상현실
컴퓨터 컬러 컬러 스크린이 장착된 컴퓨터에서는 하드웨어로 빨간색, 초록색, 파란색 양을 조절, 스크린에 있는 픽셀을 비춤. 컬러 스크린이 장착된 컴퓨터에서는 하드웨어로 빨간색, 초록색, 파란색 양을 조절, 스크린에 있는 픽셀을 비춤. 빨간색(R), 초록색(G), 파란색(B), 알파값(A) 픽셀에 대한 컬러 정보 저장 방법 RGBA 모드: 각 픽셀에 대한 컬러 정보는 한 픽셀마다 R,G,B,A 값을 지정하는 모드로 저장 컬러 인덱스 모드: 픽셀에 해당하는 컬러의 인덱스를 가리키는 숫자만 저장. 컬러 인덱스는 R, G, B 로 표현된 색들이 정의된 테이블(컬러 맵)의 한 원소를 가리킴 컬러 인덱스 모드에서는 컬러 맵의 값을 변경할 수 있다. 픽셀 배열의 크기와 한 픽셀 당 출력 가능한 컬러의 개수는 그래픽스 하드웨어 플랫폼마다 다름 2011-2학기 가상현실
Green 컬러 큐브 Yellow Cyan White Black Red Magenta Blue 2011-2학기 가상현실
픽셀에 대한 컬러 연산 과정 프로그램의 앞 부분에서 컬러 디스플레이 모드로 RGBA인지 컬러 인덱스 모드인지를 설정 컬러 디스플레이 모드는 한번 초기화한 뒤에는 변경 불가능 프로그램이 실행되면 각각의 기하 프리미티브에 대해 정점 단위로 컬러가 결정됨 다음은, 라이팅, 쉐이딩, 래스터화 등의 작업이 차례로 이루어진다. 다음은, 텍스춰효과, 안개효과, 안티앨리어싱 등이 프레그먼트에 적용된다. 프레그먼트(fragment): 래스터화 작업에서 컬러나 z(깊이, depth), 텍스춰좌표 등이 지정된 좌표를 말한다. 픽셀은 프레임버퍼의 원소를 가리키며 프레그먼트는 프리미티브를 구성하는 한 점을 의미한다. 다음은, 알파 블렌딩, 디더링(dithering), 비트들간의 논리연산 등이 수행된다. 마지막으로, 프레그먼트에 대한 컬러값을 픽셀에 기록하고 윈도우에 지정된 컬러 디스플레이 모드에 따라 픽셀을 출력한다. 2011-2학기 가상현실
RGBA 모드와 컬러 인덱스 모드 한 픽셀마다 일정한 양의 컬러 데이터를 저장 이러한 데이터의 양은 프레임버퍼의 비트평면 수에 따라 결정 하나의 비트평면은 각 픽셀에 대해 1비트의 데이터 가짐 Ex) 컬러 비트평면이 8개인경우, 한 픽셀 당 8비트 할당 RGBA, 컬러 인덱스값에 대해 사용 가능한 비트평면 수 알아보려면 glGetIntegerv() 사용 GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS, GL_INDEX_BITS 인자 사용 2011-2학기 가상현실
RGBA 디스플레이 모드 RGBA 모드를 사용하는 하드웨어에서는 각각의 R, G, B, A 성분을 위해 일정한 수의 비트평면을 예약해둔다. RGBA는 부동 소수점 수가 아니라 정수형 값으로 저장 R성분에 대해 8비트 사용할 경우 0 ~ 255 사이의 정수로 할당 A 알파값은 스크린에 출력되는 컬러에 직접 영향을 미치지는 않으나 블렌딩이나 투명 효과에 사용된다. 2011-2학기 가상현실
디더링(dithering ) 일부 그래픽스 하드웨어에서는 표현 가능한 컬러의 수를 늘리기 위해 디더링을 사용 다른 컬러를 표현하기 위해 여러 개의 컬러를 혼합하는 기법 분홍색을 표현하는 경우 픽셀에 분홍색을 주는 것이 아니라 빨간색과 흰색을 번갈아 바둑판 모양으로 칠해서 결국 눈에 보이는 색은 두 색의 평균에 해당되는 분홍색이 보이도록 하는 것 여러 개의 픽셀로 구성된 영역이 분홍색을 띠게 되는 것 실제 픽셀 값은 빨간색과 흰색 뿐임 디더링은 glEnable(GL_DITHER)과 glDIsable(GL_DITHER)로 활성/ 비활성 시킬 수 있음. 디폴트로 디더링은 활성 상태이다. 2011-2학기 가상현실
컬러 인덱스 디스플레이 모드 컬러 인덱스 모드에서 OpenGL은 컬러 맵을 사용 컬러 맵(color map, 또는 lookup table) 그림을 그리는데 사용할 수 있는 R,G,B값들에 대한 인덱스 제공 원하는 컬러에 해당하는 숫자를 컬러 팔레트에서 선택하고 그 색으로 해당 영역을 칠한다. 컬러맵의 크기와 사용 가능한 비트평면의 수에 따라 표현할 수 있는 컬러의 개수가 제한된다. 2011-2학기 가상현실
RGBA와 컬러 인덱스 모드 중에서 선택하기 두 가지 모드 중에서 선택시 반드시 하드웨어와 응용 프로그램의 요구사항에 따라 결정 대부분의 시스템에서는 RGBA모드를 사용할 때 좀더 많은 컬러를 표현할 수 있도록 구성 쉐이딩이나 라이팅, 텍스처 매핑, 안개 효과 등과 같은 여러 가지 기능을 사용할 때는 컬러 인덱스 모드 보다는 RGBA를 사용하는 것이 좋음. 2011-2학기 가상현실
RGBA 모드와 컬러 인덱스 모드 컬러 인덱스 모드를 사용하는 것이 좋은 경우 사용할 수 있는 컬러가 제한되어 있는 경우 RGBA경우, 사용 가능한 비트평면의 수가 적은 경우에 전반적인 컬러가 제대로 나타나지 않음 컬러 맵 애니메이션 등과 같은 다양한 기법을 사용할 때 유용 일반적으로 RGBA 모드를 사용하는 것이 좋다. 텍스춰매핑, 라이팅, 쉐이딩, 안개효과, 안티앨리어싱, 블렌딩 등과 같은 기법은 RGBA 모드에서 제대로 작동함. 2011-2학기 가상현실
디스플레이 모드 변경하기 RGBA 모드나 컬러 인덱스 모드 중에 고정하고 싶지 않은 경우 발생 싱글 버퍼링과 더블 버퍼링을 서로 전환하고 싶은 경우 대다수의 시스템에서는 두 모드를 쉽게 전환할 수 없음. 여러 개의 윈도우를 서로 디스플레이 모드를 달리하여 생성해두면 이러한 문제를 어느 정도 해결 가능 2011-2학기 가상현실
컬러와 쉐이딩 모델 지정하기 OpenGL 에서는 현재 컬러(RGBA 경우)와 현재 컬러 인덱스(컬러 인덱스 모드의 경우)를 관리하고 있다. RGBA 모드에서 컬러 지정하기 void glColor3{b s I f d ub us ui}(TYPE r, TYPE g, TYPE b); void glColor4{b s I f d ub us ui}(TYPE r, TYPE g, TYPE b, TYPE a); /*알파값까지 지정 */ void glColor3{b s I f d ub us ui}v(const TYPE *v); void glColor4{b s I f d ub us ui}v(const TYPE *v); 첫번째 접미사: 3(R,G,B), 4(R,G,B,A) 두번째 접미사: byte, short, integer, float, double, unsigned byte, unsigned short, unsigned integer를 나타냄 세번째 접미사 v: 인자가 배열에 대한 포인터로 주어졌을 때 2011-2학기 가상현실
부동 소수점 타입의 인자를 받는 커맨드의 경우 주어진 값이 0.0 ~1.0 사이의 값에 있어야 한다. 2011-2학기 가상현실
컬러값을 부동 소수점 수로 변환하기 접미사 데이터 타입 최소값 최소값에 매핑될 수 최대값 최대값에 b 1바이트 정수형 -128 -1.0 127 1.0 s 2바이트 정수형 -32,768 32.767 I 4바이트 정수형 -2,147,483,648 0.0 2,147,483,647 ub 부호없는 255 us 65.535 ui 4,294,967,295 2011-2학기 가상현실
컬러 인덱스 모드에서 컬러 지정하기 void glIndex{sifd ub}(TYPE c); void glIndex{sifd ub}v(const TYPE *c); 현재 컬러 인덱스를 c로 설정 컬러 인덱스 모드에 대한 현재 클리어 컬러 설정 glClearIndex(GLfloat cindex); 컬러 인덱스 모드 윈도우에서 glClear(GL_COLOR_BUFFER_BIT)를 호출할때 주어진 cindex값으로 버퍼를 클리어 클리어 인덱스에 대한 클리어 값은 0.0 OpenGL 에서는 컬러 룩업 테이블값을 로드하는 루틴을 제공하지 않는다. 일반적으로 윈도우 시스템이 이 기능 제공. GLUT 에서는 윈도우 시스템 관련 커맨드를 호출하기 위한 glutSetColor() 루틴을 제공한다. 2011-2학기 가상현실
쉐이딩 모델 지정하기 선이나 채워진 폴리곤은 하나의 컬러로 그리거나(평면 쉐이딩, flat shading), 여러 가지 컬러로 그리기(부드러운 쉐이딩, smooth shading) 가능 void glShadeModel(GLenum mode); 쉐이딩 모델 설정 Mode 값으로 GL_SMOOTH 나 GL_FLAT을 사용 평면 쉐이딩을 사용하는 경우 프리미티브의 한 정점에서 사용한 색으로 전체 프리미티브를 그린다. 부드러운 쉐이딩을 사용하는 경우 각 정점에 대한 컬러를 별도로 지정할 수 있다. 선의 경우, 선분의 양 끝에 있는 정점에 지정된 두 컬러 사이를 보간하여 색칠한다. 폴리곤의 경우, 내부에 칠할 컬러들은 정점에 지정된 컬러 사이 값으로 보간된다. 2011-2학기 가상현실
부드러운 쉐이딩으로 삼각형 그리기: smooth.c #include <GL/glut.h> /*부드러운 쉐이딩으로 삼각형 그리기 */ #include <stdlib.h> void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); } void triangle(void){ glBegin (GL_TRIANGLES); glColor3f (1.0, 0.0, 0.0); glVertex2f (5.0, 5.0); glColor3f (0.0, 1.0, 0.0); glVertex2f (25.0, 5.0); glColor3f (0.0, 0.0, 1.0); glVertex2f (5.0, 25.0); glEnd(); } 2011-2학기 가상현실
glClear (GL_COLOR_BUFFER_BIT); triangle (); glFlush (); } void display(void){ glClear (GL_COLOR_BUFFER_BIT); triangle (); glFlush (); } void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (w <= h) gluOrtho2D (0.0, 30.0, 0.0, 30.0 * (GLfloat) h/(GLfloat) w); else gluOrtho2D (0.0, 30.0 * (GLfloat) w/(GLfloat) h, 0.0, 30.0); glMatrixMode(GL_MODELVIEW); 2011-2학기 가상현실
void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } 2011-2학기 가상현실
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; } 2011-2학기 가상현실
실행 결과 2011-2학기 가상현실