FireMonkey 예제 자료

FireMonkey(파이어몽키) Live2D_android.jar sdk 활용한 live2d 실행

kimsyo11 2023. 1. 7. 15:01
728x90

공부에 도움이 되셨기를 바라겠습니다

델파이 버전 : 11.2

구동한 기기 : Z폴드3 (안드로이드13 버전)

 

live2d_android.pas
0.10MB

live2d_android.jar
0.10MB
haru.zip
1.51MB

 
 

live2d_android.jar 라이브러리 추가후 jar내에 있는 함수들 호출하여 코딩 짜시면 됩니다

live2d_android.jar파일내 함수 호출 할수 있게 pas 파일 변환하여 live2d_android.pas 파일까지 업로드 합니다

 

 
 
Livde2D_android.jar sdk 활용한 live2d 실행

SampleGLSurfaceView.java 와 SampleActivity.java 내용 토대로 짜둔것입니다

SampleGLSurfaceView.java 와 SampleActivity.java 코드 내용은 스크롤 맨 밑으로 내려보면 있습니다

 

Live2D 시작 코딩

uses FMX.Helpers.Android, Androidapi.JNI.OpenGL, Androidapi.Helpers, 
FMX.Platform.Android, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNIBridge,
 Androidapi.JNI.JavaTypes, live2d_android, Androidapi.JNI.Os;

 GLRenderer = class(TJavaLocal, Androidapi.JNI.OpenGL.JGLSurfaceView_Renderer)
   private
    var MODEL_PATH    : string;
        TEXTURE_PATHS : TArray<string>;
  public
    constructor Create;
    procedure onDrawFrame(gl: JGL10); cdecl;
    procedure onSurfaceChanged(gl: JGL10; width: Integer; height: Integer); cdecl;
    procedure onSurfaceCreated(gl: JGL10; config: JEGLConfig); cdecl;
 end;

var
  JGLRenderer : Androidapi.JNI.OpenGL.JGLSurfaceView_Renderer;
  live2DModel : JLive2DModelAndroid;

procedure PermissionState;
begin
  if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then
    if TAndroidHelper.context.checkSelfPermission(StringToJString('android.permission.WRITE_EXTERNAL_STORAGE'))
    = TJPackageManager.JavaClass.PERMISSION_DENIED then
    begin
      TAndroidHelper.Activity.requestPermissions(CreateJavaStringArray([
      'android.permission.WRITE_EXTERNAL_STORAGE'
      ]),123);
    end;
end;


constructor GLRenderer.Create;
begin
  inherited Create;
  live2DModel := TJLive2DModelAndroid.Create;
  MODEL_PATH := 'haru/haru.moc';
  TEXTURE_PATHS := ['haru/haru.1024/texture_00.png','haru/haru.1024/texture_01.png','haru/haru.1024/texture_02.png'];
end;

procedure GLRenderer.onDrawFrame(gl: JGL10); cdecl;
begin
  gl.glMatrixMode(TJGL10.JavaClass.GL_MODELVIEW);
  gl.glLoadIdentity;
  gl.glClear(TJGL10.JavaClass.GL_COLOR_BUFFER_BIT);
  var t : Double := (TJUtSystem.JavaClass.getUserTimeMSec / 1000) * (2 * PI);
  var cycle : Double := 3;
  var sin : Double := Sin(t / cycle);
  live2DModel.setParamFloat(StringToJString('PARAM_ANGLE_X'),single(30*sin));
  live2DModel.setGL(gl);
  live2DModel.update();
  live2DModel.draw();
end;

procedure GLRenderer.onSurfaceChanged(gl: JGL10; width: Integer; height: Integer); cdecl;
begin
  gl.glViewport(0,0, width, height);
  gl.glMatrixMode(TJGL10.JavaClass.GL_PROJECTION);
  gl.glLoadIdentity();
  var modelWidth : Float32 := live2DModel.getCanvasWidth();
  var aspect     : Float32 := width / height;
  gl.glOrthof(0, modelWidth, modelWidth / aspect, 0, 0.5, -0.5);
end;

procedure GLRenderer.onSurfaceCreated(gl: JGL10; config: JEGLConfig); cdecl;
begin
  var GetContext := SharedActivityContext;
  var input := GetContext.getAssets.open(StringToJString(MODEL_PATH));
 live2DModel := TJLive2DModelAndroid.JavaClass.loadModel(input);
  input.close;
  for var I : integer := 0 to High(TEXTURE_PATHS) do
  begin
    var tin := GetContext.getAssets.open(StringToJString(TEXTURE_PATHS[I]));
    var texNo : integer := TJUtOpenGL.JavaClass.loadTexture(gl, tin, True);
    live2DModel.setTexture(i, texNo);
  end;
end;

procedure SampleGLSurfaceViewStart;
var SampleGLSurfaceView : Androidapi.JNI.OpenGL.JGLSurfaceView;
begin
  TJLive2D.JavaClass.init;
  JGLRenderer := GLRenderer.Create;
  SampleGLSurfaceView :=  Androidapi.JNI.OpenGL.TJGLSurfaceView.JavaClass.init(SharedActivityContext);
  SampleGLSurfaceView.setRenderer(JGLRenderer);
  SharedActivity.setContentView(SampleGLSurfaceView);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  SampleGLSurfaceViewStart;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  PermissionState;
end;

 

SampleActivity.java

/**
 *
 *  You can modify and use this source freely
 *  only for the development of application related Live2D.
 *
 *  (c) Live2D Inc. All rights reserved.
 */
package jp.live2d.sample;

import jp.live2d.Live2D;
import android.app.Activity;
import android.os.Bundle;


public class SampleActivity extends Activity
{

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        Live2D.init();
        SampleGLSurfaceView 	view = new SampleGLSurfaceView(this) ;
        setContentView( view ) ;
    }

}

 

SampleGLSurfaceView.java

/**
 *
 *  You can modify and use this source freely
 *  only for the development of application related Live2D.
 *
 *  (c) Live2D Inc. All rights reserved.
 */
package jp.live2d.sample;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import jp.live2d.android.Live2DModelAndroid;
import jp.live2d.android.UtOpenGL;
import jp.live2d.util.UtSystem;
import android.content.Context;
import android.opengl.GLSurfaceView;

public class SampleGLSurfaceView extends GLSurfaceView
{
	private SampleGLRenderer		renderer ;

	public SampleGLSurfaceView(Context context )
	{
		super(context);

		renderer = new SampleGLRenderer() ;
		setRenderer( renderer ) ;
	}


	class SampleGLRenderer implements Renderer
	{
		private Live2DModelAndroid	live2DModel ;
		private final String MODEL_PATH = "haru/haru.moc" ;
		private final String TEXTURE_PATHS[] =
			{
				"haru/haru.1024/texture_00.png" ,
				"haru/haru.1024/texture_01.png" ,
				"haru/haru.1024/texture_02.png"
			} ;

		@Override
		public void onDrawFrame(GL10 gl)
		{
			gl.glMatrixMode(GL10.GL_MODELVIEW ) ;
			gl.glLoadIdentity() ;
			gl.glClear( GL10.GL_COLOR_BUFFER_BIT ) ;

			double t = (UtSystem.getUserTimeMSec()/1000.0) * 2 * Math.PI  ;// 1秒ごとに2π(1周期)増える
			double cycle=3.0;// パラメータが一周する時間(秒)
			double sin=Math.sin( t/cycle );// -1から1の間を周期ごとに変化する
			live2DModel.setParamFloat( "PARAM_ANGLE_X" , (float) (30 * sin) ) ;// PARAM_ANGLE_Xのパラメータが[cycle]秒ごとに-30から30まで変化する

			live2DModel.setGL( gl ) ;

			live2DModel.update() ;
			live2DModel.draw() ;
		}


		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height)
		{
			// ビューポートはデバイスの幅と合わせる。画面全体に表示される。
			gl.glViewport( 0 , 0 , width , height ) ;

			// 簡易的にプロジェクション行列一つですべての変換を行う。
			gl.glMatrixMode( GL10.GL_PROJECTION ) ;
			gl.glLoadIdentity() ;

			float modelWidth = live2DModel.getCanvasWidth();// モデラーで設定したキャンバス幅
			float aspect = (float)width/height;

			// 描画範囲の設定 引数はleft,right,bottom,topの順
			gl.glOrthof(0 ,	modelWidth , modelWidth / aspect , 0 , 0.5f , -0.5f ) ;
		}


		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config)
		{
			//  モデルの初期化
			try
			{
				InputStream in = getContext().getAssets().open( MODEL_PATH ) ;
				live2DModel = Live2DModelAndroid.loadModel( in ) ;
				in.close() ;

				for (int i = 0 ; i < TEXTURE_PATHS.length ; i++ )
				{
					InputStream tin = getContext().getAssets().open( TEXTURE_PATHS[i] ) ;
					int texNo = UtOpenGL.loadTexture(gl , tin , true ) ;
					live2DModel.setTexture( i , texNo ) ;
				}
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}
 
 

캐릭터 텍스처 원본 png 파일

 

728x90