900 likes | 1.29k Views
픽셀 , 비트맵 , 폰트 , 이미지 그리기. 내용. 비트맵과 폰트 이미지 이미지 파이프라인 픽셀 사각형을 읽고 그리기 픽셀 그리기 비율을 개선하는 팁들 ( 비법 ) 이미지의 서브셋. 비트맵과 이미지. 둘 다 픽셀 사각형 배열 형식 비트맵 폰트에 있는 문자에 전형적으로 사용됨 각 픽셀에 대한 단일한 비트 정보로 구성 이미지 데이터 스캔되거나 계산될 수 있다 . 각 픽셀마다 여러 개의 데이터 조각 (R, G, B, A 포함 ). 비트맵과 폰트. 비트맵과 폰트
E N D
내용 비트맵과 폰트 이미지 이미지 파이프라인 픽셀 사각형을 읽고 그리기 픽셀 그리기 비율을 개선하는 팁들(비법) 이미지의 서브셋 가상현실
비트맵과 이미지 • 둘 다 픽셀 사각형 배열 형식 • 비트맵 • 폰트에 있는 문자에 전형적으로 사용됨 • 각 픽셀에 대한 단일한 비트 정보로 구성 • 이미지 데이터 • 스캔되거나 계산될 수 있다. • 각 픽셀마다 여러 개의 데이터 조각(R, G, B, A 포함) 가상현실
비트맵과 폰트 • 비트맵과 폰트 • 비트맵은 윈도우의 사각형 구역을 마스크 효과처럼 0과 1로 표시하여 구성한 사각형 배열 • 비트맵을 사용하는 일반적인 경우는 스크린에 문자들을 그리는 경우 • glRasterPos*()와 glBitmap() • 스크린상에 하나의 비트맵을 위치시키고, 그리는 명령 가상현실
그림8-1 비트맵으로 그린 F와 데이터 0xff, 0xc0 0xff, 0xc0 0xc0, 0x00 0xc0, 0x00 가상현실
w=10 h=12 (xbo, ybo) = (0, 0) (xbi, ybi) = (11, 0) 0, 0 11, 0 가상현실
예제 8-1 비트맵화된 문자 그리기: drawf.c #include <GL/glut.h> #include <stdlib.h> GLubyte rasters[24] = { 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xff, 0xc0, 0xff, 0xc0}; void init(void) { glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glClearColor (0.0, 0.0, 0.0, 0.0); } 가상현실
void display(void){ glClear(GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glRasterPos2i (20, 20); glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters); glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters); glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters); glFlush(); } void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho (0, w, 0, h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); } 가상현실
void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); } } 가상현실
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(100, 100); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutMainLoop(); return 0; } 가상현실
F 라는 문자가 최대 10만큼의 너비로 표현 • 비트맵 데이터는 항상 8비트의 배수형으로 저장된다. • 비트맵을 만드는 비트들은 왼쪽 아래부터 그려짐. 처음에 제일 아래 줄부터 그려짐 • 래스터 배열은 F의 아래 2줄을 표현하는 0xc0, 0x00, 0xc0, 0x00 으로 시작해서 맨 위의 두 줄인 0xff, 0xc0, 0xff, 0xc0까지 가상현실
현재 래스터 위치 • 현재의 래스터 위치는 다음 순서의 비트맵(또는 이미지)이 그려지는 스크린상의 위치 • 예제에서 F가 그려질 때glRasterPos*()호출,아래 왼쪽 부분에 해당하는(20, 20)좌표를 설정 • glRasterPos2i(20, 20); • void glRasterPos{234}{sidf}(TYPE x, TYPE y,TYPE z, TYPE w); • void glRasterPos{234}{sidf}v(TYPE *coords); • 현재의 래스터 위치를 설정, 변수는 래스터위치 좌표 설명 • 현재의 래스터 위치를 포함시키려면 • glGetFloatv() 커맨드 사용: 첫 번째 인수로 GL_CURRENT_RASTER_POSITION 사용 • 래스터 위치가 적합한지를 판별하기 위해서는 • glGetBooleanv() 호출: 첫 번째 인수로 GL_CURRENT_RASTER_POSITION_VALID 사용 가상현실
비트맵 그리기 • void glBitmap( GLsizei width, GLsizei height, GLfloat xbo, GLfloat ybo, GLfloat xbi, GLfloat ybi, const GLubyte *bitmap); • 비트맵 이미지의 포인터인 비트맵을 bitmap으로 표시하여 그림 • 비트맵의 원점을 현재의 래스터 위치로 교체 • width와 height은 비트맵의 픽셀 너비와 높이를 나타냄 • xbo 와 ybo는 비트맵의 원점을 정의 • xbi와 ybi 는 비트맵이 래스터화 한 후에 래스터 위치에 더해지는 요소인 x와 y를 지칭 가상현실
비트맵의 컬러 선택하기 • glColor*()와 glIndex*()에 GL_CURRENT_RASTER_COLOR와 GL_CURRENT_RASTER_INDEX라는 다른 상태값들로 설정, 비트맵을 표현 • 래스터 컬러 상태값은 glRasterPos*()가 호출될 때 설정 • glColor3f(1.0, 1.0, 1.0); /*흰색*/ • glRasterPos3fv(position); • glColor3f(1.0, 0.0, 0.0); /*빨간색*/ • glBitmap(…); /* Bitmap은 흰색으로 그려짐 */ • 현재의 래스터 컬러나 인덱스 포함은 • glGetFloatv() 나 glGenIntegerv() 커맨드의 첫번째 인수를 GL_CURRENT_RASTER_COLOR 나 GL_CURRENT_RASTER_INDEX 로 설정 가상현실
폰트와 디스플레이 목록 • 하나의 폰트는 일반적으로 각 문자가 식별 숫자(ASCII코드)와 폰트의 그려지는 방법을 포함한 일련의 문자들의 조합으로 구성 • glCallLists()를 다음과 같은 방법으로 사용 가능 • void glCallLists(GLsizei n, GLenum type, const GLvoid *list); • n 은 그려질 문자들의 개수, type는 보통 GL_BYTE, list는 문자 코드들의 배열이다. • 오프셋을 설정하기 위해서 glLIstBase()라는 커맨드 이용 • glGenLists(GLsizei range)로 유효한 인덱스 번호를 얻음 • 이 함수는 디스플레이 리스트 식별자인 range라는 범위에 해당되는 리스트를 반환 가상현실
예제8-2 완전한 폰트 그리기: font.c #include <GL/glut.h> #include <stdlib.h> #include <string.h> GLubyte space[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; GLubyte letters[][13] = { {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18}, {0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 가상현실
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e}, {0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, 가상현실
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3}, {0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e}, {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c}, 가상현실
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, 가상현실
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff} }; GLuint fontOffset; void makeRasterFont(void) { GLuint i, j; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); fontOffset = glGenLists (128); 가상현실
for (i = 0,j = 'A'; i < 26; i++,j++) { glNewList(fontOffset + j, GL_COMPILE); glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, letters[i]); glEndList(); } glNewList(fontOffset + ' ', GL_COMPILE); glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, space); glEndList(); } void init(void) { glShadeModel (GL_FLAT); makeRasterFont(); } 가상현실
void printString(char *s) { glPushAttrib (GL_LIST_BIT); glListBase(fontOffset); glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); } void display(void) { GLfloat white[3] = { 1.0, 1.0, 1.0 }; glClear(GL_COLOR_BUFFER_BIT); glColor3fv(white); 가상현실
glRasterPos2i(20, 60); printString("THE QUICK BROWN FOX JUMPS"); glRasterPos2i(20, 40); printString("OVER A LAZY DOG"); glFlush (); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho (0.0, w, 0.0, h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); } 가상현실
void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(300, 100); glutInitWindowPosition (100, 100); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutMainLoop(); return 0; } 가상현실
이미지 • 이미지는 비트맵과 유사하지만 사각형 영역에서 각 픽셀이 하나의 비트만을 포함하는 것이 아니라 보다 많은 정보 포함 • 예를 들어 이미지는 각 픽셀마다 완전한 RGBA 컬러를 저장 • 보통 그림으로 생각되는 이미지는 컬러버퍼에서 나옴 • 깊이 버퍼나 스텐실 버퍼로부터 픽셀 데이터의 사각형 영역을 읽거나 쓸 수 있다. • 스크린상에 표시되는 것 이외에도 텍스처매핑에도 사용될 수 있다. 가상현실
픽셀 데이터 읽기, 쓰기, 복사하기 • glReadPixels() • 프레임 버퍼로부터 픽셀들의 사각형 배열을 읽고, 메모리 안에 데이터 저장 • glDrawPixels() • 프로세서 메모리에 유지되고 있는 데이터로부터 glRasterPos*()에 의해서 표시되는 현재의 래스터 위치의 프레임버퍼 안에 픽셀들의 사각형 배열을 씀 • glCopyPIxels() • 프레임 버퍼의 한 부분에서 다른 부분으로 픽셀들의 사각형 배열을 복사 가상현실
프레임버퍼에서 프로세서 메모리로 픽셀 데이터 읽기 • void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); • 윈도우 좌표계의 x,y축 하단에 위치 • 차원은 width와 height인 프레임버퍼 사각형으로부터 픽셀 데이터를 읽고, pixel에 의해서 지정된 배열 안에 저장 • format은 읽혀지는 픽셀 데이터의 요소의 종류 • 표8-1 인덱스값이나 R, G, B, A 구성값 • type은 각 요소들의 데이터 종류 가상현실
표 8-2 glReadPixels(), glDrawPixels()의 데이터 형(type) 가상현실
묶여진 데이터 타입 • 각 픽셀들의 모든 컬러 구성 요소가 하나의 부호 없는 데이터 타입으로 압축 • 바이트 한 개, short 정수형, 또는 표준 정수 타입(GL_UNSIGNED_BYTE_*, GL_UNSIGNED_SHORT_*, GL_UNSIGNED_INT_*) 등으로 시작하는 상수들에 의해 표시 • 묶여진 픽셀 데이터의 비트 범위 위치에서의 컬러값들의 순서 • _REV 가 없는 경우 • 컬러 구성 요소들은 첫 번째 컬러 성분이 차지하고 있는 가장 중요한 장소에 할당 • _REV 가 있는 경우 • 첫 번째 컬러 성분이 least significant 위치에 시작되면서 성분의 패킹 순서가 반대로 됨 가상현실
묶여진 데이터 형의 적합한 픽셀 포맷 가상현실
묶여진 데이터 타입과 픽셀 포맷들에 대한 구성 요소의 순서 GL_UNSIGNED_BYTE_3_3_2 with GL_RGB Red Green Blue 7 6 5 4 3 2 1 0 GL_UNSIGNED_BYTE_2_3_3_REV with GL_RGB Blue Green Red 7 6 5 4 3 2 1 0 GL_UNSIGNED_SHORT_4_4_4_4 with GL_RGBA Red Green Blue Alpha 가상현실
GL_UNSIGNED_SHORT_4_4_4_4 with GL_BGRA Blue Green Red Alpha GL_UNSIGNED_SHORT_4_4_4_4_REV with GL_RGBA Alpha Blue Green Red GL_UNSIGNED_SHORT_4_4_4_4_REV with GL_BGRA Alpha Red Green Blue 가상현실
프로세서 메모리로부터 프레임 버퍼에 픽셀 데이터 쓰기 • void glDrawpixels(GLsizei width, Glsizei height, GLenum format, GLenum type, const GLvoid, *pixels); • 픽셀 데이터의 사각형을 width 와 height 크기로 그림 • 픽셀 사각형은 현재 래스터 위치를 왼쪽 아래 모서리 지점으로 지정하여 그린다. • format 과 type은 glReadRixels()와 같은 의미 가상현실
예제 8-3 glDrawPixels()의 사용: image.c #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> #define checkImageWidth 64 #define checkImageHeight 64 GLubyte checkImage[checkImageHeight][checkImageWidth][3]; static GLdouble zoomFactor = 1.0; static GLint height; 가상현실
void makeCheckImage(void) { int i, j, c; for (i = 0; i < checkImageHeight; i++) { for (j = 0; j < checkImageWidth; j++) { c = ((((i&0x8)==0)^((j&0x8))==0))*255; // ^ 비트XOR연산자 checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; } } } 가상현실
void init(void){ glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); makeCheckImage(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } void display(void){ glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0, 0); glDrawPixels(checkImageWidth, checkImageHeight, GL_RGB, GL_UNSIGNED_BYTE, checkImage); glFlush(); } 가상현실
void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); height = (GLint) h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } 가상현실
void motion(int x, int y) { static GLint screeny; screeny = height - (GLint) y; glRasterPos2i (x, screeny); glPixelZoom (zoomFactor, zoomFactor); glCopyPixels (0, 0, checkImageWidth, checkImageHeight, GL_COLOR); glPixelZoom (1.0, 1.0); glFlush (); } 가상현실
void keyboard(unsigned char key, int x, int y) { switch (key) { case 'r': case 'R': zoomFactor = 1.0; glutPostRedisplay(); printf ("zoomFactor reset to 1.0\n"); break; case 'z': zoomFactor += 0.5; if (zoomFactor >= 3.0) zoomFactor = 3.0; printf ("zoomFactor is now %4.1f\n", zoomFactor); break; 가상현실
case 'Z': zoomFactor -= 0.5; if (zoomFactor <= 0.5) zoomFactor = 0.5; printf ("zoomFactor is now %4.1f\n", zoomFactor); break; case 27: exit(0); break; default: break; } } 가상현실
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(250, 250); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMotionFunc(motion); glutMainLoop(); return 0; } 가상현실
프레임 버퍼 안에서 픽셀 데이터 복사 • void glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum buffer); • 아래 왼쪽 모서리가 x, y • width와 height 의 넓이를 가지는 프레임 버퍼 사각형으로 부터 데이터를 복사 • 데이터는 현재 래스터 위치에 의해서 주어지는 새로운 위치인 왼쪽 아래 위치로 복사된다. • buffer는 사용되고 있는 프레임 버퍼를 설명하는 GL_COLOR, GL_STENCIL, GL_DEPTH 가상현실
이미지 파이프라인 • 픽셀 이동 동작과 픽셀 저장 모드 설명 • glPixelZoom() 함수를 호출해서 픽셀 사각형이 그려지기 전에 확대하거나 축소할 수 있다. • glDrawPixels()가 호출될 때 데이터는 실제로 픽셀 저장 모드를 따라 메모리로부터 묶임이 풀려짐(unpack) • 픽셀 이동 연산들이 수행, 픽셀 결과값은 래스터화 됨 • 래스터화 되는 동안 픽셀 사각형은 현재의 상태에 따라서 확대, 축소 • 마지막으로 조각 연산이 제공, 픽셀들은 프레임 버퍼에 쓰여짐 • glReadPixels() • 데이터가 프레임버퍼로부터 읽혀지며 픽셀 이동 동작이 수행되고, • 데이터의 결과값은 프로세서 메모리 안으로 묶여짐(pack) 가상현실
glCopyPixels() • glReadPixels()이 어떤 연산을 하는 동안에 모든 픽셀 이동 동작을 사용한다. 가상현실
이미지 파이프라인 Processor Memory Texture memory unpack Pixel storage models pack Pixel-transfer Operations (and pixel map) Rasterization (including pixel zoom) Per-fragment operations Frame buffer 가상현실
픽셀 패킹과 언패킹 • 패킹(packing 묶기)과 언패킹(unpacking, 묶기 해제)은 픽셀 데이터가 프로세서 메모리로 쓰거나 프로세서 메모리에서 읽혀지는 방법과 관계 • 메모리에 저장되는 이미지는 elements 라고 불리는 1개에서 4개 사이의 데이터 덩어리를 가진다. • 픽셀 데이터나 포맷은 각 픽셀마다 저장하는 요소들의 숫자를 결정하거나 순서를 결정하여 정렬한다. • 구성요소는 8비트 바이트에서 32비트 정수까지, 또는 소수점 숫자 등 여러 가지의 데이터 타입으로 메모리에 저장될 수 있다. 가상현실
픽셀 저장 모드의 제어 • 이미지 데이터는 프로세서 메모리 안에 사각형 2,3차원 배열 안에 저장 • OpenGL에서 지원하는 모든 픽셀 저장 모드는 glPixelStore*() 커맨드로 제어 • void glPixelStore{if}(GLenum pname, TYPE param); • pname: 매개변수(표8-4) • GL_UNPACK_SWAP_BYTES, GL_PACK_SWAP_BYTES, • GL_UNPACK_LSB_FIRST, GL_PACK_LSB_FIRST • … • param: 타입 • GL_UNPACK* 매개변수 사용 • glDrawPixels(), glBitmap(), glPolygonStipple(), glTexImage1D(), glTexImage2D(), glTexImage3D(), … • GL_PACK* 매개변수 사용 • glReadPixels(), glGetTexImage(), glGetColorTable(),… 가상현실