diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 4186cc58..d65a1db5 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -57,7 +57,19 @@ namespace MobileGL { } void AttachShader_State(GLuint program, GLuint shader) { - THROW_UNIMPL_EXCEPTION; + auto programObject = TryToGetProgramObject(program); + if (!programObject) + return; + auto shaderObject = TryToGetShaderObject(shader); + if (!shaderObject) + return; + if (!programObject->AttachShader(shaderObject)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", __func__, + "`shader` is already attached to `program`.")); + return; + } } void BindAttribLocation_State(GLuint program, GLuint index, const GLchar* name) { diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index 2f58b2b7..a82c57a9 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -4,8 +4,19 @@ namespace MobileGL { namespace MG_State { namespace GLState { - void ProgramObject::AttachShader(SharedPtr shader) { + bool ProgramObject::ShaderIsAttached(SharedPtr shader) { + auto it = std::find_if(m_shaders.begin(), m_shaders.end(), + [shader](const SharedPtr& s) { + return s.get() == shader.get(); + }); + return it != m_shaders.end(); + } + + bool ProgramObject::AttachShader(SharedPtr shader) { + if (ShaderIsAttached(shader)) + return false; m_shaders.emplace_back(shader); + return true; } SizeT ProgramObject::DetachShader(SharedPtr shader) { diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index 2d2819a5..1946707d 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -7,7 +7,8 @@ namespace MobileGL { namespace GLState { class ProgramObject { public: - void AttachShader(SharedPtr shader); + bool ShaderIsAttached(SharedPtr shader); + bool AttachShader(SharedPtr shader); SizeT DetachShader(SharedPtr shader); void Link(); void MarkAsDeleted();