From ce19309e0576e403d749eae22a137626b8782180 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 30 Dec 2025 15:17:18 +0100 Subject: [PATCH] refactor into files --- src/main/assets/quad.fs.glsl | 14 +++ src/main/assets/quad.vs.glsl | 12 ++ src/main/cpp/CMakeLists.txt | 8 ++ src/main/cpp/assets_manager.cpp | 21 ++++ src/main/cpp/assets_manager.h | 12 ++ src/main/cpp/external_texture.cpp | 42 +++++++ src/main/cpp/external_texture.h | 14 +++ src/main/cpp/mosis-test.cpp | 177 ++++-------------------------- src/main/cpp/quad.cpp | 50 +++++++++ src/main/cpp/quad.h | 12 ++ src/main/cpp/shader.cpp | 108 ++++++++++++++++++ src/main/cpp/shader.h | 16 +++ 12 files changed, 330 insertions(+), 156 deletions(-) create mode 100644 src/main/assets/quad.fs.glsl create mode 100644 src/main/assets/quad.vs.glsl create mode 100644 src/main/cpp/assets_manager.cpp create mode 100644 src/main/cpp/assets_manager.h create mode 100644 src/main/cpp/external_texture.cpp create mode 100644 src/main/cpp/external_texture.h create mode 100644 src/main/cpp/quad.cpp create mode 100644 src/main/cpp/quad.h create mode 100644 src/main/cpp/shader.cpp create mode 100644 src/main/cpp/shader.h diff --git a/src/main/assets/quad.fs.glsl b/src/main/assets/quad.fs.glsl new file mode 100644 index 0000000..a829dac --- /dev/null +++ b/src/main/assets/quad.fs.glsl @@ -0,0 +1,14 @@ +#version 300 es +#extension GL_OES_EGL_image_external_essl3 : require + +precision mediump float; + +uniform samplerExternalOES uTexture; + +in vec2 vTexCoord; +out vec4 fragColor; + +void main() +{ + fragColor = texture(uTexture, vTexCoord); +} diff --git a/src/main/assets/quad.vs.glsl b/src/main/assets/quad.vs.glsl new file mode 100644 index 0000000..48265b5 --- /dev/null +++ b/src/main/assets/quad.vs.glsl @@ -0,0 +1,12 @@ +#version 300 es + +layout(location = 0) in vec4 aPosition; +layout(location = 1) in vec2 aTexCoord; + +out vec2 vTexCoord; + +void main() +{ + gl_Position = aPosition; + vTexCoord = aTexCoord; +} diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt index 858e427..c00f457 100644 --- a/src/main/cpp/CMakeLists.txt +++ b/src/main/cpp/CMakeLists.txt @@ -11,6 +11,10 @@ add_library(mosis-service SHARED mosis-service.cpp com/omixlab/mosis/IMosisService.cpp com/omixlab/mosis/IMosisListener.cpp + assets_manager.cpp + shader.cpp + external_texture.cpp + quad.cpp egl_context.cpp logger.cpp glad/src/egl.c @@ -24,6 +28,10 @@ add_library(mosis-test SHARED com/omixlab/mosis/IMosisService.cpp com/omixlab/mosis/IMosisListener.cpp mosis-test.cpp + assets_manager.cpp + shader.cpp + external_texture.cpp + quad.cpp egl_context.cpp logger.cpp glad/src/egl.c diff --git a/src/main/cpp/assets_manager.cpp b/src/main/cpp/assets_manager.cpp new file mode 100644 index 0000000..5d2e0a7 --- /dev/null +++ b/src/main/cpp/assets_manager.cpp @@ -0,0 +1,21 @@ +#include "assets_manager.h" +#include + +void AssetsManager::Init(AAssetManager *asset_manager) +{ + m_asset_manager = asset_manager; +} + +std::vector AssetsManager::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 {}; +} diff --git a/src/main/cpp/assets_manager.h b/src/main/cpp/assets_manager.h new file mode 100644 index 0000000..5533c56 --- /dev/null +++ b/src/main/cpp/assets_manager.h @@ -0,0 +1,12 @@ +#pragma once +#include + +struct AAssetManager; + +class AssetsManager +{ + static inline AAssetManager* m_asset_manager = nullptr; +public: + static void Init(AAssetManager* asset_manager); + static std::vector ReadAll(const std::string& filename); +}; diff --git a/src/main/cpp/external_texture.cpp b/src/main/cpp/external_texture.cpp new file mode 100644 index 0000000..75e8daf --- /dev/null +++ b/src/main/cpp/external_texture.cpp @@ -0,0 +1,42 @@ +#include "external_texture.h" +#include +#include +#include "logger.h" + +bool ExternalTexture::create(AHardwareBuffer *hardwareBuffer) +{ + AHardwareBuffer_Desc desc{}; + AHardwareBuffer_describe(hardwareBuffer, &desc); + EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer); + EGLImageKHR eglImage = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, + EGL_NATIVE_BUFFER_ANDROID, clientBuffer, nullptr); + if (eglImage == EGL_NO_IMAGE_KHR) + { + Logger::Log("Failed to create EGL image"); + return false; + } + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage); + eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + return true; +} + +void ExternalTexture::destroy() +{ + if (texture) + glDeleteTextures(1, &texture); + texture = 0; +} + +void ExternalTexture::bind() const +{ + glBindTexture(GL_TEXTURE_2D, texture); +} + +void ExternalTexture::unbind() const +{ + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/src/main/cpp/external_texture.h b/src/main/cpp/external_texture.h new file mode 100644 index 0000000..1dd9583 --- /dev/null +++ b/src/main/cpp/external_texture.h @@ -0,0 +1,14 @@ +#pragma once +#include + +struct AHardwareBuffer; + +class ExternalTexture +{ + GLuint texture = 0; +public: + bool create(AHardwareBuffer* hardwareBuffer); + void destroy(); + void bind() const; + void unbind() const; +}; diff --git a/src/main/cpp/mosis-test.cpp b/src/main/cpp/mosis-test.cpp index 8296f9b..8795d5a 100644 --- a/src/main/cpp/mosis-test.cpp +++ b/src/main/cpp/mosis-test.cpp @@ -8,6 +8,10 @@ #include #include "logger.h" #include "egl_context.h" +#include "assets_manager.h" +#include "shader.h" +#include "external_texture.h" +#include "quad.h" #include #include #include @@ -17,163 +21,12 @@ 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 -{ - GLuint texture = 0; -public: - bool create(AHardwareBuffer* hardwareBuffer) - { - AHardwareBuffer_Desc desc{}; - AHardwareBuffer_describe(hardwareBuffer, &desc); - EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer); - EGLImageKHR eglImage = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, - EGL_NATIVE_BUFFER_ANDROID, clientBuffer, nullptr); - if (eglImage == EGL_NO_IMAGE_KHR) - { - Logger::Log("Failed to create EGL image"); - return false; - } - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); - eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - return true; - } -}; - class Renderer : public BnMosisListener { std::unique_ptr m_egl_context; - std::unique_ptr m_texture; + std::unique_ptr m_texture; + std::unique_ptr m_quad_shader; + std::unique_ptr m_quad; AHardwareBuffer* m_hwbuffer = nullptr; std::thread m_render_loop; bool m_active = false; @@ -182,12 +35,13 @@ class Renderer : public BnMosisListener m_egl_context = std::make_unique(); if (m_egl_context->create(window)) { + init_resources(); m_active = true; while (m_active) { if (m_hwbuffer && !m_texture) { - m_texture = std::make_unique(); + m_texture = std::make_unique(); if (!m_texture->create(m_hwbuffer)) { Logger::Log("Failed to create texture"); @@ -201,13 +55,24 @@ class Renderer : public BnMosisListener Logger::Log("Failed to create EGL context"); } } + void init_resources() + { + m_quad_shader = std::make_unique(); + m_quad_shader->load("quad.vs.glsl", "quad.fs.glsl"); + m_quad = std::make_unique(); + m_quad->create(); + } void render_frame() { glClearColor(0.f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); if (m_texture) { - + m_quad_shader->use(); + glUniform1i(m_quad_shader->getUniformLocation("uTexture"), 0); + glActiveTexture(GL_TEXTURE0); + m_texture->bind(); + m_quad->draw(); } m_egl_context->swap(); } diff --git a/src/main/cpp/quad.cpp b/src/main/cpp/quad.cpp new file mode 100644 index 0000000..250952c --- /dev/null +++ b/src/main/cpp/quad.cpp @@ -0,0 +1,50 @@ +#include "quad.h" + +void Quad::create() +{ + // 4 vertices for a triangle strip covering the screen + // Format: X, Y, Z, U, V + float vertices[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // Bottom-left + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // Bottom-right + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-left + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f // Top-right + }; + + glGenVertexArrays(1, &m_vao); + glGenBuffers(1, &m_vbo); + + glBindVertexArray(m_vao); + + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // Attribute 0: Position (3 floats) + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + + // Attribute 1: TexCoord (2 floats) + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void Quad::draw() const +{ + if (m_vao) + { + glBindVertexArray(m_vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + } +} + +void Quad::destroy() +{ + if (m_vao) + glDeleteVertexArrays(1, &m_vao); + if (m_vbo) + glDeleteBuffers(1, &m_vbo); +} diff --git a/src/main/cpp/quad.h b/src/main/cpp/quad.h new file mode 100644 index 0000000..6149cac --- /dev/null +++ b/src/main/cpp/quad.h @@ -0,0 +1,12 @@ +#pragma once +#include + +class Quad +{ + GLuint m_vao = 0; + GLuint m_vbo = 0; +public: + void create(); + void draw() const; + void destroy(); +}; diff --git a/src/main/cpp/shader.cpp b/src/main/cpp/shader.cpp new file mode 100644 index 0000000..e6ceea1 --- /dev/null +++ b/src/main/cpp/shader.cpp @@ -0,0 +1,108 @@ +#include "shader.h" +#include +#include +#include "assets_manager.h" +#include "logger.h" + +void Shader::destroy() +{ + if (m_program != 0) + { + glDeleteProgram(m_program); + } +} + +bool Shader::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 Shader::use() const +{ + if (m_program) glUseProgram(m_program); +} + +GLint Shader::getUniformLocation(const char *name) const +{ + return glGetUniformLocation(m_program, name); +} + +GLint Shader::getAttribLocation(const char *name) const +{ + return glGetAttribLocation(m_program, name); +} + +GLuint Shader::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; +} diff --git a/src/main/cpp/shader.h b/src/main/cpp/shader.h new file mode 100644 index 0000000..b60bb49 --- /dev/null +++ b/src/main/cpp/shader.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +class Shader +{ + GLuint m_program = 0; +public: + void destroy(); + bool load(const std::string& vertexFilename, const std::string& fragmentFilename); + void use() const; + GLint getUniformLocation(const char* name) const; + GLint getAttribLocation(const char* name) const; +private: + GLuint compile(GLenum type, const char* source); +};