From 21a46ee15141d2c84f6a392afbd6db61c3c29582 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 16:47:18 +0800 Subject: [PATCH] [Feat] (MG_State/Program): glShaderSource, glUseProgram --- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 29 +++++++++++++++++-- MobileGL/MG_State/GLState/Core.cpp | 4 +++ MobileGL/MG_State/GLState/Core.h | 1 + .../GLState/ProgramState/ProgramState.cpp | 8 +++++ .../GLState/ProgramState/ProgramState.h | 4 +++ .../GLState/ProgramState/ShaderObject.cpp | 4 +++ .../GLState/ProgramState/ShaderObject.h | 1 + 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index d65a1db5..0e7cea03 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -203,11 +203,36 @@ namespace MobileGL { } void ShaderSource_State(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { - THROW_UNIMPL_EXCEPTION; + if (count < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, + "`count` is less than 0.")); + } + + auto programObject = TryToGetShaderObject(shader); + if (!programObject) + return; + + std::string src; + for (GLsizei i = 0; i < count; i++) { + src += + (length[i] <= 0) ? string[i] : std::string(string[i], length[i]); + } + programObject->SetShaderSource(Move(src)); } void UseProgram_State(GLuint program) { - THROW_UNIMPL_EXCEPTION; + if (program == 0) { + MG_State::pGLContext->UseProgram(0); + return; + } + + auto programObject = TryToGetProgramObject(program); + if (!programObject) + return; + MG_State::pGLContext->UseProgram(program); + } void Uniform1f_State(GLint location, GLfloat v0) { diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 92c190ea..3f28f6f4 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -187,6 +187,10 @@ namespace MobileGL { SharedPtr GLContext::GetShaderObject(const Uint index) { return m_programState.GetShaderObject(index); } + + void GLContext::UseProgram(Uint program) { + return m_programState.UseProgram(program); + } } // namespace GLState GLState::GLContext* pGLContext; diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index b3bb10c6..e57d0785 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -63,6 +63,7 @@ namespace MobileGL { Bool ValidateShaderName(Uint index) const; SharedPtr GetProgramObject(Uint index); SharedPtr GetShaderObject(Uint index); + void UseProgram(Uint program); private: // Error ErrorState m_errorState; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp index a90a9457..6f290128 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp @@ -33,6 +33,14 @@ namespace MobileGL { return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr; } + void ProgramState::UseProgram(Uint program) { + if (program == 0) + m_currentProgram.reset(); + + if (!CheckIndexAvail(program, m_programObjects)) return; + m_currentProgram = m_programObjects[program]; + } + Uint ProgramState::CreateShader(ShaderStage stage) { Uint shaderId = 0; m_shaderIndexGenerator.Generate(1, &shaderId); diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h index 85a653a0..ff981cb1 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h @@ -15,6 +15,8 @@ namespace MobileGL { void MarkProgramObjectForDeletion(Uint program); Bool ValidateProgramObject(Uint program) const; + void UseProgram(Uint program); + Uint CreateShader(ShaderStage stage); SharedPtr GetShaderObject(Uint shader); void MarkShaderObjectForDeletion(Uint shader); @@ -38,6 +40,8 @@ namespace MobileGL { IndexGenerator m_shaderIndexGenerator; Vector> m_shaderObjects; + + SharedPtr m_currentProgram; }; } // namespace GLState } // namespace MG_State diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index fbbd93de..3345f025 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -8,6 +8,10 @@ namespace MobileGL { m_source = source; } + void ShaderObject::SetShaderSource(std::string &&source) { + m_source = Move(source); + } + void ShaderObject::Compile() { using namespace MG_Util::ShaderTranspiler; ShaderAttrib attrib{ diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index c743a629..3d14af78 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -58,6 +58,7 @@ namespace MobileGL { public: ShaderObject(const ShaderStage stage) : m_stage(stage) {} void SetShaderSource(const std::string& source); + void SetShaderSource(std::string&& source); void Compile(); void MarkAsDeleted();