diff --git a/src/main/cpp/mosis-test.cpp b/src/main/cpp/mosis-test.cpp index 9bfc45f..8296f9b 100644 --- a/src/main/cpp/mosis-test.cpp +++ b/src/main/cpp/mosis-test.cpp @@ -4,19 +4,144 @@ #include #include #include +#include +#include #include "logger.h" #include "egl_context.h" #include #include #include #include +#include using namespace aidl::com::omixlab::mosis; using namespace aidl::android::hardware; +class AssetsManager +{ + static inline AAssetManager* m_asset_manager = nullptr; +public: + static void Init(AAssetManager* asset_manager) + { + m_asset_manager = asset_manager; + } + static std::vector ReadAll(const std::string& filename) + { + if (AAsset* asset = AAssetManager_open(m_asset_manager, + filename.c_str(), AASSET_MODE_BUFFER)) + { + const auto size = AAsset_getLength(asset); + auto buffer = std::vector(size); + AAsset_read(asset, buffer.data(), size); + AAsset_close(asset); + return buffer; + } + return {}; + } +}; + class Shader { + GLuint m_program = 0; +public: + ~Shader() + { + if (m_program != 0) + { + glDeleteProgram(m_program); + } + } + bool load(const std::string& vertexFilename, const std::string& fragmentFilename) + { + // Read source from assets + std::vector vsSourceRaw = AssetsManager::ReadAll(vertexFilename); + std::vector fsSourceRaw = AssetsManager::ReadAll(fragmentFilename); + if (vsSourceRaw.empty() || fsSourceRaw.empty()) + { + Logger::Log("Failed to read shader files from assets"); + return false; + } + + // Null-terminate the source strings + std::string vsSource(vsSourceRaw.begin(), vsSourceRaw.end()); + std::string fsSource(fsSourceRaw.begin(), fsSourceRaw.end()); + + GLuint vertexShader = compile(GL_VERTEX_SHADER, vsSource.c_str()); + if (!vertexShader) return false; + + GLuint fragmentShader = compile(GL_FRAGMENT_SHADER, fsSource.c_str()); + if (!fragmentShader) + { + glDeleteShader(vertexShader); + return false; + } + + m_program = glCreateProgram(); + glAttachShader(m_program, vertexShader); + glAttachShader(m_program, fragmentShader); + glLinkProgram(m_program); + + // Check for link errors + GLint linked; + glGetProgramiv(m_program, GL_LINK_STATUS, &linked); + if (!linked) + { + GLint infoLen = 0; + glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + std::vector infoLog(infoLen); + glGetProgramInfoLog(m_program, infoLen, nullptr, infoLog.data()); + Logger::Log(std::format("Error linking program: {}", infoLog.data())); + } + glDeleteProgram(m_program); + m_program = 0; + } + + // Shaders can be deleted after linking + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + return (m_program != 0); + } + void use() const + { + if (m_program) glUseProgram(m_program); + } + GLint getUniformLocation(const char* name) const + { + return glGetUniformLocation(m_program, name); + } + GLint getAttribLocation(const char* name) const + { + return glGetAttribLocation(m_program, name); + } +private: + GLuint compile(GLenum type, const char* source) + { + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &source, nullptr); + glCompileShader(shader); + + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + std::vector infoLog(infoLen); + glGetShaderInfoLog(shader, infoLen, nullptr, infoLog.data()); + Logger::Log(std::format("Error compiling shader type {}: {}", + type, infoLog.data())); + } + glDeleteShader(shader); + return 0; + } + return shader; + } }; class ImportedTexture @@ -165,3 +290,11 @@ Java_com_omixlab_mosis_MainActivity_destroySurface(JNIEnv *env, jobject thiz) g_renderer->destroy(); } } + +extern "C" +JNIEXPORT void JNICALL +Java_com_omixlab_mosis_MainActivity_setAssetManager(JNIEnv *env, jobject thiz, + jobject asset_manager) +{ + AssetsManager::Init(AAssetManager_fromJava(env, asset_manager)); +} \ No newline at end of file diff --git a/src/main/java/com/omixlab/mosis/MainActivity.kt b/src/main/java/com/omixlab/mosis/MainActivity.kt index 4f7613e..43b9351 100644 --- a/src/main/java/com/omixlab/mosis/MainActivity.kt +++ b/src/main/java/com/omixlab/mosis/MainActivity.kt @@ -3,6 +3,7 @@ package com.omixlab.mosis import android.content.ComponentName import android.content.Intent import android.content.ServiceConnection +import android.content.res.AssetManager import android.os.Bundle import android.os.IBinder import android.util.Log @@ -78,6 +79,7 @@ class MainActivity : ComponentActivity() { } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setAssetManager(assets) startRemoteService() enableEdgeToEdge() setContent { @@ -108,6 +110,7 @@ class MainActivity : ComponentActivity() { } ) } + external fun setAssetManager(assetManager: AssetManager) external fun serviceConnected(binder: IBinder) external fun setSurface(surface: Surface) external fun destroySurface()