Files
MosisVR/Packages/com.omarator.mosissdk/Plugins/Android/cpp/opengl_backend.cpp
2026-01-17 08:46:11 +01:00

179 lines
4.7 KiB
C++

#include "opengl_backend.h"
#include <logger.h>
bool OpenGLTextureBackend::InitializeGLAD()
{
gladLoaderLoadEGL(EGL_NO_DISPLAY);
int egl_version = gladLoadEGL(eglGetCurrentDisplay(), eglGetProcAddress);
if (egl_version == 0)
{
Logger::Log("OpenGLTextureBackend: Failed to load EGL");
return false;
}
int gl_version = gladLoaderLoadGLES2();
if (gl_version == 0)
{
Logger::Log("OpenGLTextureBackend: Failed to load GLES2");
return false;
}
Logger::Log("OpenGLTextureBackend: GLAD initialized successfully");
return true;
}
bool OpenGLTextureBackend::Create(AHardwareBuffer* buffer)
{
if (m_Created)
{
Destroy();
}
// Get buffer dimensions
AHardwareBuffer_Desc desc{};
AHardwareBuffer_describe(buffer, &desc);
m_Width = static_cast<GLint>(desc.width);
m_Height = static_cast<GLint>(desc.height);
// Create EGL image from hardware buffer
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
EGLImageKHR eglImage = eglCreateImageKHR(
eglGetCurrentDisplay(),
EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID,
clientBuffer,
nullptr
);
if (eglImage == EGL_NO_IMAGE_KHR)
{
Logger::Log("OpenGLTextureBackend: Failed to create EGL image");
return false;
}
// Create source texture (external OES format from hardware buffer)
glGenTextures(1, &m_SourceTexture);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_SourceTexture);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage);
// Create source framebuffer
glGenFramebuffers(1, &m_SourceFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_SourceFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_EXTERNAL_OES,
m_SourceTexture,
0
);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Logger::Log("OpenGLTextureBackend: Source framebuffer incomplete");
Destroy();
return false;
}
// Create destination texture (standard 2D texture for Unity)
glGenTextures(1, &m_DestTexture);
glBindTexture(GL_TEXTURE_2D, m_DestTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
m_Width,
m_Height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr
);
// Create destination framebuffer
glGenFramebuffers(1, &m_DestFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_DestFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
m_DestTexture,
0
);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Logger::Log("OpenGLTextureBackend: Dest framebuffer incomplete");
Destroy();
return false;
}
m_Created = true;
// Initial blit
Blit();
Logger::Log("OpenGLTextureBackend: Created successfully");
return true;
}
void OpenGLTextureBackend::Update()
{
if (m_Created)
{
Blit();
}
}
void OpenGLTextureBackend::Blit()
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_SourceFramebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_DestFramebuffer);
glBlitFramebuffer(
0, 0, m_Width, m_Height,
0, 0, m_Width, m_Height,
GL_COLOR_BUFFER_BIT,
GL_NEAREST
);
}
void OpenGLTextureBackend::Destroy()
{
if (m_DestFramebuffer)
{
glDeleteFramebuffers(1, &m_DestFramebuffer);
m_DestFramebuffer = 0;
}
if (m_SourceFramebuffer)
{
glDeleteFramebuffers(1, &m_SourceFramebuffer);
m_SourceFramebuffer = 0;
}
if (m_DestTexture)
{
glDeleteTextures(1, &m_DestTexture);
m_DestTexture = 0;
}
if (m_SourceTexture)
{
glDeleteTextures(1, &m_SourceTexture);
m_SourceTexture = 0;
}
m_Width = 0;
m_Height = 0;
m_Created = false;
}
void* OpenGLTextureBackend::GetNativeTexturePtr()
{
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_DestTexture));
}