Android 개발 OpenGL ES 3D 그래 픽 인 스 턴 스 상세 설명 그리 기

OpenGL ES 는 OpenGL 3 차원 그래 픽 API 의 부분 집합 으로 휴대 전화,PDA,게임 호스트 등 내장 형 장 치 를 대상 으로 설계 되 었 다.오 폰 은 현재 OpenGL ES 1.0 을,OpenGL ES 1.0 은 OpenGL 1.3 규범 을,OpenGL ES 1.1 은 OpenGL 1.5 규범 을 기반 으로 지원 하고 있다.본 고 는 주로 OpenGL ES 를 이용 하여 도형 을 그 리 는 기본 적 인 절 차 를 소개 한다.
본문의 내용 은 세 부분 으로 구성 되 어 있다.먼저 EGL 을 통 해 OpenGL ES 의 프로 그래 밍 인 터 페 이 스 를 얻 습 니 다.그 다음 에 3D 프로그램 을 구축 하 는 기본 개념 을 소개 한다.마지막 으로 응용 프로그램 예제 입 니 다.
OpenGL ES 는 본질 적 으로 그래 픽 렌 더 링 라인 의 상태 기 이 고 EGL 은 이러한 상 태 를 감시 하고 프레임 버퍼 와 다른 렌 더 링 면 의 외부 층 을 유지 하 는 데 사용 된다.그림 1 은 전형 적 인 EGL 시스템 레이아웃 그림 이다.EGL 윈도우 디자인 은 마이크로소프트 윈도(WGL)와 유 닉 스(GLX)에 익숙 한 OpenGL 을 위 한 네 이 티 브 인 터 페 이 스 를 기반 으로 한 것 으로 후자 와 비슷 하 다.OpenGL ES 그래 픽 파이프라인 의 상 태 는 EGL 이 관리 하 는 컨 텍스트 에 저 장 됩 니 다.프레임 버퍼 와 기타 그리 기 렌 더 링 면 은 EGL API 를 통 해 생 성,관리,소각 합 니 다.EGL 은 장치 디 스 플레이 와 가능 한 장치 렌 더 링 설정 에 대한 접근 도 제어 하고 제공 합 니 다.

그림 1
OpenGL ES 는 렌 더 링 컨 텍스트 와 렌 더 링 면 이 필요 합 니 다.렌 더 링 컨 텍스트 에 OpenGL ES 의 상태 정 보 를 저장 하고 렌 더 링 면 은 그림%1 개의 캡 션 을 편 집 했 습 니 다.OpenGL ES 를 작성 하기 전에 EGL 작업 이 필요 합 니 다.
장치 가 지원 하 는 디 스 플레이 핸들 을 조회 하고 초기 화 합 니 다.
렌 더 링 면 을 만 들 고 OpenGL ES 도형 을 그립 니 다.
렌 더 링 컨 텍스트 를 만 듭 니 다.EGL 은 렌 더 링 면 과 연 결 된 OpenGL ES 렌 더 링 컨 텍스트 를 만들어 야 합 니 다.
Ophone 에 서 는 EGL 이 4 가지 종 류 를 포함 하 는데 각각 EGLDisplay:핸들 표시,EGLConfig:설정 류 입 니 다.EGLContext:컨 텍스트 렌 더 링;의 클래스 와 EGLSurface:렌 더 링 가능 한 보기 클래스 입 니 다.
EGL 은 OpenGL ES 와 로 컬 창 시스템 사이 의 중간 층 으로 볼 수 있다.로 컬 창 시스템 은 GNU/Linux 에서 X 창 시스템 이나 Mac OX X's Quartz 등 을 말한다.EGL 에서 렌 더 링 면 의 종 류 를 확인 하기 전에 EGL 은 바 텀 창 시스템 과 통신 해 야 합 니 다.EGL 은 운영 체제 에 따라 창 시스템 이 다 르 기 때문에 EGLDisplay 라 는 투명 한 창 형식 을 제공 합 니 다.그것 은 각종 창 시스템 을 추상 화 했다.그래서 먼저 EGLDisplay 대상 을 만 들 고 초기 화 해 야 합 니 다.

// EGLContext     getEGL  EGL  
EGL10 egl = (EGL10)EGLContext.getEGL();
//  EGLDisplay, EGL_DEFAULT_DISPLAY             
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
//   EGLDispla        
int[] version = new int[2];
egl.eglInitialize(dpy, version);
모든 EGLDisplay 는 사용 하기 전에 초기 화 되 어야 합 니 다.EGLDisplay 를 초기 화 하 는 동시에 시스템 의 EGL 구현 버 전 번 호 를 얻 을 수 있 습 니 다.버 전 번 호 를 통 해 해당 OpenGL ES API 를 합 리 적 으로 활용 하면 호환성 이 좋 은 프로그램 을 작성 하여 더 많은 장치 에 적응 하고 최대한 의 이식 성 을 제공 할 수 있 습 니 다.함수 원형 초기 화:
boolean eglInitialize(EGLDisplay display, int[] major_minor)
디 스 플레이 는 올 바른 EGLDisplay 인 스 턴 스 입 니 다.함수 호출 완료 시,majorminor 는 현재 EGL 버 전 번 호 를 부여 합 니 다.예 를 들 어 EGL 1.0,majorminor[0]는 1,majorminor[1]는 0 이다.EGLSurface 는 EGL 렌 더 링 면 과 관련 된 모든 정 보 를 포함 하고 있 습 니 다.EGLSurface 설정 정 보 를 조회 하 는 데 는 두 가지 방법 이 있 습 니 다.하 나 는 모든 설정 정 보 를 조회 하 는 것 입 니 다.그 중에서 가장 적합 한 것 을 선택 하 십시오.둘째,설정 정 보 를 지정 하여 시스템 에서 가장 좋 은 일치 결 과 를 제공 합 니 다.일반적으로 두 번 째 방법 을 채택 한다.사용 자 는 configSpec 를 통 해 원 하 는 설정 을 지정 합 니 다.함수 eglChooseConfig 는 매개 변수 Configs 를 통 해 가장 좋 은 설정 목록 을 되 돌려 줍 니 다.이후 획득 한 Configs 를 이용 하여 eglCreate Context 를 호출 하여 렌 더 링 컨 텍스트 를 만 들 고 이 함 수 는 EGLContext 구 조 를 되 돌려 줍 니 다.렌 더 링 면 EGLSurface 생 성 은 함수 eglCreate WindowSurface 를 통 해 이 루어 집 니 다.하나의 프로그램 이 여러 개의 EGLContext 를 만 들 수 있 습 니 다.egl MakeCurrent 는 렌 더 링 컨 텍스트 를 렌 더 링 면 에 연결 하 는 것 입 니 다.조회 함수 eglGetCurrentContext,eglGetCurrentDisplay 와 eglGetCurrentSurface 는 현재 시스템 의 렌 더 링 컨 텍스트,디 스 플레이 핸들 과 렌 더 링 면 을 얻 는 데 사 용 됩 니 다.마지막 으로 EGLContext 의 정적 방법 getGL 은 OpenGL ES 의 프로 그래 밍 인 터 페 이 스 를 얻 습 니 다.아래 의 프로그램 부분 은 상술 한 내용 을 총 결 하 였 다.

EGL10 egl = (EGL10)EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2];
egl.eglInitialize(dpy, version);
int[] configSpec = {
EGL10.EGL_RED_SIZE, 5,
EGL10.EGL_GREEN_SIZE, 6,
EGL10.EGL_BLUE_SIZE, 5,
EGL10.EGL_DEPTH_SIZE, 16,
EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
EGLConfig config = configs[0];
EGLContext context = egl.eglCreateContext(dpy, config,
EGL10.EGL_NO_CONTEXT, null);
EGLSurface surface = egl.eglCreateWindowSurface(dpy, config,
sHolder, null);
egl.eglMakeCurrent(dpy, surface, surface, context);
GL10 gl = (GL10)context.getGL();
3D 도형 을 구축 하 는 점
점 은 3D 모델 을 구축 하 는 기초 이다.OpenGL ES 의 내부 계산 은 점 에 기초 한 것 이다.점 으로 도 광원 의 위치,물체 의 위 치 를 나 타 낼 수 있다.일반적으로 우 리 는 한 조 의 부동 소수점 으로 점 을 표시 한다.예 를 들 어 정사각형 의 네 개의 정점 은 다음 과 같다.

float vertices[] = {
-1.0f, 1.0f, 0.0f, //  
-1.0f, -1.0f, 0.0f, //  
1.0f, -1.0f, 0.0f, //  
1.0f, 1.0f, 0.0f, //  
};
성능 을 향상 시 키 기 위해 서 는 부동 소수점 배열 을 바이트 버퍼 에 저장 해 야 합 니 다.그래서 다음 작업 이 있 습 니 다.

ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
그 중에서 ByteOrder.nativeOrder()는 이 컴퓨터 의 바이트 순 서 를 가 져 오 는 것 입 니 다.OpenGL ES 는 그래 픽 렌 더 링 라인 을 조작 하 는 함수 가 있 습 니 다.기본 적 인 상황 에서 이러한 함수 기능 의 사용 상 태 는 닫 혀 있 습 니 다.이 함수 들 을 사용 하고 닫 으 면 glEnableClient State,glDisableClient State 로 완성 할 수 있 습 니 다.
//지정 하려 면 지정 배열 을 사용 해 야 합 니 다.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//배열 의 종류 와 바이트 버퍼 를 사용 합 니 다.형식 은 GL 입 니 다.FLOAT
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
//더 이상 필요 하지 않 을 때 정점 배열 을 닫 습 니 다.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
가장자리
변 은 두 점 을 연결 하 는 선 으로 다각형 면 의 가장자리 이다.
다각형
다각형 은 변 으로 구 성 된 단 폐 환 이다.OpenGL ES 의 다각형 은 돌출 다각형 이 어야 한다.즉,다각형 의 내부 에서 두 점 을 임의로 취하 고 이 두 점 을 연결 하 는 선분 이 모두 변화 가 많은 내부 에 있다 면 이 다각형 은 돌출 다각형 이다.다각형 을 그 릴 때 렌 더 링 방향 을 지정 하고 시계 방향 과 시계 반대 방향 으로 나 누 어야 합 니 다.방향 이 다각형 의 방향,즉 정면 과 뒷면 을 결정 하기 때문이다.가 려 진 부분 을 과장 하지 않 으 면 프로그램의 성능 을 효과적으로 향상 시 킬 수 있다.함수 glFront Face 는 렌 더 링 정점 의 방향 을 정의 합 니 다.
//CCW 방향 을'정면'으로 설정 합 니 다.CCW 는 CounterClockWise 이 고 시계 반대 방향 입 니 다.
glFrontFace(GL_CCW);
//CW 방향 을"정면"으로 설정 합 니 다.CW 는 ClockWise 이 고 시계 방향 입 니 다.
glFrontFace(GL_CW);
과장 하 다
이상 의 개념 설명 이 있 으 면 지금 가장 중요 한 작업 인 렌 더 링 을 해 야 한다.렌 더 링 은 물체 좌표 가 지정 한 그림 을 프레임 버퍼 에 있 는 그림 으로 바 꾸 는 것 입 니 다.그림 과 정점 좌 표 는 밀접 한 관 계 를 가진다.이 관 계 는 그리 기 모드 를 통 해 제 시 됩 니 다.그리 기 모드 에 자주 사용 되 는 GLPOINTS、GL_LINE_STRIP、
GL_LINE_LOOP、GL_LINES、 GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。다음은 각각 소개 한다.
GL_POINTS:모든 정점 을 하나의 점 으로 처리 합 니 다.정점 n 은 점 n 을 정의 하고 n 개의 점 을 함께 그립 니 다.

GL_LINES:모든 정점 을 하나의 독립 된 선분 으로 하고 정점 2n-1 과 2n 사이 에 n 개의 선분 을 정의 하 며 모두 N/2 개의 선분 을 그립 니 다.N 이 홀수 라면 마지막 정점 을 무시 합 니 다.

GL_LINE_STRIP:첫 번 째 정점 에서 마지막 정점 까지 차례대로 연 결 된 선분 을 그립 니 다.n 과 n+1 개의 정점 은 선분 n 을 정의 하고 모두 N-1 개의 선분 을 그립 니 다.

GL_LINE_LOOP:첫 번 째 정점 에서 마지막 정점 까지 순서대로 연 결 된 라인 을 그립 니 다.그리고 마지막 정점 은 첫 번 째 정점 과 연 결 됩 니 다.n 과 n+1 개의 정점 은 선분 n 을 정의 한 다음 에 마지막 선분 은 정점 N 과 1 사이 에 정의 되 어 모두 N 개의 선분 을 그립 니 다.

GL_TRIANGLES:세 개의 정점 을 하나의 독립 된 삼각형 으로 합 니 다.정점 3n-2,3n-1 과 3n 은 n 번 째 삼각형 을 정의 하고 모두 N/3 개의 삼각형 을 그립 니 다.

GL_TRIANGLE_STRIP:연 결 된 삼각형 을 그립 니 다.홀수 n,정점 n,n+1 과 n+2 에 대해 n 번 째 삼각형 을 정의 했다.짝수 n,정점 n+1,n 과 n+2 는 n 번 째 삼각형 을 정의 하고 모두 N-2 개의 삼각형 을 그립 니 다.

GL_TRIANGLE_FAN:연 결 된 삼각형 을 그립 니 다.삼각형 은 첫 번 째 정점 과 그 후에 주어진 정점 에 의 해 확정 된다.정점 1,n+1 과 n+2 는 n 번 째 삼각형 을 정의 하고 모두 N-2 개의 삼각형 을 그립 니 다.

함수 그리 기:
void glDrawArrays(int mode, int first, int count)
void glDrawElements(int mode, int count, int type, Buffer indices)
glDrawArrays 는 모든 배열 에서 first 부터 first+count C 1 까지 의 배열 요 소 를 사용 하여 기하학 적 메타 시퀀스 를 만 듭 니 다.mode 는 그리 기 모드 입 니 다.
glDrawElements 는 count 요 소 를 사용 하여 그림 시퀀스 를 정의 합 니 다.type 은 indices 배열 의 데이터 형식 이 고 mode 는 그리 기 모드 이 며 indices 배열 저장 정상 입 니 다.
점 의 색인 값.
예 를 들다
위 에서 설명 한 내용 을 이용 하여 오 폰 에 3D 구형 을 그 리 는 프로그램 을 제시 합 니 다.효과 도 는 다음 과 같다.

그림 2 구형 예시
주요 그리 기 프로그램:

static private FloatBuffer vertex;//         
static private FloatBuffer normal;//          
float[] lightPos = new float[] {10.0f, 10.0f, 10.0f, 1.0f };//     
private static final int STEP = 24;//
private static final float RADIUS = 1.0f;//  
protected void init(GL10 gl) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//      
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
gl.glEnable(GL10.GL_LIGHTING);//    
gl.glEnable(GL10.GL_LIGHT0); //    
gl.glClearDepthf(1.0f);//      
gl.glDepthFunc(GL10.GL_LEQUAL);//          ,GL_LEQUAL                                 
gl.glEnable(GL10.GL_DEPTH_TEST);//      
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);//      GL_SMOOTH
}
protected void drawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 7f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);//
drawSphere(gl, RADIUS, STEP, STEP); //    
}
public static void gluLookAt (GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
그것 은 모두 세 개의 좌 표를 받 아들 이 는데 각각 eye,center,up 이다.eye 는 우리 의 눈 이'세계 좌표계'에 있 는 위 치 를 나타 낸다.center 는 눈 이'보 는'그 점 의 좌 표를 나타 낸다.up 좌 표 는 관찰자 자체 의 방향 을 나타 낸다.만약 에 관찰 점 을 우리 의 눈 에 비유한다 면 이 up 은 우리 가 정립 인지 역 립 인지 또는 어떤 각도 에서 보 는 지 를 나타 낸다.여 기 는 정립 방식 이기 때문에{0,1,0}이다.

private static void drawSphere(GL10 gl, float radius,
int stacks, int slices) {
vertex=allocateFloatBuffer( 4* 6 * stacks * (slices+1) );
normal=allocateFloatBuffer( 4* 6 * stacks * (slices+1) );
int i, j, triangles;
float slicestep, stackstep;
stackstep = ((float)Math.PI) / stacks;
slicestep = 2.0f * ((float)Math.PI) / slices;
for (i = 0; i < stacks; ++i)
{
float a = i * stackstep;
float b = a + stackstep;
float s0 = (float)Math.sin(a);
float s1 = (float)Math.sin(b);
float c0 = (float)Math.cos(a);
float c1 = (float)Math.cos(b);
float nv;
for (j = 0; j <= slices; ++j)
{
float c = j * slicestep;
float x = (float)Math.cos(c);
float y = (float)Math.sin(c);
nv=x * s0;
normal.put(nv);
vertex.put( nv * radius);
nv=y * s0;
normal.put(nv);
vertex.put( nv * radius);
nv=c0;
normal.put(nv);
vertex.put( nv * radius);
nv=x * s1;
normal.put(nv);
vertex.put( nv * radius);
nv=y * s1;
normal.put(nv);
vertex.put( nv * radius);
nv=c1;
normal.put(nv);
vertex.put( nv * radius);
}
}
normal.position(0);
vertex.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
gl.glEnableClientState (GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState (GL10.GL_NORMAL_ARRAY);
triangles = (slices + 1) * 2;
for(i = 0; i < stacks; i++)
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
i * triangles, triangles);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
private static FloatBuffer allocateFloatBuffer(int capacity){
ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
vbb.order(ByteOrder.nativeOrder());
return vbb.asFloatBuffer();
}
요약:
본 고 는 오 폰 에서 OpenGL ES 를 이용 해 그래 픽 을 그 리 는 기본 개념 과 방법 을 소개 한다.OpenGL ES 에는 무늬,빛 과 재질,혼합,안개,몽 판,반사,3D 모델 로드 등 다른 내용 도 많이 있다.OpenGL ES 함 수 를 이용 하여 풍부 한 그래 픽 애플 리 케 이 션 과 게임 인 터 페 이 스 를 그 릴 수 있 습 니 다.

좋은 웹페이지 즐겨찾기