[Feat] (MG_Impl/Program, MG_State/Program): initial impl of shader related states

This commit is contained in:
2025-08-11 15:19:35 +08:00
parent 9944408104
commit 2c40177f06
9 changed files with 231 additions and 38 deletions
+94 -10
View File
@@ -1,5 +1,7 @@
#include "GL_Program.h"
#include "MG_State/GLState/Core.h"
namespace MobileGL {
namespace MG_Impl::GLImpl {
void AttachShader_State(GLuint program, GLuint shader) {
@@ -11,27 +13,99 @@ namespace MobileGL {
}
void CompileShader_State(GLuint shader) {
THROW_UNIMPL_EXCEPTION;
if (!MG_State::pGLContext->ValidateShaderName(shader)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shader` is not a value generated by OpenGL."));
return;
}
auto shaderObject = MG_State::pGLContext->GetShaderObject(shader);
if (!shaderObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shader` is not a shader object."));
return;
}
shaderObject->Compile();
}
GLuint CreateProgram_State(void) {
THROW_UNIMPL_EXCEPTION;
return MG_State::pGLContext->CreateProgram();
}
GLuint CreateShader_State(GLenum type) {
THROW_UNIMPL_EXCEPTION;
auto shaderId = MG_State::pGLContext->CreateShader(MG_State::GLState::GetMGLShaderStageByGLShaderType(type));
if (shaderId == 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shaderType` is not an accepted value."));
return 0;
}
return shaderId;
}
void DeleteProgram_State(GLuint program) {
THROW_UNIMPL_EXCEPTION;
if (!MG_State::pGLContext->ValidateProgramName(program)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`program` is not a value generated by OpenGL"));
return;
}
MG_State::pGLContext->MarkProgramForDeletion(program);
}
void DeleteShader_State(GLuint shader) {
THROW_UNIMPL_EXCEPTION;
if (!MG_State::pGLContext->ValidateShaderName(shader)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shader` is not a value generated by OpenGL"));
return;
}
MG_State::pGLContext->MarkShaderForDeletion(shader);
}
void DetachShader_State(GLuint program, GLuint shader) {
THROW_UNIMPL_EXCEPTION;
if (!MG_State::pGLContext->ValidateProgramName(program) ||
!MG_State::pGLContext->ValidateShaderName(shader)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Either `program` or `shader` is a value that was not generated by OpenGL"));
return;
}
auto programObject = MG_State::pGLContext->GetProgramObject(program);
if (!programObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`program` is not a program object."));
return;
}
auto shaderObject = MG_State::pGLContext->GetShaderObject(shader);
if (!shaderObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shader` is not a shader object."));
return;
}
auto count = programObject->DetachShader(shaderObject);
if (count <= 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Shader is not attached to program."));
return;
}
}
void GetActiveAttrib_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size,
@@ -85,11 +159,19 @@ namespace MobileGL {
}
GLboolean IsProgram_State(GLuint program) {
THROW_UNIMPL_EXCEPTION;
/* FIXME: Handle situations that:
* A program object marked for deletion with glDeleteProgram but still in use as part of current
* rendering state is still considered a program object and glIsProgram will return GL_TRUE.
*/
return MG_State::pGLContext->ValidateProgramName(program);
}
GLboolean IsShader_State(GLuint shader) {
THROW_UNIMPL_EXCEPTION;
/* FIXME: Handle situations that:
* A shader object marked for deletion with glDeleteShader but still attached to a program object is still
* considered a shader object and glIsShader will return GL_TRUE.
*/
return MG_State::pGLContext->ValidateShaderName(shader);
}
void LinkProgram_State(GLuint program) {
@@ -227,8 +309,9 @@ namespace MobileGL {
void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
GetAttachedShaders_State(program, maxCount, count, shaders);
}
GLint GetAttribLocation(GLuint program, const GLchar* name) {
GetAttribLocation_State(program, name);
return GetAttribLocation_State(program, name);
}
void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
@@ -250,8 +333,9 @@ namespace MobileGL {
void GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) {
GetShaderSource_State(shader, bufSize, length, source);
}
GLint GetUniformLocation(GLuint program, const GLchar* name) {
GetUniformLocation_State(program, name);
return GetUniformLocation_State(program, name);
}
void GetUniformfv(GLuint program, GLint location, GLfloat* params) {