본문 바로가기
C++ 200제/코딩 IT 정보

[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼

by vicddory 2017. 10. 20.

[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼(Meshe, Lines OptimizationFrame Buffers


Meshes and Lines Optimization (메쉬와 라인 옵션)

OpenGL ES에서 점point를 그리는(찍는) 방법은 한 가지이지만, 선line과 삼각형triangle을 그리는 방법엔 3가지가 있다.

선을 그리는 방법은 아래다.


. normal

. strip

. loop


OpenGL ES에서 삼각형을 (옵션) 그리는 방법 아래다.


. normal

. strip

. fan


어떻게 그리느냐에 따라 속도 향상과 메모리 절약이 가능하다.


지금 다뤄볼 것은 3차원 다각형mesh이다. 여기서는 OpenGL ES 삼각형을 면face이라 부르자. 꼭지점vertex들의 배열을 이용해서 3차원 큐브cube를 만들어보자.


1
2
3
4
5
6
7
8
9
10
11
12
// Array of vertices to a cube.
GLfloat cube3D[] =  
{
    0.50,-0.50,-0.50,    // vertex 1
    0.50,-0.50,0.50,    // vertex 2
    -0.50,-0.50,0.50,    // vertex 3
    -0.50,-0.50,-0.50,    // vertex 4
    0.50,0.50,-0.50,    // vertex 5
    -0.50,0.50,-0.50,    // vertex 6
    0.50,0.50,0.50,        // vertex 7
    -0.50,0.50,0.50        // vertex 8
}
cs


float 값의 소수점은 크게 문제가 되지 않지만, 잘 사용하면 메모리를 절약하고 파일 사이즈를 줄일 수도 있다.


그래서 나는 소수점 둘째 자리까지만 사용하는 것을 즐긴다. 여기서 중요한건 다각형이 갖고있는 세 가지 중요한 정보다. (vertex, texture coordinates, nomals(꼭지점, 텍스쳐 좌표, 법선)).


[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼[[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼]


일차원 배열에 모든 정보를 함께 담는 게 좋으며, 이런 배열을 구조 배열(Array of Structures)이라 부른다. 각각의 꼭지점 데이터를 위와 같은 방법으로 생성할 수 있다.


이렇게 데이터를 배열에 담으면 OpenGL ES 배열에 데이터 타입GLfloat이 하나뿐인데 별문제가 없을까?


없다. 문제 될 게 없다.


왜냐면 받는 쪽은 float 배열 데이터만 받기 때문이다.


받는 쪽에선 받아온 모든 데이터를 GLfloat로 변환해 사용한다. 자, 이제 3차원 어플리케이션의 정보를 생성/설정하고 메쉬를 OpenGL ES의 버퍼에 담아보자.


Buffers


opengl_crane_hooks_example[[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼]


OpenGL ES는 항구의 크레인처럼 동작하는 상태 머신과도 같다. 조금 다르게 말하자면, OpenGL은 여러 개의 어깨arm와 고리hook를 갖고 있는 항구의 크레인처럼 행동한다.


그래서 그림처럼 동시에 여러개를 잡아둘 수 있다. 기본적으로는 4종 6개의 어깨가 있다.


- Texture 어깨 2개

- Buffer object 어깨 2개

- render buffer 어깨 1개

- frame buffer 어깨 1개


각각의 어깨들은 하나의 물건만 잡아놓을 수 있다. 사용자는 OpenGL ES에게 무언가를 잡으라 지시할 수 있는데, 잡을 것의 이름과 id만 알려주면 된다


OpenGL에게 잡으라 알려주는 명령어는 glBind*이다. 앞으로 glBind*라는 명령어를 보면 무언가를 잡는다고 이해하면 된다.


한가지 예외가 있지만 그건 나중에 살펴보도록 하고, OpenGL ES가 무언가를 잡으려면 그 무언가를 만들어야 하는데, glGen* 명령어는 잡아야 할 무언가를 만들어준다.


Frame Buffers

Frame Buffers는 Render output을 위한 임시 저장소이다.

render(그릴 것)가 일단 frame buffer에 들어가면 기기의 화면에 표시할 수도 있고, 이미지 파일로 저장될 수도 있다. 아래는 frame buffer와 관련된 두 가지 기능이다.


1. GLvoid glGenFramebuffers (GLsizei n, GLuint* framebuffers)

n : 한 번에 몇 개의 frame buffer를 만들 것인가.

framebuffers : 생성된 frame buffer의 번호를 저장할 변수. 하나 이상을 만들 때는 배열의 시작점을 넣음.


2. GLvoid glBindFramebuffer (GLenum target, GLuint framebuffer)

target : 항상 GL_FRAMEBUFFER.

framebuffer : 연결할 frame buffer의 번호.


처음 Object를 binding 할 때 OpenGL ES의 코어는 자동으로 버퍼를 생성하지만, 사용자에게 이름과 id까지 생성해 알려주진 않는다.


OpenGL ES 메쉬[[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼]


그렇기에 useglGen* 함수로 버퍼의 이름과 id를 기입하여 binding 하는 것이 좋다. 헷갈리는가? 그렇다면 아래의 코드를 첫 줄부터 자세히 보도록 하자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GLuint frameBuffer;
 
// Creates a name/id to our frameBuffer.
glGenFramebuffers(1&frameBuffer);
 
// The real Frame Buffer Object will be created here,
// at the first time we bind an unused name/id.
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
 
// We can suppress the glGenFrambuffers.
// But in this case we'll need to manage the names/ids by ourselves.
// In this case, instead the above code, we could write something like:
//
// GLint frameBuffer = 1;
// glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
cs


4번 glGenFramebuffers는 생략해도 되지만, 그럴 경우 버퍼들의 번호를 사용자가 직접 관리해야 한다.


14번처럼 frameBuffer란 변수를 생성해 glGenFramebuffers에게 frameBuffer 변수의 위치와 번호로 생성할 것을 지시할 수 있다.


출처 : All About OpenGL ES 2.X 번역

[OpenGL ES] 2. 메쉬, 라인옵션, 프레임 버퍼

댓글