Files
2025-09-10 18:45:17 +08:00

178 lines
6.6 KiB
Java

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);
}