OpenGL은 ARCore를 개발하는데 있어서 중요한 항목중의 하나입니다 여기서는 ARCore에 관련한 기본적인 사항에대해서 알아보겠습니다. 모든것이 마찬가지이지만 기본적인 것은 가장중요하기 때문에 흐름을 이해한다음 여러번 반복하여 익히시길바라겠습니다. 그리고 실제프로젝트에 들어가면 그때마다 상세한것은 문서등을 조사하여 여러분이 스스로 응용하여 작성하는 힘을 키우기 바랍니다 그러므로 여기서는 기초적인사항을 중심으로 설명드리겠습니다. 초보자도 이해할수 있도록 설명을 드릴테니 그대신 하나하나 실제로 실행시키시기를 바랍니다. 전제조건으로 여기서는 Java의 기초지식과 안드로이드스튜디오가 설치되어있고 안드로이드 스마트폰 실기에 연결되있다는 조건으로 시작합니다. 작성일 2023 / 10/ 02
안드로이드 프로젝트 만들기
- 아래 그림과같이 안드로이드 스튜디오에서 New Project 를 선택합니다。

2. 다음에 아래 그림과 같이 No Activity를 선택합니다

3. 그리고 다음 그림과같이 각항목을 넣습니다
— Name : PrimitiveTriangle
— Package name : com.mogusatech.primitivetriangle
Package name 에는 예로서 도메인 이 com 으로 끝나는 경우는 앞뒤를 바꾸어서 넣습니다
mogusatech.com 인경우에는 com.mogusatech 다음에 프로젝트이름 을 위와같이 넣으면 됩니다
— Save location 에는 임으로 지정
— Language 에는 Java 지정합니다
— Minimun SDK 에는 Android 8.0을 지정합니다

4. Finish를 클릭하면 아래 그림과같이 Andriod가 나올경우 클릭하여 Project가 나오게 합니다

5. Project를 클릭하면 아래그림과같이 프로젝트 이름을 아래로 펼칩니다

6. 아래로 펼친후 com.mogusatech.primitivetriangle 부분을 오른쪽 클릭하여 펼친후 Java Class를 선택합니다

7. 아래 그림과 같이 MainActivity.java 파일 이름을 넣고 엔터를 칩니다

8. MainActivity.java 파일을 열고 기본적으로 생성된부분을 전부 삭제하고 아래를 커피하여 넣습니다
package com.mogusatech.primitivetriangle;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
//삼각형을 표시하기위한 처음 Activity부분
// MainActivity 의 이름이 AndroidManifest.xml 파일에 정의 되어있으므로 MainActivity이 불려짐
public class MainActivity extends Activity {
//GLSurfaceView는 OpenGL ES를 렌더링의 일부 또는 전체에 사용하는 애플리케이션을 구축하는 훌륭한 기반입니다.
private GLSurfaceView glView;
//Activity가 생성시 불려짐
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
//GLSurfaceView의 생성 (1)
glView=new GLSurfaceView(this);
glView.setEGLContextClientVersion(2);//(2)
glView.setRenderer(new GLRenderer());
setContentView(glView);
}
//Activity의 onResume 에서 불려짐
@Override
public void onResume() {
super.onResume();
glView.onResume();//(3)
}
//Activity의 onPause 에서 불려짐
@Override
public void onPause() {
super.onPause();
glView.onPause();//(4)
}
}
9. 같은방법으로 같은 폴더내에 GLRenderer.java 파일만듭니다

10. 마찬가지로 기본생성된 코드를 전부삭제하고 아래 코드를 넣습니다
package com.mogusatech.primitivetriangle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
//렌더러 부분
public class GLRenderer implements
GLSurfaceView.Renderer {
private FloatBuffer vertexBuffer;//정점버퍼
//GLSurfaceView가 생성시 불려짐
@Override
public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) {
//쉐이더를 위한 프로그램 생성
GLES.makeProgram();
//정점버퍼를 유효화 함
GLES20.glEnableVertexAttribArray(GLES.positionHandle);
//정점버퍼 만들기 아래는 x,y,z 의 좌표를 나타내 여기서 z 는 0으로 넣고 평면상에서 만든다는것을 생각하고
// 나중에 정육각형 만들때 z 좌표를 생각하는것으로 합니다
float[] vertexs={
0.0f,1.0f,0.0f,//장점 0 가운데 위
0.0f,0.0f,0.0f,//정점 1 화면 가운데
1.0f,1.0f,0.0f,//정점 2 화면 오른쪽 위
};
vertexBuffer=makeFloatBuffer(vertexs);
}
//화면 크기가 변경시 불려짐(3)
@Override
public void onSurfaceChanged(GL10 gl10,int w,int h) {
//화면의 표시영역의 지정
GLES20.glViewport(0,0,w,h);
}
//매 프레임마다 그려질때 불려짐 여기서는 각각의 기기의 성능에따라 초당 60,120 프레임등으로 나타냄
@Override
public void onDrawFrame(GL10 gl10) {
//먼저 화면을 깨끗이 청소합니다
GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//각 정점의 색을 지정 r,g,b ,a : 빨간색,녹색, 파란색,알파 , 여기서는 빨간색을 지정하고 있음
GLES20.glUniform4f(GLES.colorHandle,1.0f,0.0f,0.0f,1.0f);//(D)-[3]
//정점버퍼의 지정
GLES20.glVertexAttribPointer(GLES.positionHandle,3,//(C)-[4]
GLES20.GL_FLOAT,false,0,vertexBuffer);
//Primitive 그리기
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
}
//float배열을 FloatBuffer로의 변환
private FloatBuffer makeFloatBuffer(float[] array) {
FloatBuffer fb=ByteBuffer.allocateDirect(array.length*4).order(
ByteOrder.nativeOrder()).asFloatBuffer();
fb.put(array).position(0);
return fb;
}
}
11. 위와 같은방법으로 GLES.java 파일을 생성하고 아래코드를 넣습니다
package com.mogusatech.primitivetriangle;
import android.opengl.GLES20;
//쉐이더 조작하기
public class GLES {
//정점쉐이더 코드
private final static String VERTEX_CODE=
"attribute vec4 a_Position;"+//(C)-[1]
"void main(){"+
"gl_Position=a_Position;"+
"}";
//flagment 쉐이더 코드
private final static String FRAGMENT_CODE=
"precision mediump float;"+
"uniform vec4 u_Color;"+//(D)-[1]
"void main(){"+
"gl_FragColor=u_Color;"+
"}";
//현재으 쉐이더 시스템
private static int program;//프로그램 오브젝트
//ハンドル
public static int positionHandle;//위치 핸들
public static int colorHandle; //색을 나타내는 핸들
//쉐이더 생성하기
public static void makeProgram() {
//쉐이더 오브젝트생성
int vertexShader=loadShader(GLES20.GL_VERTEX_SHADER,VERTEX_CODE);
int fragmentShader=loadShader(GLES20.GL_FRAGMENT_SHADER,FRAGMENT_CODE);
//프로그램 오브젝트생성
program=GLES20.glCreateProgram();
GLES20.glAttachShader(program,vertexShader);
GLES20.glAttachShader(program,fragmentShader);
GLES20.glLinkProgram(program);
//핸들 취득
positionHandle=GLES20.glGetAttribLocation(program,"a_Position");
colorHandle=GLES20.glGetUniformLocation(program,"u_Color");
//프로그램 오브젝트 이용개시
GLES20.glUseProgram(program);
}
//오브젝트 쉐이더 생성
private static int loadShader(int type,String shaderCode) {
int shader=GLES20.glCreateShader(type);
GLES20.glShaderSource(shader,shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
12. 아래 그림과같이 main 폴더안에 있는 Androidmanifest.xml 파일을 열고 아래의 코드를 넣습니다

13. Androidmanifest.xml 의 내용
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PrimitiveTriangle"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
14. 실행하기

15. 실행결과는 다음과같습니다

コメント