save code
This commit is contained in:
@@ -8,7 +8,7 @@ apply from: "./download_vvl.gradle"
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
ndkVersion '28.2.13676358'
|
ndkVersion '28.2.13676358'
|
||||||
compileSdk 35
|
compileSdk 36
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'com.khronos.vulkan_samples'
|
applicationId 'com.khronos.vulkan_samples'
|
||||||
|
|||||||
@@ -2,47 +2,61 @@ package com.khronos.vulkan_samples;
|
|||||||
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.TextureView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.camera.core.Camera;
|
|
||||||
import androidx.camera.core.CameraSelector;
|
import androidx.camera.core.CameraSelector;
|
||||||
import androidx.camera.core.Preview;
|
import androidx.camera.core.Preview;
|
||||||
|
import androidx.camera.core.SurfaceRequest;
|
||||||
import androidx.camera.lifecycle.ProcessCameraProvider;
|
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||||
import androidx.camera.view.PreviewView;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.google.androidgamesdk.GameActivity;
|
import com.google.androidgamesdk.GameActivity;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.mediapipe.examples.facelandmarker.FaceLandmarkerHelper;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
public class MainActivity extends GameActivity {
|
public class MainActivity extends GameActivity {
|
||||||
private PreviewView previewView;
|
private TextureView textureView; // 使用 TextureView 替代 PreviewView
|
||||||
private ProcessCameraProvider cameraProvider;
|
private ProcessCameraProvider cameraProvider;
|
||||||
|
private FrameLayout containerLayout;
|
||||||
private void initCamera(){
|
private void initCamera(){
|
||||||
// 创建摄像头预览视图
|
// 获取 GameActivity 的根视图
|
||||||
previewView = new PreviewView(this);
|
ViewGroup rootView = (ViewGroup) getWindow().getDecorView();
|
||||||
previewView.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE);
|
|
||||||
previewView.setScaleType(PreviewView.ScaleType.FILL_CENTER);
|
|
||||||
|
|
||||||
addContentView(previewView, new ViewGroup.LayoutParams(
|
// 创建容器布局
|
||||||
|
containerLayout = new FrameLayout(this);
|
||||||
|
containerLayout.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
));
|
));
|
||||||
|
|
||||||
bringVulkanToFront();
|
// 创建 TextureView 用于摄像头预览
|
||||||
|
textureView = new TextureView(this);
|
||||||
|
textureView.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
));
|
||||||
|
|
||||||
|
// 将 TextureView 添加到容器
|
||||||
|
containerLayout.addView(textureView);
|
||||||
|
|
||||||
|
// 将容器添加到根视图的底部(作为背景)
|
||||||
|
//rootView.addView(containerLayout); // 添加到索引0(最底层)
|
||||||
|
rootView.addView(containerLayout, 0);
|
||||||
|
|
||||||
|
|
||||||
if (hasCameraPermission()) {
|
if (hasCameraPermission()) {
|
||||||
startCamera();
|
startCamera();
|
||||||
@@ -51,23 +65,6 @@ public class MainActivity extends GameActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bringVulkanToFront() {
|
|
||||||
// 获取窗口的根视图
|
|
||||||
View rootView = getWindow().getDecorView();
|
|
||||||
if (rootView instanceof ViewGroup) {
|
|
||||||
ViewGroup rootGroup = (ViewGroup) rootView;
|
|
||||||
|
|
||||||
for (int i = rootGroup.getChildCount() - 1; i >= 0; i--) {
|
|
||||||
View child = rootGroup.getChildAt(i);
|
|
||||||
if (child != previewView) {
|
|
||||||
child.bringToFront();
|
|
||||||
child.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -115,7 +112,18 @@ public class MainActivity extends GameActivity {
|
|||||||
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
preview.setSurfaceProvider(previewView.getSurfaceProvider());
|
// 使用 TextureView 的 SurfaceTexture
|
||||||
|
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
|
||||||
|
if (surfaceTexture != null) {
|
||||||
|
Surface surface = new Surface(surfaceTexture);
|
||||||
|
preview.setSurfaceProvider(new Preview.SurfaceProvider() {
|
||||||
|
@Override
|
||||||
|
public void onSurfaceRequested(@NonNull SurfaceRequest request) {
|
||||||
|
request.provideSurface(surface, ContextCompat.getMainExecutor(MainActivity.this),
|
||||||
|
result -> {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cameraProvider.bindToLifecycle(this, cameraSelector, preview);
|
cameraProvider.bindToLifecycle(this, cameraSelector, preview);
|
||||||
|
|
||||||
@@ -125,6 +133,7 @@ public class MainActivity extends GameActivity {
|
|||||||
}, ContextCompat.getMainExecutor(this));
|
}, ContextCompat.getMainExecutor(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final int REQUEST_CODE_PERMISSIONS = 1001;
|
private static final int REQUEST_CODE_PERMISSIONS = 1001;
|
||||||
private static final String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.CAMERA};
|
private static final String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.CAMERA};
|
||||||
private static final String TAG = "MainActivity";
|
private static final String TAG = "MainActivity";
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
package com.khronos.vulkan_samples;
|
||||||
|
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.TextureView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.camera.core.CameraSelector;
|
||||||
|
import androidx.camera.core.Preview;
|
||||||
|
import androidx.camera.core.SurfaceRequest;
|
||||||
|
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.google.androidgamesdk.GameActivity;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public class VulkanTopActivity extends GameActivity {
|
||||||
|
private TextureView textureView; // 使用 TextureView 替代 PreviewView
|
||||||
|
private ProcessCameraProvider cameraProvider;
|
||||||
|
private void initCamera(){
|
||||||
|
// 创建 TextureView
|
||||||
|
textureView = new TextureView(this);
|
||||||
|
textureView.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
));
|
||||||
|
|
||||||
|
// 获取根视图并添加 TextureView 作为背景
|
||||||
|
ViewGroup rootView = (ViewGroup) getWindow().getDecorView();
|
||||||
|
rootView.addView(textureView, 0); // 添加到最底层
|
||||||
|
|
||||||
|
// 配置 Vulkan 视图透明度
|
||||||
|
setupVulkanView();
|
||||||
|
|
||||||
|
if (hasCameraPermission()) {
|
||||||
|
startCamera();
|
||||||
|
} else {
|
||||||
|
requestCameraPermission();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupVulkanView() {
|
||||||
|
ViewGroup rootView = (ViewGroup) getWindow().getDecorView();
|
||||||
|
|
||||||
|
for (int i = 0; i < rootView.getChildCount(); i++) {
|
||||||
|
View child = rootView.getChildAt(i);
|
||||||
|
if (child instanceof SurfaceView && child != textureView) {
|
||||||
|
SurfaceView vulkanView = (SurfaceView) child;
|
||||||
|
|
||||||
|
// 关键设置:确保 Vulkan 视图在顶层且透明
|
||||||
|
vulkanView.setZOrderOnTop(true);
|
||||||
|
vulkanView.getHolder().setFormat(PixelFormat.TRANSPARENT);
|
||||||
|
vulkanView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
|
||||||
|
// 确保它在最前面
|
||||||
|
vulkanView.bringToFront();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
String native_lib_name = getResources().getString(R.string.native_lib_name);
|
||||||
|
try {
|
||||||
|
System.loadLibrary(native_lib_name);
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
Toast.makeText(getApplicationContext(), "Native code library failed to load.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
String[] argArray = new String[2];
|
||||||
|
argArray[0] = "sample";
|
||||||
|
argArray[1] = "hello_triangle";
|
||||||
|
// sendArgumentsToPlatform(argArray);
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
initCamera();
|
||||||
|
|
||||||
|
Log.i("MainActivity", "onCreate: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasCameraPermission() {
|
||||||
|
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
|
||||||
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestCameraPermission() {
|
||||||
|
ActivityCompat.requestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.CAMERA},
|
||||||
|
REQUEST_CAMERA_PERMISSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int REQUEST_CAMERA_PERMISSION = 1001;
|
||||||
|
|
||||||
|
private void startCamera() {
|
||||||
|
ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
|
||||||
|
ProcessCameraProvider.getInstance(this);
|
||||||
|
|
||||||
|
cameraProviderFuture.addListener(() -> {
|
||||||
|
try {
|
||||||
|
cameraProvider = cameraProviderFuture.get();
|
||||||
|
Preview preview = new Preview.Builder().build();
|
||||||
|
CameraSelector cameraSelector = new CameraSelector.Builder()
|
||||||
|
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
||||||
|
Surface surface = new Surface(surfaceTexture);
|
||||||
|
preview.setSurfaceProvider(request -> {
|
||||||
|
request.provideSurface(surface, ContextCompat.getMainExecutor(VulkanTopActivity.this),
|
||||||
|
result -> {});
|
||||||
|
});
|
||||||
|
|
||||||
|
cameraProvider.bindToLifecycle(VulkanTopActivity.this, cameraSelector, preview);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int width, int height) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
Log.e("MainActivity", "Error starting camera: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}, ContextCompat.getMainExecutor(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final int REQUEST_CODE_PERMISSIONS = 1001;
|
||||||
|
private static final String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.CAMERA};
|
||||||
|
private static final String TAG = "MainActivity";
|
||||||
|
|
||||||
|
private boolean allPermissionsGranted() {
|
||||||
|
for (String permission : REQUIRED_PERMISSIONS) {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == REQUEST_CODE_PERMISSIONS) {
|
||||||
|
if (allPermissionsGranted()) {
|
||||||
|
startCamera();
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Permissions not granted by the user.");
|
||||||
|
finish(); // Close the activity if permission is denied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private native void sendArgumentsToPlatform(String[] args);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user