노력과 삽질 퇴적물
OpenGL ES: 기초 및 입문 (2) 본문
*OpenGL ES를 하기전 OpenGL 이론부터 다루고 있습니다.
본격적인 ES는 다음편부터 입니다.
OpenGL ES: 기초 및 입문 (4)
OpenGL ES: 기초 및 입문 (5)
1. 기본 이론, OpenGL
1) 기초
① 특성
> OpenGL 자체는 C 언어로 제작되었지만 함수 수준의 라이브러리이므로 특정 언어에 종속되지는 않는다
> gl 라이브러리의 함수는 gl 접두어로 시작하고 glu의 라이브러리는 glu로 시작한다. 마찬가지로 glut 소속의 함수는 glut 접두가 붙는다. 접두만으로도 OpenGL 함수임을 쉽게 알 수 있다.
② 좌표
[#출처]
> openGL은 오른손 좌표계 사용.
> 이 경우
X축: 엄지 / Y축: 검지 / Z축: 중지(손가락끝이 화면에서 사람눈쪽, 손가락 방향으로 Z+)
혹은
X축: 검지 / Y축: 중지 / Z축: 엄지(손가락끝이 화면에서 사람눈쪽, 손가락 방향으로 Z+)
> 사족으로 X축=끄덕축, Y축=도리축, Z축은 갸웃축으로도 불린다.
2) 주요 용어
정점, Vertex | 삼각폴리곤의 꼭지점들에 해당하는 부분. 오직 위치값만 가지고 있어서 3D에서 원자같은 요소이다. (색상이나 크기에 대한 정보X) |
상태 머신 | 그리기 함수 이전에 필요한 정보값들이 저장됨. > 좌표/색상/굵기/모양/조명 등등. |
안티 얼라이싱, Anti Aliasing | 서로 다른 색상으로 채워진 픽셀들의 경계를 중간색을 넣는 방식이 가장 일반적. 혹은 계단현상등이 발생하는 이미지를 좀더 자연스러 보이게 사용하기도. |
에지 플래그 | OpenGL 규칙상 다각형에 오목한게 있으면 안 된다고 한다. |
3) 기본 흐름
1 2 3 4 5 6 7 | glClearColor(R, G, B, Alpha);//각 함수인자들은 0~1.0f. 단 배경은 새로 지정하지 않는 이상 유지 glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); ... ... ...//그려넣을 내용물. 단, ES에서는 그리기 함수 호출불가&정점 배열만 사용가능 glEnd(); glFlush(); | cs |
4) 미분류
> OpenGL은 이미지 파일을 읽는 기능을 제공하지 않아서 운영체제별로 이미지 읽기 함수등을 별도로 만들어야 한다.
> glFuncName[2,3,4][s,i,f,d]인 경우,
2~4가 처리할 함수인자 갯수, 함수명 맨끝의 알파벳 표기는 처리할 타입(short, int, float, double)
2. 파이프라인
1) 절차
[#출처, OpenGL Rendering Pipeline]
① 지오메트리 패스(Geometry Path)
Vertex Operations | 정점 (Verteces)를 직선 및 다각형으로 변환(Primitives) |
Primitive Assembly | 안 보이는 부분을 잘라내는 작업을 처리(클리핑) 여기서 나오는 결과물에 색상/깊이/텍스쳐좌표등이 존재. (일종의 상태머신?) |
② 이미지 패스(Image Path)
Pixel Transfer Operation | 메모리에 있는 픽셀 데이터를 Unpacking |
③ 나머지
Display List | 랜더링 성능향상과 관련있음. > #[OpenGL Tutorial] Display List |
Texture Memory (Texture Assembly) | '텍스쳐 바르기'로도 불리는 과정 |
Rasterization | 앞서 처리한것들을 프레그멘트로 넣는다. (프레그멘트에 인쇄하는 과정이라는 설명도 있다.) |
Fragment Operation | 프레임 버퍼(Frame Bufer)에 저장하기전 여러 테스트과정이 있다. |
Frame Bufer | glGenFramebuffers > #Framebuffers - Learn OpenGL 랜더링을 위한 버퍼 모음집이다. openGL에는 2가지 프레임 버퍼가 존재하는데, Default Framebuffer와 Framebuffer Objects(FBOs, user-created framebuffers)이다. |
2) 버퍼
① 주요버퍼
> glClear함수 인자를 지정해서 사용.
> Fragment Operation에서 테스트전 연관된 버퍼가 할당되어야 한다.
또한 대부분의 버퍼는 각자 연관된 마스크가 있다. #opengl.org/wiki, Write Mask
> #OpenGL - Depth and stencils
Color Buffer | 알파 테스트와 연관된 버퍼. 프론트&백 버퍼를 이용한 더블버퍼 방식 |
Stencil Buffer | 스텐실 테스트와 연관된 버퍼. 원하는 부분만 그리고 싶을때 사용 |
Depth Buffer | 깊이 테스트와 연관된 버퍼. |
Accumulattion Buffer | 일반적으로 연산처리후의 이미지에 사용되며, 해당 버퍼에 직접 그릴수는 없다. |
② 블렌딩
화면에 그려진 출력물은 '색상버퍼'에 저장
> 같은 위치에 다르 그림을 그리면 이전에 저장된 내용물은 덧씌워진다.
여기서 블렌딩은 색상버퍼에 이미 저장된 내용물과 새로 저장되는 내용물에 대한 논리적 연산을 정의
어떻게 보면 캔버스상에서 레이어들을 겹치는것과 유사.
> glEnable(GL_BLEND); // glBegin 사용전 호출.
③ 디더링(Ditherring)
> glEnable(GL_DITHER);
④ 테스트
> Fragment Operation에서 테스트전 연관된 버퍼가 할당되어야 한다.
Scissor Test | glEnable(GL_SCISSOR_TEST); glScissor(x, y, width, height); 테스트들중 가장 간단하다.(제약이 커서?) |
Alpha Test | glEnable(GL_ALPHA_TEST); |
Stencil Test | glEnable(GL_STENCIL_TEST); |
Depth Test | glEnable(GL_DEPTH_TEST); |
⑤ 기타
> 기본적으로 CALayers는 투명하지만, OpenGL 에서는 성능상의 이유로, 불투명하게 하는게 좋다
3. 카메라와 행렬
1) 투영
> 3차원 공간의 오브젝트를 2차원인 디스플레이로 투영하려면
로컬 좌표 -> 월드 좌표 -> 카메라 좌표 -> 투영
> [#참조]
투시투영(Perspective Projection) |
직교투영(Orthographic Projection) |
원근표현이 있는 입체적인 뷰포트(Z좌표 영향O) 주로 3D게임에서 활용도가 높음. (카메라 범위내)근평면(near plane)에서 끝평면(far plane)으로 갈수록 넓어짐. |
원근표현이 전혀 없는 평면적인 뷰포트(Z좌표 영향X) 주로 2D게임에서 활용도가 높음. (카메라 범위내)근평면(near plane)에서 끝평면(far plane)이 동일한 면적. |
2) 좌표와 행렬
월드 좌표 | 디스플레이상 표현되는 좌표. > 워드 프로세서로 치면 특정 단어의 위치를 표현시 N줄 K열로 표기하는셈 |
로컬 좌표 | 오브젝트 내부에 포함된 좌표. > 워드 프로세서에 들어가는 글자 1칸마다의 내부 좌표격. > 오브젝트 갯수만큼 존재 |
카메라 좌표 |
4. 텍스쳐
1) 비트맵
> 미리 만들어진 이미지. 다양한 크기와 색상 존재가능.
> "대용량의 래스터 데이터로 구성되므로 파일 형태로 저장되는 것이 일반적이다. 그러나 안타깝게도 OpenGL은 파일 입출력 기능을 제공하지 않으므로 파일이나 리소스로부터 비트맵을 생성하기 어렵다. 간단한 이미지라면 메모리에서 래스터 데이터를 직접 정의하여 만들어 써야 한다." 1
> 3차원 그래픽에서 글꼴을 비트맵으로 처리하는 경우가 많다.
> 싱글 버퍼일땐 프론트 버퍼, 더블 버퍼링에서는 백 버퍼에서 실행.
① 관련 주요함수
glPixelStore[f, i](GLenum pname, GLfloat param) |
glRasterPos[2,3,4][s,i,f,d][v](x, y, z,w) |
glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); |
2) 픽셀맵
① 관련 주요함수
1 2 3 4 5 6 | void glDrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data); | cs |
> glFuncName[2,3,4][s,i,f,d]인 경우,
2~4가 처리할 함수인자 갯수, 함수명 맨끝의 알파벳 표기는 처리할 타입(short, int, float, double)
3) 텍스처 맵핑
> 흔히 '텍스쳐를 발라 붙인다'/'텍스쳐를 입힌다'등으로 표현되는 기법.
> 텍스처의 좌하단은 (0,0)이고 우상단은 (1,1)이고, 중앙이 (0.5, 0.5)
> 버텍스와 텍스쳐 내부 좌표를 대응시키는것으로 출력처리가 된다.
> 텍스쳐 필터링
① 관련 주요함수
1 2 3 4 5 6 7 | glEnable(GL_TEXTURE_2D) //함수인자에 1~3차원 이미지 가능. ES는 2차원만 가능. glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) glTexCoord[1,2,3,4][s,i,f,d][v](s, t, r, q) glTexEnv[f, i](GLenum target, GLenum pname, GLfloat param) | cs |
5. 조명
환경광 (Ambient Light) | 다른 표면에서 반사된 빛을 받는것. 반사된 빛을 비교적 저렴하고 간단하게 구현하는 방법. |
난반사광 (Diffuse Light) | 모든 방향으로 동일하게 반사되므로 위치와는 관계없이 관찰자의 눈에 빛이 도달하고 관찰자의 위치를 고려할 필요가 없다. |
정반사광 (Specular Light) | 특정한 방향으로 진행하며, 표면에 닿으면 한 방향으로 강하게 반사하여 특정한 각도에서만 관찰할 수 있다. 관찰자의 시점을 모두 고려해야 한다. |
퐁 | 연산비용이 가장 비싸지만, 완성도가 가장 높은 조명이다. |
> glLight 함수 인자중 조명번호에 따르면 조명은 총 8개가 존재.(2^8로 총 256가지 조합?)
> 조명의 디폴트는 모두 (0,0,0,1)로 화면상 암흑상자가 된다.
2) 재질
1 2 | void glDisable( GLenum cap); void glColorMaterial(GLenum face, GLenum mode); | cs |
> glMaterial[f, i][v](GLenum face, GLenum pname, GLfloat* param)로 조명의 어떤 색상을 반사할지 지정
이는 물체의 색상이 사람의 눈에 어떻게 닿는지의 원리와 같다.
재질에 대한 작업은 '빛의 반사'에 대한 처리라서 glColor로 입력된 색상을 무시가능. 만약 재질이 아닌 glColor 색상을 적용 하려면 색상 트래킹으로 처리.
3) 법선
1 | void glNormal3[f,d,i,s,b][v](GLfloat nx, GLfloat ny, GLfloat nz); | cs |
> 조명은 물체표면과의 입사각에 따라 빛의 강도도 달라진다. (빛은 직진한다.)
> OpenGL은 (광원의 각도) 계산을 단순화하기 위해 길이가 1인 법선벡터 사용.
기타. 참조자료
SoEn:소프트웨어 공학 연구소, OpenGL 강좌 소개
Unavailable :: OpenGL Rendering Pipeline
기타. 변경이력
일자 |
변경이력 |
2016-11-24 | 초안 |
'📂기초 및 세팅 note > 2D & 3D' 카테고리의 다른 글
Box2d: 요약 및 정리 (0) | 2017.08.30 |
---|---|
오픈소스 게임엔진 (0) | 2017.04.11 |
OpenGL ES: 기초 및 입문 (1) (0) | 2016.08.04 |
스마트폰기반 개발툴 종류 및 튜토리얼 모음 (0) | 2015.11.07 |
라이센스: 주요 모바일게임 엔진 (0) | 2015.04.23 |