[Feat] (...): Add GLES Backend.

This commit is contained in:
BZLZHH
2025-04-26 12:03:42 +08:00
parent adbadbba30
commit 91fa9e2d01
453 changed files with 70432 additions and 58 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
#ifdef __ANDROID__
#define __ANDROID_API__ 26
#endif
#define MG_EXPORT __attribute__((visibility("default")))
#define MG_EXPORT extern "C" __attribute__((visibility("default")))
#include <array>
#include <unordered_set>
+15 -3
View File
@@ -3,8 +3,11 @@
//
#include "Constants.h"
#define BACKEND_TYPE BACKEND_VULKAN
#define BACKEND_TYPE BACKEND_GLES
#include "Global.h"
#ifndef MOBILEGL_GLES_LOADER_H
#include "MG_GL/BackendLoader/GLES/Loader.h"
#endif
#ifndef MOBILEGL_GL_FRAMEBUFFER_H
#include "MG_GL/GL/Framebuffer/GL_Framebuffer.h"
#endif
@@ -17,8 +20,8 @@
#ifndef MOBILEGL_GL_BUFFER_H
#include "MG_GL/GL/Buffer/GL_Buffer.h"
#endif
#ifndef MOBILEGL_GL_COMMAND_H
#include "MG_GL/GL/Command/GL_Command.h"
#ifndef MOBILEGL_GL_DRAWING_H
#include "MG_GL/GL/Drawing/GL_Drawing.h"
#endif
#ifndef MOBILEGL_GL_PROGRAM_H
#include "MG_GL/GL/Program/GL_Program.h"
@@ -50,6 +53,12 @@
#ifndef MOBILEGL_EGL_VK_EMU_H
#include "MG_GL/EGL/VK/EGL_EMU.h"
#endif
#ifndef MOBILEGL_EGL_GLES_EGL_WRAP_H
#include "MG_GL/EGL/GLES/EGL_WRAP.h"
#endif
#ifndef MOBILEGL_TESTDRAWING_H
#include "MG_RHI/GLES/Test/TestDrawing.h"
#endif
#include <cstring>
#include <iostream>
@@ -77,6 +86,9 @@
#include <glslang/Public/ShaderLang.h>
#include <spirv_cross/spirv_cross_c.h>
#include <glslang/SPIRV/GlslangToSpv.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/glm.hpp>
#include "GLES/gl32.h"
#ifdef __ANDROID__
#include <android/log.h>
+1
View File
@@ -8,6 +8,7 @@ __attribute__((constructor)) void MG_Initialize() {
MG_Util::Debug::LogInit();
MG_Util::Debug::LogI("MobileGL Initializing...");
MG_State::Init();
MG_GL::BackendLoader::Init();
}
__attribute__((destructor)) void MG_Destroy() {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+179
View File
@@ -0,0 +1,179 @@
//
// Created by BZLZHH on 2025/4/26.
//
#include "EGL_WRAP.h"
#if BACKEND_TYPE == BACKEND_GLES
MG_EXPORT EGLint eglGetError(void) {
LOAD_EGL(eglGetError)
return egl_eglGetError();
}
MG_EXPORT EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
LOAD_EGL(eglGetDisplay)
return egl_eglGetDisplay(display_id);
}
MG_EXPORT EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
LOAD_EGL(eglInitialize)
return egl_eglInitialize(dpy, major, minor);
}
MG_EXPORT EGLBoolean eglTerminate(EGLDisplay dpy) {
LOAD_EGL(eglTerminate)
return egl_eglTerminate(dpy);
}
MG_EXPORT const char *eglQueryString(EGLDisplay dpy, EGLint name) {
LOAD_EGL(eglQueryString)
return egl_eglQueryString(dpy, name);
}
MG_EXPORT EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) {
LOAD_EGL(eglGetConfigs)
return egl_eglGetConfigs(dpy, configs, config_size, num_config);
}
MG_EXPORT EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) {
LOAD_EGL(eglChooseConfig)
return egl_eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
}
MG_EXPORT EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) {
LOAD_EGL(eglGetConfigAttrib)
return egl_eglGetConfigAttrib(dpy, config, attribute, value);
}
MG_EXPORT EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) {
LOAD_EGL(eglCreateWindowSurface)
return egl_eglCreateWindowSurface(dpy, config, win, attrib_list);
}
MG_EXPORT EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) {
LOAD_EGL(eglCreatePbufferSurface)
return egl_eglCreatePbufferSurface(dpy, config, attrib_list);
}
MG_EXPORT EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) {
LOAD_EGL(eglCreatePixmapSurface)
return egl_eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
}
MG_EXPORT EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
LOAD_EGL(eglDestroySurface)
return egl_eglDestroySurface(dpy, surface);
}
MG_EXPORT EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) {
LOAD_EGL(eglQuerySurface)
return egl_eglQuerySurface(dpy, surface, attribute, value);
}
MG_EXPORT EGLBoolean eglBindAPI(EGLenum api) {
LOAD_EGL(eglBindAPI)
return egl_eglBindAPI(api);
}
MG_EXPORT EGLenum eglQueryAPI(void) {
LOAD_EGL(eglQueryAPI)
return egl_eglQueryAPI();
}
MG_EXPORT EGLBoolean eglWaitClient(void) {
LOAD_EGL(eglWaitClient)
return egl_eglWaitClient();
}
MG_EXPORT EGLBoolean eglReleaseThread(void) {
LOAD_EGL(eglReleaseThread)
return egl_eglReleaseThread();
}
MG_EXPORT EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) {
LOAD_EGL(eglCreatePbufferFromClientBuffer)
return egl_eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
}
MG_EXPORT EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
LOAD_EGL(eglSurfaceAttrib)
return egl_eglSurfaceAttrib(dpy, surface, attribute, value);
}
MG_EXPORT EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
LOAD_EGL(eglBindTexImage)
return egl_eglBindTexImage(dpy, surface, buffer);
}
MG_EXPORT EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
LOAD_EGL(eglReleaseTexImage)
return egl_eglReleaseTexImage(dpy, surface, buffer);
}
MG_EXPORT EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
LOAD_EGL(eglSwapInterval)
return egl_eglSwapInterval(dpy, interval);
}
MG_EXPORT EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) {
LOAD_EGL(eglCreateContext)
return egl_eglCreateContext(dpy, config, share_context, attrib_list);
}
MG_EXPORT EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
LOAD_EGL(eglDestroyContext)
return egl_eglDestroyContext(dpy, ctx);
}
MG_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
LOAD_EGL(eglMakeCurrent)
return egl_eglMakeCurrent(dpy, draw, read, ctx);
}
MG_EXPORT EGLContext eglGetCurrentContext(void) {
LOAD_EGL(eglGetCurrentContext)
return egl_eglGetCurrentContext();
}
MG_EXPORT EGLSurface eglGetCurrentSurface(EGLint readdraw) {
LOAD_EGL(eglGetCurrentSurface)
return egl_eglGetCurrentSurface(readdraw);
}
MG_EXPORT EGLDisplay eglGetCurrentDisplay(void) {
LOAD_EGL(eglGetCurrentDisplay)
return egl_eglGetCurrentDisplay();
}
MG_EXPORT EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) {
LOAD_EGL(eglQueryContext)
return egl_eglQueryContext(dpy, ctx, attribute, value);
}
MG_EXPORT EGLBoolean eglWaitGL(void) {
LOAD_EGL(eglWaitGL)
return egl_eglWaitGL();
}
MG_EXPORT EGLBoolean eglWaitNative(EGLint engine) {
LOAD_EGL(eglWaitNative)
return egl_eglWaitNative(engine);
}
MG_EXPORT EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
LOAD_EGL(eglSwapBuffers)
return egl_eglSwapBuffers(dpy, surface);
}
MG_EXPORT EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) {
LOAD_EGL(eglCopyBuffers)
return egl_eglCopyBuffers(dpy, surface, target);
}
MG_EXPORT EGLDisplay eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) {
LOAD_EGL(eglGetPlatformDisplay)
return egl_eglGetPlatformDisplay(platform, native_display, (const EGLint *)attrib_list);
}
#endif
+14
View File
@@ -0,0 +1,14 @@
//
// Created by BZLZHH on 2025/4/26.
//
#ifndef MOBILEGL_EGL_GLES_EGL_WRAP_H
#define MOBILEGL_EGL_GLES_EGL_WRAP_H
#include "../../../Includes.h"
#if BACKEND_TYPE == BACKEND_GLES
#endif
#endif //MOBILEGL_EGL_GLES_EGL_WRAP_H
+19 -19
View File
@@ -78,25 +78,25 @@ extern thread_local EGLContext tls_currentContext;
extern thread_local EGLSurface tls_drawSurface;
extern thread_local EGLSurface tls_readSurface;
extern "C" MG_EXPORT EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list);
extern "C" MG_EXPORT EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
extern "C" MG_EXPORT EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list);
extern "C" MG_EXPORT EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor);
extern "C" MG_EXPORT EGLDisplay eglGetDisplay(NativeDisplayType display);
extern "C" MG_EXPORT EGLint eglGetError();
extern "C" MG_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
extern "C" MG_EXPORT EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
extern "C" MG_EXPORT EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
extern "C" MG_EXPORT EGLBoolean eglTerminate(EGLDisplay dpy);
extern "C" MG_EXPORT EGLBoolean eglReleaseThread(void);
extern "C" MG_EXPORT EGLContext eglGetCurrentContext(void);
extern "C" MG_EXPORT EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
extern "C" MG_EXPORT EGLBoolean eglBindAPI(EGLenum api);
extern "C" MG_EXPORT EGLSurface eglGetCurrentSurface(EGLint readdraw);
extern "C" MG_EXPORT EGLBoolean eglQuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint *value);
extern "C" MG_EXPORT EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
extern "C" MG_EXPORT EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
extern "C" MG_EXPORT EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
MG_EXPORT EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list);
MG_EXPORT EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
MG_EXPORT EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list);
MG_EXPORT EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor);
MG_EXPORT EGLDisplay eglGetDisplay(NativeDisplayType display);
MG_EXPORT EGLint eglGetError();
MG_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
MG_EXPORT EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
MG_EXPORT EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
MG_EXPORT EGLBoolean eglTerminate(EGLDisplay dpy);
MG_EXPORT EGLBoolean eglReleaseThread(void);
MG_EXPORT EGLContext eglGetCurrentContext(void);
MG_EXPORT EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
MG_EXPORT EGLBoolean eglBindAPI(EGLenum api);
MG_EXPORT EGLSurface eglGetCurrentSurface(EGLint readdraw);
MG_EXPORT EGLBoolean eglQuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint *value);
MG_EXPORT EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
MG_EXPORT EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
MG_EXPORT EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
#endif
-9
View File
@@ -1,9 +0,0 @@
//
// Created by BZLZHH on 2025/3/15.
//
#include "GL_Command.h"
namespace MG_GL::GL {
}
-14
View File
@@ -1,14 +0,0 @@
//
// Created by BZLZHH on 2025/3/15.
//
#ifndef MOBILEGL_GL_COMMAND_H
#define MOBILEGL_GL_COMMAND_H
#include "../../../Includes.h"
namespace MG_GL::GL {
}
#endif //MOBILEGL_GL_COMMAND_H
+17
View File
@@ -0,0 +1,17 @@
//
// Created by BZLZHH on 2025/3/15.
//
#include "GL_Drawing.h"
namespace MG_GL::GL {
// This is a test function that directly draws textures.
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) {
::GLES::glViewport(0,0,3200,1440);
MG_RHI::GLES::Test::DrawAllTextures();
};
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
::GLES::glViewport(0,0,3200,1440);
MG_RHI::GLES::Test::DrawAllTextures();
};
}
+15
View File
@@ -0,0 +1,15 @@
//
// Created by BZLZHH on 2025/3/15.
//
#ifndef MOBILEGL_GL_DRAWING_H
#define MOBILEGL_GL_DRAWING_H
#include "../../../Includes.h"
namespace MG_GL::GL {
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void DrawArrays(GLenum mode, GLint first, GLsizei count);
}
#endif //MOBILEGL_GL_DRAWING_H
+4 -1
View File
@@ -5,5 +5,8 @@
#include "GL_Program.h"
namespace MG_GL::GL {
void GetProgramiv(GLuint program, GLenum pname, GLint *params) {
// TODO: Check if program linking is successful.
*params = GL_TRUE;
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
#include "../../../Includes.h"
namespace MG_GL::GL {
void GetProgramiv(GLuint program, GLenum pname, GLint *params);
}
#endif //MOBILEGL_GL_PROGRAM_H
+4 -1
View File
@@ -5,5 +5,8 @@
#include "GL_Shader.h"
namespace MG_GL::GL {
void GetShaderiv(GLuint shader, GLenum pname, GLint *params) {
// TODO: Check if shader compilation is successful.
*params = GL_TRUE;
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
#include "../../../Includes.h"
namespace MG_GL::GL {
void GetShaderiv(GLuint shader, GLenum pname, GLint *params);
}
#endif //MOBILEGL_GL_SHADER_H
+6 -6
View File
@@ -5,7 +5,7 @@
#include "GL_Def.h"
#define DECLARE_GL_FUNCTION_STUB_HEAD(type,name,...) \
extern "C" MG_EXPORT type gl##name(__VA_ARGS__) {
MG_EXPORT type gl##name(__VA_ARGS__) {
#define DECLARE_GL_FUNCTION_STUB_END(type,name,...) \
MG_Util::Debug::LogW("Stub function: %s(...)", __FUNCTION__); \
@@ -17,7 +17,7 @@ extern "C" MG_EXPORT type gl##name(__VA_ARGS__) {
}
#define DECLARE_GL_FUNCTION_HEAD(type,name,...) \
extern "C" MG_EXPORT type gl##name(__VA_ARGS__) {
MG_EXPORT type gl##name(__VA_ARGS__) {
#define DECLARE_GL_FUNCTION_END(type,name,...) \
MG_Util::Debug::LogD("Implementing function: %s(...)", __FUNCTION__); \
@@ -73,8 +73,8 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, DepthRangef, GLfloat n, GLfloat f) DECLARE_G
DECLARE_GL_FUNCTION_STUB_HEAD(void, DetachShader, GLuint program, GLuint shader) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DetachShader, program,shader)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Disable, GLenum cap) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Disable, cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DisableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DisableVertexAttribArray, index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawArrays, GLenum mode, GLint first, GLsizei count) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawArrays, mode,first,count)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const void *indices) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawElements, mode,count,type,indices)
DECLARE_GL_FUNCTION_HEAD(void, DrawArrays, GLenum mode, GLint first, GLsizei count) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawArrays, mode,first,count)
DECLARE_GL_FUNCTION_HEAD(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const void *indices) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawElements, mode,count,type,indices)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Enable, GLenum cap) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Enable, cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EnableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EnableVertexAttribArray, index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Finish) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Finish)
@@ -97,10 +97,10 @@ DECLARE_GL_FUNCTION_HEAD(GLenum, GetError) DECLARE_GL_FUNCTION_END(GLenum, GetEr
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetFloatv, GLenum pname, GLfloat *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetFloatv, pname,data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetFramebufferAttachmentParameteriv, target,attachment,pname,params)
DECLARE_GL_FUNCTION_HEAD(void, GetIntegerv, GLenum pname, GLint *data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetIntegerv, pname,data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramiv, program,pname,params)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramiv, program,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramInfoLog, program,bufSize,length,infoLog)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetRenderbufferParameteriv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetRenderbufferParameteriv, target,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetShaderiv, shader,pname,params)
DECLARE_GL_FUNCTION_HEAD(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetShaderiv, shader,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetShaderInfoLog, shader,bufSize,length,infoLog)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetShaderPrecisionFormat, shadertype,precisiontype,range,precision)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetShaderSource, shader,bufSize,length,source)
+2
View File
@@ -109,6 +109,8 @@ GLenum TextureState::CreateN(GLsizei n, GLuint* textures) {
obj.generated = true;
this->textures[id] = obj;
textures[i] = id;
static uint64_t counter = 0;
obj.createTimestamp = ++counter;
}
return GL_NO_ERROR;
}
+2 -1
View File
@@ -40,6 +40,7 @@ public:
TextureParams params;
const void* data = nullptr;
bool IsImmutable() const;
uint64_t createTimestamp;
};
class TextureUnitState {
@@ -60,7 +61,6 @@ private:
GLuint lastUsedID = 0;
std::set<GLuint> freeIDs;
std::unordered_map<GLuint, TextureObject> textures;
std::unordered_map<GLenum, TextureObject> proxyTextures;
public:
TextureState();
@@ -68,6 +68,7 @@ public:
static TextureState& GetInstance();
bool IsTextureGenerated(GLuint texture);
bool IsTexture(GLuint texture);
std::unordered_map<GLuint, TextureObject> textures;
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum BindUnit(GLenum textureUnit);
+187
View File
@@ -0,0 +1,187 @@
//
// Created by BZLZHH on 2025/4/26.
//
#include "TestDrawing.h"
namespace MG_RHI::GLES::Test {
bool IsTextureComplete(const TextureObject& tex) {
if (tex.params.mipmapData.empty()) return false;
return true;
}
void DrawAllTextures() {
struct ScreenResources {
GLuint program = 0;
GLuint quadVAO = 0;
GLuint quadVBO = 0;
std::unordered_map<GLuint, GLuint> textureCache; // [state_texID] => GL_texID
};
static ScreenResources sRes;
static glm::ivec2 lastScreenSize{0, 0};
GLint viewport[4];
::GLES::glGetIntegerv(GL_VIEWPORT, viewport);
glm::ivec2 screenSize(viewport[2], viewport[3]);
if (screenSize != lastScreenSize) {
if (sRes.quadVAO) {
::GLES::glDeleteVertexArrays(1, &sRes.quadVAO);
::GLES::glDeleteBuffers(1, &sRes.quadVBO);
sRes.quadVAO = sRes.quadVBO = 0;
}
lastScreenSize = screenSize;
}
if (!sRes.program) {
const char* vsSrc = R"(#version 320 es
layout(location=0) in vec2 aPos;
layout(location=1) in vec2 aTexUV;
out vec2 vUV;
uniform mat4 uMVP;
void main() {
::GLES::gl_Position = uMVP * vec4(aPos, 0.0, 1.0);
vUV = aTexUV;
})";
const char* fsSrc = R"(#version 320 es
precision mediump float;
in vec2 vUV;
uniform sampler2D uTex;
out vec4 FragColor;
void main() {
FragColor = texture(uTex, vUV);
})";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
::GLES::glShaderSource(vs, 1, &vsSrc, NULL);
::GLES::glShaderSource(fs, 1, &fsSrc, NULL);
::GLES::glCompileShader(vs);
::GLES::glCompileShader(fs);
sRes.program = glCreateProgram();
::GLES::glAttachShader(sRes.program, vs);
::GLES::glAttachShader(sRes.program, fs);
::GLES::glLinkProgram(sRes.program);
::GLES::glDeleteShader(vs);
::GLES::glDeleteShader(fs);
}
if (!sRes.quadVAO) {
const float margin = 0.02f;
const float gridSize = (1.0f - 2*margin) / 6.0f;
std::vector<float> vertices;
for (int col = 0; col < 6; ++col) {
for (int row = 0; row < 5; ++row) {
float xStart = -1.0f + margin + col * gridSize;
float yStart = -1.0f + margin + row * gridSize;
float xEnd = xStart + gridSize - margin;
float yEnd = yStart + gridSize - margin;
vertices.insert(vertices.end(), {
xStart, yStart, 0.0f, 0.0f,
xEnd, yStart, 1.0f, 0.0f,
xEnd, yEnd, 1.0f, 1.0f,
xStart, yEnd, 0.0f, 1.0f
});
}
}
::GLES::glGenVertexArrays(1, &sRes.quadVAO);
::GLES::glGenBuffers(1, &sRes.quadVBO);
::GLES::glBindVertexArray(sRes.quadVAO);
::GLES::glBindBuffer(GL_ARRAY_BUFFER, sRes.quadVBO);
::GLES::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
::GLES::glEnableVertexAttribArray(0);
::GLES::glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
::GLES::glEnableVertexAttribArray(1);
::GLES::glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,4 * sizeof(float), (void*)(2 * sizeof(float)));
::GLES::glBindVertexArray(0);
}
auto& texState = TextureState::GetInstance();
std::vector<std::pair<GLuint, TextureObject*>> sortedTextures;
for (auto&& [stateID, texObj] : texState.textures) {
if (!texObj.generated || texObj.target != GL_TEXTURE_2D) continue;
if (texObj.params.mipmapData.empty()) continue;
sortedTextures.emplace_back(stateID, &texObj);
}
std::sort(sortedTextures.begin(), sortedTextures.end(), [](auto& a, auto& b) {
return a.second->createTimestamp > b.second->createTimestamp;
});
sortedTextures.resize(std::min<size_t>(sortedTextures.size(), 30));
for (auto&& [stateID, texObj] : sortedTextures) {
bool needCreate = sRes.textureCache.find(stateID) == sRes.textureCache.end();
bool needUpdate = true;
GLuint glTexID = 0;
if (needCreate) {
::GLES::glGenTextures(1, &glTexID);
sRes.textureCache[stateID] = glTexID;
needUpdate = true;
} else {
glTexID = sRes.textureCache[stateID];
}
const auto& mip0 = texObj->params.mipmapData.begin()->second;
if (mip0.hasData) {
::GLES::glActiveTexture(GL_TEXTURE0);
::GLES::glBindTexture(GL_TEXTURE_2D, glTexID);
if (needUpdate || needCreate) {
::GLES::glTexImage2D(GL_TEXTURE_2D, 0, mip0.internalFormat,
mip0.width, mip0.height, 0,
mip0.format, mip0.type, mip0.pixelData.data());
::GLES::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::GLES::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::GLES::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
::GLES::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (texObj->params.mipmapData.size() > 1) {
::GLES::glGenerateMipmap(GL_TEXTURE_2D);
}
}
}
}
GLboolean origDepthTest = glIsEnabled(GL_DEPTH_TEST);
GLint origProgram;
GLint origViewport[4];
::GLES::glGetIntegerv(GL_VIEWPORT, origViewport);
::GLES::glGetIntegerv(GL_CURRENT_PROGRAM, &origProgram);
::GLES::glDisable(GL_DEPTH_TEST);
::GLES::glUseProgram(sRes.program);
GLint uTexLoc = ::GLES::glGetUniformLocation(sRes.program, "uTex");
::GLES::glUniform1i(uTexLoc, 0);
::GLES::glBindVertexArray(sRes.quadVAO);
glm::mat4 proj = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f);
GLint uMVPLoc = glGetUniformLocation(sRes.program, "uMVP");
glm::mat4 identity(1.0f);
::GLES::glUniformMatrix4fv(uMVPLoc, 1, GL_FALSE, &identity[0][0]);
for (size_t i = 0; i < sortedTextures.size(); ++i) {
GLuint glTexID = sRes.textureCache[sortedTextures[i].first];
::GLES::glActiveTexture(GL_TEXTURE0);
::GLES::glBindTexture(GL_TEXTURE_2D, glTexID);
GLint uTexLoc = ::GLES::glGetUniformLocation(sRes.program, "uTex");
::GLES::glUniform1i(uTexLoc, 0);
::GLES::glDrawArrays(GL_TRIANGLE_FAN, static_cast<GLint>(i*4), 4);
}
}
}
+14
View File
@@ -0,0 +1,14 @@
//
// Created by BZLZHH on 2025/4/26.
//
#ifndef MOBILEGL_TESTDRAWING_H
#define MOBILEGL_TESTDRAWING_H
#include "../../../Includes.h"
namespace MG_RHI::GLES::Test {
void DrawAllTextures();
}
#endif //MOBILEGL_TESTDRAWING_H