diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a80b06a..4aa4456a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -393,7 +393,7 @@ else() endif() if(ANDROID) - target_link_libraries(Alber PRIVATE log) + target_link_libraries(Alber PRIVATE EGL log) endif() if(ENABLE_LTO OR ENABLE_USER_BUILD) diff --git a/src/jni_driver.cpp b/src/jni_driver.cpp index c2a00d7b..11d19963 100644 --- a/src/jni_driver.cpp +++ b/src/jni_driver.cpp @@ -1,11 +1,36 @@ #include +#include #include +#include +#include "renderer_gl/renderer_gl.hpp" #include "emulator.hpp" -std::unique_ptr emulator; +std::unique_ptr emulator = nullptr; +RendererGL* renderer = nullptr; extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_Initialize(JNIEnv* env, jobject obj) { - __android_log_print(ANDROID_LOG_INFO, "Panda3DS", "Initializing Alber Driver"); emulator = std::make_unique(); - __android_log_print(ANDROID_LOG_INFO, "Panda3DS", "Done"); + if (emulator->getRendererType() != RendererType::OpenGL) { + throw std::runtime_error("Renderer is not OpenGL"); + } + renderer = static_cast(emulator->getRenderer()); + __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "OpenGL ES Before %d.%d", GLVersion.major, GLVersion.minor); + if (!gladLoadGLES2Loader(reinterpret_cast(eglGetProcAddress))) { + throw std::runtime_error("OpenGL ES init failed"); + } + __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "OpenGL ES %d.%d", GLVersion.major, GLVersion.minor); + emulator->initGraphicsContext(nullptr); + // girlboss it for now :3 + emulator->loadROM("/data/data/com.panda3ds.pandroid/files/rom.3ds"); +} + +extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_RunFrame(JNIEnv* env, jobject obj, jint fbo) { + renderer->setFBO(fbo); + renderer->resetStateManager(); + emulator->runFrame(); +} + +extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_Finalize(JNIEnv* env, jobject obj) { + emulator = nullptr; + renderer = nullptr; } \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java index 55bcd47e..da3b2020 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java @@ -2,7 +2,13 @@ package com.panda3ds.pandroid; public class AlberDriver { + AlberDriver() { + super(); + } + public static native void Initialize(); + public static native void RunFrame(int fbo); + public static native void Finalize(); static { System.loadLibrary("Alber"); diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java index e2ab412b..8cb6b6d1 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java @@ -2,15 +2,20 @@ package com.panda3ds.pandroid; import androidx.appcompat.app.AppCompatActivity; +import android.os.Build; import android.os.Bundle; +import android.view.WindowInsets; +import android.view.View; public class MainActivity extends AppCompatActivity { + PandaGlSurfaceView glView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - AlberDriver.Initialize(); + glView = new PandaGlSurfaceView(this); + setContentView(glView); } } \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java new file mode 100644 index 00000000..cc6499e6 --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java @@ -0,0 +1,79 @@ +package com.panda3ds.pandroid; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import static android.opengl.GLES32.*; + +import android.content.res.Resources; +import android.opengl.GLSurfaceView; +import android.util.DisplayMetrics; +import android.util.Log; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +public class PandaGlRenderer implements GLSurfaceView.Renderer { + int screenWidth, screenHeight; + int screenTexture; + public int screenFbo; + + PandaGlRenderer() { + super(); + } + + @Override + protected void finalize() throws Throwable { + if (screenTexture != 0) { + glDeleteTextures(1, new int[]{screenTexture}, 0); + } + if (screenFbo != 0) { + glDeleteFramebuffers(1, new int[]{screenFbo}, 0); + } + super.finalize(); + } + + public void onSurfaceCreated(GL10 unused, EGLConfig config) { + Log.i("pandroid", glGetString(GL_EXTENSIONS)); + Log.w("pandroid", glGetString(GL_VERSION)); + screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels; + screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels; + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + int[] generateBuffer = new int[1]; + glGenTextures(1, generateBuffer, 0); + screenTexture = generateBuffer[0]; + glBindTexture(GL_TEXTURE_2D, screenTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, screenWidth, screenHeight); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenFramebuffers(1, generateBuffer, 0); + screenFbo = generateBuffer[0]; + glBindFramebuffer(GL_FRAMEBUFFER, screenFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + AlberDriver.Initialize(); + } + + public void onDrawFrame(GL10 unused) { + AlberDriver.RunFrame(screenFbo); + // is this needed? prob not + glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, screenFbo); + glBlitFramebuffer(0, 0, 400, 480, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + } + + public void onSurfaceChanged(GL10 unused, int width, int height) { + glViewport(0, 0, width, height); + screenWidth = width; + screenHeight = height; + glDisable(GL_SCISSOR_TEST); + } +} diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlSurfaceView.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlSurfaceView.java new file mode 100644 index 00000000..657b327c --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlSurfaceView.java @@ -0,0 +1,19 @@ +package com.panda3ds.pandroid; + +import android.app.Activity; +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.DisplayMetrics; + +import com.panda3ds.pandroid.PandaGlRenderer; + +public class PandaGlSurfaceView extends GLSurfaceView { + final PandaGlRenderer renderer; + + public PandaGlSurfaceView(Context context) { + super(context); + setEGLContextClientVersion(3); + renderer = new PandaGlRenderer(); + setRenderer(renderer); + } +} \ No newline at end of file