본문 바로가기

프로그래밍/Android

API demos openGL es 2.0

 

ApiDemos GLES20Activity.java / GLES20TriangleRenderer.java

glVertexAtribPointer() , glDrawElemnts() 등 몇가지 메쏘드는 안드로이드버전 2.3 이상..

 

>> 2.0 호환여부 검사

ActivityManager am = (ActivityManager) getSystemService( Context.ACTIVITY_SERVICE );

ConfigurationInfo info = am.getDeviceConfigurationInfo();

if (info.reqGlEsVersion >= 0x20000 ) {

// 지원함

}

 

2.0 은 기존 그래픽 파이프라이의 버텍스, 프레그먼트 프로세스가 쉐이더로 변경되었다.

렌더러에서 GL10 인터페이스는 무시되며, GLES20 클래스를 static 호출로 사용하면 된다.

 

 

>> 쉐이더 적용 및 프로그램 생성

 

private final String mVertexShader = "쉐이더코드";

private final String mFragmentShader = "쉐이더코드";

 

public void onSurfaceCreated( GL10 glInused, EGLConfig config ) {

// 쉐이더 생성

int vertexShader = GLES20.glCreateShader( GLES20.GL_VERTEX_SHADER );

 

if( vertexShader != 0 ) {

// 소스 지정

GLES20.glShaderSource( vertexShader , mVertexShader );

 

// 컴파일

GLES20.glCompileShader( vertexShader );

 

int[] compiled = new int[1];

GLES20.glGetShaderiv(vertexShader, GLES20.GL_COMPILE_STATUS, compiled, 0 );

if( compiled[0] == 0 ) {

// 컴파일 오류

GLES20.glDeleteShader(vertexShader);

}

}

 

// 프래그먼트 쉐이더도 위와 같이 생성-소스지정-컴파일 과정을 거친다.

int pixelShader = GLES20.glCreateShader( GLES20.GL_FRAGMENT_SHADER );

.

.

.

 

// 프로그램 생성 및 쉐이더 적용

int program = GLES20.glCreateProgram();

if( program != 0 ) {

GLES20.glAttachShader( program, vertexShader );

GLES20.glAttachShader( program, pixelShader );

 

GLES20.glLinkProgram( program );

 

int[] linkStatus = new int[1];

GLES20.glGetProgramiv( program, GLES20.GL_LINK_STATUS, linkStatus, 0);

if( linkStatus[0] != GLES20.GL_TRUE ) {

// 링크 실패

GLES20.glDeleteProgram( program );

}

 

mProgram = program;

}

 

 

>> 어트리뷰트

쉐이더 코드에서 선언한 변수에 사용할 메모리를 지정해야 한다.

attribute는 glGetAttribLocation

uniform은 glGetUniformLocation

 

버텍스 쉐이더 코드가 아래와 같은 경우 설정을 보자.

 

    private final String mVertexShader =

        "uniform mat4 uMVPMatrix;\n" +

        "attribute vec4 aPosition;\n" +

        "attribute vec2 aTextureCoord;\n" +

        "varying vec2 vTextureCoord;\n" +

        "void main() {\n" +

        "  gl_Position = uMVPMatrix * aPosition;\n" +

        "  vTextureCoord = aTextureCoord;\n" +

        "}\n";

 

int maPositionHandle;

int maTextureHandle;

int maMVPMatrixHAndle;

 

// 어트리뷰트 설정( 쉐이더에서 접근 가능한 변수 )

// 포지션

maPositionHandle = GLES20.glGetAttribLocation( program, "aPosition" );

 

// uv

maTextureHandle = GLES20.glGetAttribLocation( program, "aTextureCoord" );

 

// 매트릭스

maMVPMatrixHandle = GLES20.glGetUniformLocation( program, "uMVPMatrix" );

 

 

 

>> 카메라와 프로젝션 설정은 매트릭스로 저장

float[] mVMatrix = new float[16];

float[] mMVPMatirx = new float[16];

float[] mPMatrix = new float[16];

float[] mMMatrix = new float[16];

 

Matrix.setLookAtM( mVMatrix, 0, 0, 0, -5.0f, 0f, 0f, 0f, 1.0f, 0.0f );

 

>> 텍스처 생성이나 바인딩은 변경없음.

}

 

>> 프로젝션 매트릭스

Matrix.frustumM( mPMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

 

 

이제 프레임을 그린다.

예제에서의 버텍스 배열은 x,y,z,u,v 의 float 배열이고, 삼각형(버텍스 3개)인 경우이다.

( 한개의 버텍스는 sizeof(float) * 5 인 20byte )

FloatBuffer mTriangleVertices;

 

public void onDrawFrame( GL10 glUnused ) {

// 쉐이더 프로그램 사용

GLES20.glUseProgram( mProgram );

 

// 텍스처 바인딩

GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );

GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, mTextureID );

 

mTriangleVertices.position(0);

 

// 쉐이더에서 사용할 변수의 실제 위치를 지정해 주어야 한다.

// (핸들 index, 크기, 타입, 법선벡터 여부(normalize), 버텍스당 크기, 버퍼 )

GLES20.glVertexAttribPointer( maPositionHandle, 3, GLES20.GL_FLOAT, false,

20 , mTriangleVertices );

 

GLES20.glEnableVertexAttribArray( mPositionHandle );

 

// uv 값도 동일한 방법으로 지정한다.

mTriangleVertices.position(3);

GLES20.glVertexAttribPointer( maTextureHandle, 2, GLES20.GL_FLOAT, false,

20, mTiangleVertices );

GLES20.glEnableVertexAttribArray( maTextureHAndle );

 

// 매트릭스 설정

// 변형

Matrix.setRotateM( mMMatrix, 0, angle, 0, 0, 1.0f );

 

// 뷰 변환 적용( mMVPMatrix = mVMatrix * mMMatrix )

Matrix.multiplyMM( mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0 );

 

// 프로젝션 변환( mMVPMatrix = mPMatrix * mMVPMatrix )

Matrix.multiplyMM( mMVPMatirx, 0, mProjMatrix, 0, mMVPMatrix, 0 );

 

// 매트릭스의 주소 지정

GLES20.glUniformMatrix4fv( muMVPMatrixHandle, 1, false, mMVPMatrix, 0 );

GLES20.glDrawArrays( GLES20.GL_TRIANGLES, 0, 3 );

}

 

 

인덱싱을 통한 그리기에는 1.1과 동일하게 GLES20.glDrawElements 를 사용하면 된다.

'프로그래밍 > Android' 카테고리의 다른 글

Data Animation???  (0) 2012.04.18
Assets 폴더의 이미지 읽기  (0) 2012.03.15
JSON  (0) 2012.01.31
HTTP POST/GET 몇가지 정리  (0) 2012.01.30
OpenGL es 조명  (0) 2011.12.07
GLSurfaceView 배경 투명하게  (1) 2011.11.04
최상위 뷰 만들기  (0) 2011.10.27
OpenGL 프레임버퍼 사용  (0) 2011.10.27
ADB tcp/usb 연결설정  (0) 2011.10.26
sdk3.0 fragment를 하위버전에서 사용하기  (0) 2011.10.19