diff --git a/CMakeLists.txt b/CMakeLists.txt index 42afb407..87ca0874 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,6 @@ add_library(${CMAKE_PROJECT_NAME} SHARED MG/MG_GL/Implementations/GL/Program/GL_Program.cpp - MG/MG_GL/Implementations/GL/Shader/GL_Shader.cpp - MG/MG_GL/Implementations/GL/Texture/GL_Texture.cpp MG/MG_GL/Implementations/GL/VertexArray/GL_VertexArray.cpp @@ -65,6 +63,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED MG/MG_GL/State/VertexArray/VertexArrayState.cpp MG/MG_GL/State/Buffer/BufferState.cpp + + MG/MG_GL/State/Program/ProgramState.cpp # MG_GL/BackendLoader MG/MG_GL/BackendLoader/GLES/Loader.cpp diff --git a/MG/Includes.h b/MG/Includes.h index 5ca8453b..d0af133a 100644 --- a/MG/Includes.h +++ b/MG/Includes.h @@ -26,9 +26,6 @@ #ifndef MOBILEGL_GL_PROGRAM_H #include "MG_GL/Implementations/GL/Program/GL_Program.h" #endif -#ifndef MOBILEGL_GL_SHADER_H -#include "MG_GL/Implementations/GL/Shader/GL_Shader.h" -#endif #ifndef MOBILEGL_GL_TEXTURE_H #include "MG_GL/Implementations/GL/Texture/GL_Texture.h" #endif @@ -50,6 +47,9 @@ #ifndef MOBILEGL_BUFFERSTATE_H #include "MG_GL/State/Buffer/BufferState.h" #endif +#ifndef MOBILEGL_PROGRAMSTATE_H +#include "MG_GL/State/Program/ProgramState.h" +#endif #ifndef MOBILEGL_LOOKUP_H #include "MG_GL/Implementations/GLX/LookUp/LookUp.h" #endif @@ -99,6 +99,8 @@ #include #include "GLES/gl32.h" +#include "MG_Include/UncertainBool.hpp" + #ifdef __ANDROID__ #include #include diff --git a/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp b/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp index eaf8c198..153d00bc 100644 --- a/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp +++ b/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp @@ -34,8 +34,8 @@ DECLARE_GL_FUNCTION_HEAD(const GLubyte*, GetString, GLenum name) DECLARE_GL_FUNC DECLARE_GL_FUNCTION_HEAD(void*, MapBuffer, GLenum target, GLenum access) DECLARE_GL_FUNCTION_END(void*, MapBuffer, target, access) DECLARE_GL_FUNCTION_HEAD(void, ClearDepth, GLclampd depth) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearDepth, depth) DECLARE_GL_FUNCTION_HEAD(void, ActiveTexture, GLenum texture) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ActiveTexture, texture) -DECLARE_GL_FUNCTION_STUB_HEAD(void, AttachShader, GLuint program, GLuint shader) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, AttachShader, program,shader) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindAttribLocation, program,index,name) +DECLARE_GL_FUNCTION_HEAD(void, AttachShader, GLuint program, GLuint shader) DECLARE_GL_FUNCTION_END_NO_RETURN(void, AttachShader, program,shader) +DECLARE_GL_FUNCTION_HEAD(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindAttribLocation, program,index,name) DECLARE_GL_FUNCTION_HEAD(void, BindBuffer, GLenum target, GLuint buffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindBuffer, target,buffer) DECLARE_GL_FUNCTION_STUB_HEAD(void, BindFramebuffer, GLenum target, GLuint framebuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindFramebuffer, target,framebuffer) DECLARE_GL_FUNCTION_STUB_HEAD(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindRenderbuffer, target,renderbuffer) @@ -58,14 +58,14 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, CompressedTexImage2D, GLenum target, GLint l DECLARE_GL_FUNCTION_STUB_HEAD(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CompressedTexSubImage2D, target,level,xoffset,yoffset,width,height,format,imageSize,data) DECLARE_GL_FUNCTION_STUB_HEAD(void, CopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CopyTexImage2D, target,level,internalformat,x,y,width,height,border) DECLARE_GL_FUNCTION_STUB_HEAD(void, CopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CopyTexSubImage2D, target,level,xoffset,yoffset,x,y,width,height) -DECLARE_GL_FUNCTION_STUB_HEAD(GLuint, CreateProgram) DECLARE_GL_FUNCTION_STUB_END(GLuint, CreateProgram) -DECLARE_GL_FUNCTION_STUB_HEAD(GLuint, CreateShader, GLenum type) DECLARE_GL_FUNCTION_STUB_END(GLuint, CreateShader, type) +DECLARE_GL_FUNCTION_HEAD(GLuint, CreateProgram) DECLARE_GL_FUNCTION_END(GLuint, CreateProgram) +DECLARE_GL_FUNCTION_HEAD(GLuint, CreateShader, GLenum type) DECLARE_GL_FUNCTION_END(GLuint, CreateShader, type) DECLARE_GL_FUNCTION_STUB_HEAD(void, CullFace, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CullFace, mode) DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteBuffers, GLsizei n, const GLuint *buffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteBuffers, n,buffers) DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteFramebuffers, n,framebuffers) -DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteProgram, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteProgram, program) +DECLARE_GL_FUNCTION_HEAD(void, DeleteProgram, GLuint program) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteProgram, program) DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteRenderbuffers, n,renderbuffers) -DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteShader, GLuint shader) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteShader, shader) +DECLARE_GL_FUNCTION_HEAD(void, DeleteShader, GLuint shader) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteShader, shader) DECLARE_GL_FUNCTION_HEAD(void, DeleteTextures, GLsizei n, const GLuint *textures) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteTextures, n,textures) DECLARE_GL_FUNCTION_STUB_HEAD(void, DepthFunc, GLenum func) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DepthFunc, func) DECLARE_GL_FUNCTION_STUB_HEAD(void, DepthMask, GLboolean flag) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DepthMask, flag) @@ -90,7 +90,7 @@ DECLARE_GL_FUNCTION_HEAD(void, GenTextures, GLsizei n, GLuint *textures) DECLARE DECLARE_GL_FUNCTION_STUB_HEAD(void, GetActiveAttrib, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetActiveAttrib, program,index,bufSize,length,size,type,name) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetActiveUniform, program,index,bufSize,length,size,type,name) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetAttachedShaders, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetAttachedShaders, program,maxCount,count,shaders) -DECLARE_GL_FUNCTION_STUB_HEAD(GLint, GetAttribLocation, GLuint program, const GLchar *name) DECLARE_GL_FUNCTION_STUB_END(GLint, GetAttribLocation, program,name) +DECLARE_GL_FUNCTION_HEAD(GLint, GetAttribLocation, GLuint program, const GLchar *name) DECLARE_GL_FUNCTION_END(GLint, GetAttribLocation, program,name) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBooleanv, GLenum pname, GLboolean *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBooleanv, pname,data) DECLARE_GL_FUNCTION_HEAD(void, GetBufferParameteriv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetBufferParameteriv, target,pname,params) DECLARE_GL_FUNCTION_HEAD(GLenum, GetError) DECLARE_GL_FUNCTION_END(GLenum, GetError) @@ -108,7 +108,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetTexParameterfv, GLenum target, GLenum pna DECLARE_GL_FUNCTION_STUB_HEAD(void, GetTexParameteriv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetTexParameteriv, target,pname,params) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetUniformfv, GLuint program, GLint location, GLfloat *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetUniformfv, program,location,params) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetUniformiv, GLuint program, GLint location, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetUniformiv, program,location,params) -DECLARE_GL_FUNCTION_STUB_HEAD(GLint, GetUniformLocation, GLuint program, const GLchar *name) DECLARE_GL_FUNCTION_STUB_END(GLint, GetUniformLocation, program,name) +DECLARE_GL_FUNCTION_HEAD(GLint, GetUniformLocation, GLuint program, const GLchar *name) DECLARE_GL_FUNCTION_END(GLint, GetUniformLocation, program,name) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribfv, GLuint index, GLenum pname, GLfloat *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribfv, index,pname,params) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribiv, GLuint index, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribiv, index,pname,params) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribPointerv, GLuint index, GLenum pname, void **pointer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribPointerv, index,pname,pointer) @@ -121,7 +121,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsRenderbuffer, GLuint renderbuffer) DE DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsShader, GLuint shader) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsShader, shader) DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsTexture, GLuint texture) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsTexture, texture) DECLARE_GL_FUNCTION_STUB_HEAD(void, LineWidth, GLfloat width) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, LineWidth, width) -DECLARE_GL_FUNCTION_STUB_HEAD(void, LinkProgram, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, LinkProgram, program) +DECLARE_GL_FUNCTION_HEAD(void, LinkProgram, GLuint program) DECLARE_GL_FUNCTION_END_NO_RETURN(void, LinkProgram, program) DECLARE_GL_FUNCTION_HEAD(void, PixelStorei, GLenum pname, GLint param) DECLARE_GL_FUNCTION_END_NO_RETURN(void, PixelStorei, pname,param) DECLARE_GL_FUNCTION_STUB_HEAD(void, PolygonOffset, GLfloat factor, GLfloat units) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PolygonOffset, factor,units) DECLARE_GL_FUNCTION_STUB_HEAD(void, ReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ReadPixels, x,y,width,height,format,type,pixels) @@ -130,7 +130,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, RenderbufferStorage, GLenum target, GLenum i DECLARE_GL_FUNCTION_STUB_HEAD(void, SampleCoverage, GLfloat value, GLboolean invert) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, SampleCoverage, value,invert) DECLARE_GL_FUNCTION_STUB_HEAD(void, Scissor, GLint x, GLint y, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Scissor, x,y,width,height) DECLARE_GL_FUNCTION_STUB_HEAD(void, ShaderBinary, GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ShaderBinary, count,shaders,binaryformat,binary,length) -DECLARE_GL_FUNCTION_STUB_HEAD(void, ShaderSource, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ShaderSource, shader,count,string,length) +DECLARE_GL_FUNCTION_HEAD(void, ShaderSource, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ShaderSource, shader,count,string,length) DECLARE_GL_FUNCTION_STUB_HEAD(void, StencilFunc, GLenum func, GLint ref, GLuint mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, StencilFunc, func,ref,mask) DECLARE_GL_FUNCTION_STUB_HEAD(void, StencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, StencilFuncSeparate, face,func,ref,mask) DECLARE_GL_FUNCTION_STUB_HEAD(void, StencilMask, GLuint mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, StencilMask, mask) @@ -162,7 +162,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, Uniform4iv, GLint location, GLsizei count, c DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix2fv, location,count,transpose,value) DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix3fv, location,count,transpose,value) DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix4fv, location,count,transpose,value) -DECLARE_GL_FUNCTION_STUB_HEAD(void, UseProgram, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UseProgram, program) +DECLARE_GL_FUNCTION_HEAD(void, UseProgram, GLuint program) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UseProgram, program) DECLARE_GL_FUNCTION_STUB_HEAD(void, ValidateProgram, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ValidateProgram, program) DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib1f, GLuint index, GLfloat x) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib1f, index,x) DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib1fv, GLuint index, const GLfloat *v) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib1fv, index,v) diff --git a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp index 6ad7f054..267db769 100644 --- a/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp +++ b/MG/MG_GL/Implementations/GL/Program/GL_Program.cpp @@ -5,8 +5,129 @@ #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; + GLuint CreateShader(GLenum type) { + MG_Util::Debug::LogD("glCreateShader, type: %s", MG_Util::Debug::GLEnumToString(type)); + GLuint shader; + GLenum result = MG_State::CreateShader(type, &shader); + if (result == GL_NO_ERROR) { + MG_Util::Debug::LogD("Created shader ID: %u", shader); + return shader; + } + MG_State::SetError(result); + MG_Util::Debug::LogE("Error creating shader: %s", MG_Util::Debug::GLEnumToString(result)); + return 0; + } + + GLuint CreateProgram() { + MG_Util::Debug::LogD("glCreateProgram"); + GLuint program; + GLenum result = MG_State::CreateProgram(&program); + if (result == GL_NO_ERROR) { + MG_Util::Debug::LogD("Created program ID: %u", program); + return program; + } + MG_State::SetError(result); + MG_Util::Debug::LogE("Error creating program: %s", MG_Util::Debug::GLEnumToString(result)); + return 0; + } + + void DeleteShader(GLuint shader) { + MG_Util::Debug::LogD("glDeleteShader, shader: %u", shader); + GLenum result = MG_State::DeleteShader(shader); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error deleting shader: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void DeleteProgram(GLuint program) { + MG_Util::Debug::LogD("glDeleteProgram, program: %u", program); + GLenum result = MG_State::DeleteProgram(program); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error deleting program: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void AttachShader(GLuint program, GLuint shader) { + MG_Util::Debug::LogD("glAttachShader, program: %u, shader: %u", program, shader); + GLenum result = MG_State::LinkShaderToProgram(program, shader); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error attaching shader: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void ShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint* length) { + MG_Util::Debug::LogD("glShaderSource, shader: %u, count: %d", shader, count); + GLenum result = MG_State::UploadShaderSource(shader, count, (const GLchar **)string, length); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error setting shader source: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void CompileShader(GLuint shader) { + MG_Util::Debug::LogD("glCompileShader, shader: %u", shader); + GLenum result = MG_State::BuildShaderStage(shader); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error compiling shader: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void LinkProgram(GLuint program) { + MG_Util::Debug::LogD("glLinkProgram, program: %u", program); + GLenum result = MG_State::FinalizeProgramPipeline(program); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error linking program: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void UseProgram(GLuint program) { + MG_Util::Debug::LogD("glUseProgram, program: %u", program); + GLenum result = MG_State::ActivateRenderProgram(program); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error using program: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void BindAttribLocation(GLuint program, GLuint index, const GLchar* name) { + MG_Util::Debug::LogD("glBindAttribLocation, program: %u, index: %u, name: %s", program, index, name); + GLenum result = MG_State::DefineProgramAttributeBinding(program, index, name); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error binding attribute: %s", MG_Util::Debug::GLEnumToString(result)); + } + + GLint GetAttribLocation(GLuint program, const GLchar* name) { + MG_Util::Debug::LogD("glGetAttribLocation, program: %u, name: %s", program, name); + GLint location = MG_State::QueryProgramAttributeBinding(program, name); + if (location != -1) return location; + MG_State::SetError(GL_INVALID_OPERATION); + MG_Util::Debug::LogE("Attribute not found: %s", name); + return -1; + } + + GLint GetUniformLocation(GLuint program, const GLchar* name) { + MG_Util::Debug::LogD("glGetUniformLocation, program: %u, name: %s", program, name); + GLint location = MG_State::QueryProgramUniformLocation(program, name); + if (location != -1) return location; + MG_State::SetError(GL_INVALID_OPERATION); + MG_Util::Debug::LogE("Uniform not found: %s", name); + return -1; + } + + void GetProgramiv(GLuint program, GLenum pname, GLint* params) { + MG_Util::Debug::LogD("glGetProgramiv, program: %u, pname: %s", + program, MG_Util::Debug::GLEnumToString(pname)); + GLenum result = MG_State::QueryProgramStateIntVector(program, pname, params); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error getting program param: %s", MG_Util::Debug::GLEnumToString(result)); + } + + void GetShaderiv(GLuint shader, GLenum pname, GLint* params) { + MG_Util::Debug::LogD("glGetShaderiv, shader: %u, pname: %s", + shader, MG_Util::Debug::GLEnumToString(pname)); + GLenum result = MG_State::QueryShaderStateIntVector(shader, pname, params); + if (result == GL_NO_ERROR) return; + MG_State::SetError(result); + MG_Util::Debug::LogE("Error getting shader param: %s", MG_Util::Debug::GLEnumToString(result)); } } \ No newline at end of file diff --git a/MG/MG_GL/Implementations/GL/Program/GL_Program.h b/MG/MG_GL/Implementations/GL/Program/GL_Program.h index 89ff17ab..53039296 100644 --- a/MG/MG_GL/Implementations/GL/Program/GL_Program.h +++ b/MG/MG_GL/Implementations/GL/Program/GL_Program.h @@ -8,7 +8,20 @@ #include "../../../../Includes.h" namespace MG_GL::GL { - void GetProgramiv(GLuint program, GLenum pname, GLint *params); + GLuint CreateShader(GLenum type); + GLuint CreateProgram(); + void DeleteShader(GLuint shader); + void DeleteProgram(GLuint program); + void AttachShader(GLuint program, GLuint shader); + void ShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint* length); + void CompileShader(GLuint shader); + void LinkProgram(GLuint program); + void UseProgram(GLuint program); + void BindAttribLocation(GLuint program, GLuint index, const GLchar* name); + GLint GetAttribLocation(GLuint program, const GLchar* name); + GLint GetUniformLocation(GLuint program, const GLchar* name); + void GetProgramiv(GLuint program, GLenum pname, GLint* params); + void GetShaderiv(GLuint shader, GLenum pname, GLint* params); } #endif //MOBILEGL_GL_PROGRAM_H diff --git a/MG/MG_GL/Implementations/GL/Shader/GL_Shader.cpp b/MG/MG_GL/Implementations/GL/Shader/GL_Shader.cpp deleted file mode 100644 index 79b58af4..00000000 --- a/MG/MG_GL/Implementations/GL/Shader/GL_Shader.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by BZLZHH on 2025/3/15. -// - -#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; - } -} \ No newline at end of file diff --git a/MG/MG_GL/Implementations/GL/Shader/GL_Shader.h b/MG/MG_GL/Implementations/GL/Shader/GL_Shader.h deleted file mode 100644 index 40081308..00000000 --- a/MG/MG_GL/Implementations/GL/Shader/GL_Shader.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// Created by BZLZHH on 2025/3/15. -// - -#ifndef MOBILEGL_GL_SHADER_H -#define MOBILEGL_GL_SHADER_H - -#include "../../../../Includes.h" - -namespace MG_GL::GL { - void GetShaderiv(GLuint shader, GLenum pname, GLint *params); -} - -#endif //MOBILEGL_GL_SHADER_H diff --git a/MG/MG_GL/Implementations/GL/Texture/GL_Texture.cpp b/MG/MG_GL/Implementations/GL/Texture/GL_Texture.cpp index ac67782a..be4d7b6e 100644 --- a/MG/MG_GL/Implementations/GL/Texture/GL_Texture.cpp +++ b/MG/MG_GL/Implementations/GL/Texture/GL_Texture.cpp @@ -84,7 +84,7 @@ namespace MG_GL::GL { void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) { MG_Util::Debug::LogD("glGetTexLevelParameteriv, target: %d, level: %d, pname: %d, params: %p", target, level, pname, params); - GLenum result = MG_State::GetTextureLevelPropertyIntVector(target, level, pname, params); + GLenum result = MG_State::QueryTextureLevelPropertyIntVector(target, level, pname, params); if (result == GL_NO_ERROR) return; MG_State::SetError(result); diff --git a/MG/MG_GL/State/Common/CommonState.cpp b/MG/MG_GL/State/Common/CommonState.cpp index c08f30e5..50552b03 100644 --- a/MG/MG_GL/State/Common/CommonState.cpp +++ b/MG/MG_GL/State/Common/CommonState.cpp @@ -45,7 +45,7 @@ GLenum CommonState::SetPixelStoreInt(GLenum pname, GLint param) { return GL_NO_ERROR; } -GLint CommonState::GetPixelStoreInt(GLenum pname) { +GLint CommonState::QueryPixelStoreInt(GLenum pname) { auto it = pixelStoreParams.find(pname); if (it != pixelStoreParams.end()) { return it->second; diff --git a/MG/MG_GL/State/Common/CommonState.h b/MG/MG_GL/State/Common/CommonState.h index a2b58a61..ab4b25fe 100644 --- a/MG/MG_GL/State/Common/CommonState.h +++ b/MG/MG_GL/State/Common/CommonState.h @@ -16,7 +16,7 @@ public: // Return: the validity of the operation, according to OpenGL 3 standard GLenum SetPixelStoreInt(GLenum pname, GLint param); - GLint GetPixelStoreInt(GLenum pname); + GLint QueryPixelStoreInt(GLenum pname); }; #endif //MOBILEGL_COMMONSTATE_H diff --git a/MG/MG_GL/State/Core/GLState.cpp b/MG/MG_GL/State/Core/GLState.cpp index bcd4d433..ce86134f 100644 --- a/MG/MG_GL/State/Core/GLState.cpp +++ b/MG/MG_GL/State/Core/GLState.cpp @@ -9,6 +9,7 @@ TextureState* MG_State_T::textureState = nullptr; CommonState* MG_State_T::commonState = nullptr; BufferState* MG_State_T::bufferState = nullptr; VertexArrayState* MG_State_T::vertexArrayState = nullptr; +ProgramState* MG_State_T::programState = nullptr; namespace MG_State { void Init() { @@ -16,6 +17,7 @@ namespace MG_State { MG_State_T::commonState = new CommonState(); MG_State_T::bufferState = new BufferState(); MG_State_T::vertexArrayState = new VertexArrayState(); + MG_State_T::programState = new ProgramState(); } void Destroy() { @@ -23,6 +25,7 @@ namespace MG_State { delete MG_State_T::commonState; delete MG_State_T::bufferState; delete MG_State_T::vertexArrayState; + delete MG_State_T::programState; } void SetError(GLenum error) { @@ -88,8 +91,8 @@ namespace MG_State { return MG_State_T::textureState->DeleteN(n, textures); } - GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) { - return MG_State_T::textureState->GetLevelPropertyIntVector(target, level, pname, params); + GLenum QueryTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) { + return MG_State_T::textureState->QueryLevelPropertyIntVector(target, level, pname, params); } // Common @@ -97,8 +100,8 @@ namespace MG_State { return MG_State_T::commonState->SetPixelStoreInt(pname, param); } - GLint MG_State::GetPixelStoreInt(GLenum pname) { - return MG_State_T::commonState->GetPixelStoreInt(pname); + GLint MG_State::QueryPixelStoreInt(GLenum pname) { + return MG_State_T::commonState->QueryPixelStoreInt(pname); } // Buffer @@ -180,4 +183,73 @@ namespace MG_State { index, size, type, GL_FALSE, stride, pointer, true, currentBuffer ); } + + // Program + GLenum CreateShader(GLenum type, GLuint* shader) { + return MG_State_T::programState->CreateShader(type, shader); + } + + GLenum CreateProgram(GLuint* program) { + return MG_State_T::programState->CreateProgram(program); + } + + GLenum DeleteShader(GLuint shader) { + return MG_State_T::programState->DeleteShader(shader); + } + + GLenum DeleteProgram(GLuint program) { + return MG_State_T::programState->DeleteProgram(program); + } + + GLenum LinkShaderToProgram(GLuint program, GLuint shader) { + return MG_State_T::programState->LinkShaderToProgram(program, shader); + } + + GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) { + return MG_State_T::programState->UploadShaderSource(shader, count, string, length); + } + + GLenum BuildShaderStage(GLuint shader) { + return MG_State_T::programState->BuildShaderStage(shader); + } + + GLenum FinalizeProgramPipeline(GLuint program) { + return MG_State_T::programState->FinalizeProgramPipeline(program); + } + + GLenum ActivateRenderProgram(GLuint program) { + return MG_State_T::programState->ActivateRenderProgram(program); + } + + GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name) { + return MG_State_T::programState->DefineProgramAttributeBinding(program, index, name); + } + + GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name) { + return MG_State_T::programState->QueryProgramAttributeBinding(program, name); + } + + GLint QueryProgramUniformLocation(GLuint program, const GLchar* name) { + return MG_State_T::programState->QueryProgramUniformLocation(program, name); + } + + GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params) { + return MG_State_T::programState->QueryProgramStateIntVector(program, pname, params); + } + + GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params) { + return MG_State_T::programState->QueryShaderStateIntVector(shader, pname, params); + } + + GLuint GetCurrentProgram() { + return MG_State_T::programState->GetCurrentProgram(); + } + + bool SetProgramStatus(GLuint program, GLboolean status) { + return MG_State_T::programState->SetProgramStatus(program, status); + } + + bool SetShaderStatus(GLuint shader, GLboolean status) { + return MG_State_T::programState->SetShaderStatus(shader, status); + } } \ No newline at end of file diff --git a/MG/MG_GL/State/Core/GLState.h b/MG/MG_GL/State/Core/GLState.h index 25cdda1e..f31e0661 100644 --- a/MG/MG_GL/State/Core/GLState.h +++ b/MG/MG_GL/State/Core/GLState.h @@ -13,6 +13,7 @@ struct MG_State_T { static CommonState* commonState; static BufferState* bufferState; static VertexArrayState* vertexArrayState; + static ProgramState* programState; }; namespace MG_State { @@ -36,11 +37,11 @@ namespace MG_State { GLenum SetTexturePropertyFloat(GLenum target, GLenum pname, GLfloat param); GLenum DeleteTexture(GLuint texture); GLenum DeleteTextures(GLsizei n, const GLuint* textures); - GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params); + GLenum QueryTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params); // Common GLenum SetPixelStoreInt(GLenum pname, GLint param); - GLint GetPixelStoreInt(GLenum pname); + GLint QueryPixelStoreInt(GLenum pname); // Buffer GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr); @@ -54,7 +55,6 @@ namespace MG_State { GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params); // VertexArray - GLenum CreateVertexArray(GLuint* array); GLenum CreateVertexArrays(GLsizei n, GLuint* arrays); GLenum BindVertexArray(GLuint array); @@ -65,6 +65,26 @@ namespace MG_State { const void* pointer); GLenum SetVertexAttributeLayoutInt(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + + // Program + GLenum CreateShader(GLenum type, GLuint* shader); + GLenum CreateProgram(GLuint* program); + GLenum DeleteShader(GLuint shader); + GLenum DeleteProgram(GLuint program); + GLenum LinkShaderToProgram(GLuint program, GLuint shader); + GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); + GLenum BuildShaderStage(GLuint shader); + GLenum FinalizeProgramPipeline(GLuint program); + GLenum ActivateRenderProgram(GLuint program); + GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name); + GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name); + GLint QueryProgramUniformLocation(GLuint program, const GLchar* name); + GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params); + GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params); + + GLuint GetCurrentProgram(); + bool SetProgramStatus(GLuint program, GLboolean status); + bool SetShaderStatus(GLuint shader, GLboolean status); } diff --git a/MG/MG_GL/State/Program/ProgramState.cpp b/MG/MG_GL/State/Program/ProgramState.cpp new file mode 100644 index 00000000..02aecf29 --- /dev/null +++ b/MG/MG_GL/State/Program/ProgramState.cpp @@ -0,0 +1,258 @@ +// +// Created by BZLZHH on 2025/5/1. +// + +// TODO: Add more gl error check for buffer state manager. +// TODO: Check if the state machine really meets up to OpenGL 3 standard. + +#include "ProgramState.h" + +GLenum ProgramState::CreateShader(GLenum type, GLuint* shader) { + if (!shader) return GL_INVALID_VALUE; + if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) + return GL_INVALID_ENUM; + + GLuint id = freeShaderIds_.empty() ? ++lastShaderId_ : *freeShaderIds_.begin(); + if (!freeShaderIds_.empty()) freeShaderIds_.erase(freeShaderIds_.begin()); + + ShaderObject obj; + obj.type = type; + obj.compiled = UncertainBool::False; + obj.markedForDeletion = false; + shaders_[id] = obj; + *shader = id; + return GL_NO_ERROR; +} + +GLenum ProgramState::CreateProgram(GLuint* program) { + if (!program) return GL_INVALID_VALUE; + + GLuint id = freeProgramIds_.empty() ? ++lastProgramId_ : *freeProgramIds_.begin(); + if (!freeProgramIds_.empty()) freeProgramIds_.erase(freeProgramIds_.begin()); + + ProgramObject obj; + obj.linked = UncertainBool::False; + obj.markedForDeletion = false; + programs_[id] = obj; + *program = id; + return GL_NO_ERROR; +} + +GLenum ProgramState::DeleteShader(GLuint shader) { + if (!ValidateShader_(shader)) return GL_INVALID_VALUE; + + if (shaders_[shader].markedForDeletion) return GL_NO_ERROR; + + bool inUse = false; + for (auto& [progId, program] : programs_) { + auto it = std::find(program.attachedShaders.begin(), + program.attachedShaders.end(), shader); + if (it != program.attachedShaders.end()) { + inUse = true; + break; + } + } + + if (inUse) { + shaders_[shader].markedForDeletion = true; + } else { + shaders_.erase(shader); + freeShaderIds_.insert(shader); + } + return GL_NO_ERROR; +} + +GLenum ProgramState::DeleteProgram(GLuint program) { + if (!ValidateProgram_(program)) return GL_INVALID_VALUE; + + programs_.erase(program); + freeProgramIds_.insert(program); + if (currentProgram_ == program) + currentProgram_ = 0; + return GL_NO_ERROR; +} + +GLenum ProgramState::LinkShaderToProgram(GLuint program, GLuint shader) { + if (!ValidateProgram_(program) || !ValidateShader_(shader)) + return GL_INVALID_VALUE; + + auto& prog = programs_[program]; + if (std::find(prog.attachedShaders.begin(), + prog.attachedShaders.end(), shader) != prog.attachedShaders.end()) + return GL_INVALID_OPERATION; + + prog.attachedShaders.push_back(shader); + return GL_NO_ERROR; +} + +GLenum ProgramState::UploadShaderSource(GLuint shader, GLsizei count, + const GLchar** string, const GLint* length) { + if (!ValidateShader_(shader)) return GL_INVALID_VALUE; + if (count < 0) return GL_INVALID_VALUE; + + std::string source; + for (GLsizei i = 0; i < count; ++i) { + const GLchar* str = string[i]; + GLint len = (length && length[i] >= 0) ? length[i] : strlen(str); + source.append(str, len); + } + shaders_[shader].source = std::move(source); + return GL_NO_ERROR; +} + +GLenum ProgramState::BuildShaderStage(GLuint shader) { + if (!ValidateShader_(shader)) return GL_INVALID_VALUE; + + auto& obj = shaders_[shader]; + // TODO: Add glslang to convert it to SPIR-V first, and then check it in the actual backend. + obj.compiled = {UncertainBool::Unknown, UncertainBool::True}; + obj.compileStatus = GL_TRUE; + obj.infoLog.clear(); + + return GL_NO_ERROR; +} + +GLenum ProgramState::FinalizeProgramPipeline(GLuint program) { + if (!ValidateProgram_(program)) return GL_INVALID_VALUE; + auto& prog = programs_[program]; + + for (GLuint shader : prog.attachedShaders) { + if (!shaders_[shader].compiled.toBool()) + return GL_INVALID_OPERATION; + } + + // TODO: Check the actual program linking status. + // We might consider using a program emulator (or real backend checking?) or something better in the future. + prog.linked = {UncertainBool::Unknown, UncertainBool::True}; + prog.linkStatus = GL_TRUE; + prog.infoLog.clear(); + + for (auto& [name, index] : prog.attribBindings) { + prog.attribLocations[name] = index; + } + + CleanupShaders_(); + return GL_NO_ERROR; +} + +GLenum ProgramState::ActivateRenderProgram(GLuint program) { + if (program != 0 && !ValidateProgram_(program)) + return GL_INVALID_VALUE; + + currentProgram_ = program; + return GL_NO_ERROR; +} + +GLenum ProgramState::DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name) { + if (!ValidateProgram_(program)) return GL_INVALID_VALUE; + if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE; + + programs_[program].attribBindings[name] = index; + return GL_NO_ERROR; +} + +GLint ProgramState::QueryProgramAttributeBinding(GLuint program, const GLchar* name) { + if (!ValidateProgram_(program)) return -1; + + auto& prog = programs_[program]; + if (prog.attribLocations.count(name)) + return prog.attribLocations[name]; + return -1; +} + +GLint ProgramState::QueryProgramUniformLocation(GLuint program, const GLchar* name) { + if (!ValidateProgram_(program)) return -1; + + auto& prog = programs_[program]; + if (prog.uniformLocations.count(name)) + return prog.uniformLocations[name]; + return -1; +} + +GLenum ProgramState::QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params) { + if (!ValidateProgram_(program)) return GL_INVALID_VALUE; + auto& prog = programs_[program]; + + switch (pname) { + case GL_LINK_STATUS: *params = prog.linkStatus; break; + case GL_DELETE_STATUS: *params = prog.markedForDeletion; break; + case GL_ATTACHED_SHADERS: *params = (GLint)prog.attachedShaders.size(); break; + default: return GL_INVALID_ENUM; + } + return GL_NO_ERROR; +} + +GLenum ProgramState::QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params) { + if (!ValidateShader_(shader)) return GL_INVALID_VALUE; + auto& obj = shaders_[shader]; + + switch (pname) { + case GL_COMPILE_STATUS: *params = obj.compileStatus; break; + case GL_DELETE_STATUS: *params = obj.markedForDeletion; break; + case GL_SHADER_TYPE: *params = obj.type; break; + default: return GL_INVALID_ENUM; + } + return GL_NO_ERROR; +} + +bool ProgramState::SetProgramStatus(GLuint program, GLboolean status) { + if (!ValidateProgram_(program)) return false; + auto& prog = programs_[program]; + if (prog.linked && status != GL_TRUE) { + return false; + } + if (status == GL_TRUE) + prog.linked = true; + else + prog.linked = false; + prog.linkStatus = status; + return true; +} + +bool ProgramState::SetShaderStatus(GLuint shader, GLboolean status) { + if (!ValidateShader_(shader)) return false; + auto& obj = shaders_[shader]; + if (status == GL_TRUE) + obj.compiled = true; + else + obj.compiled = false; + obj.compileStatus = status; + return true; +} + +bool ProgramState::ValidateShader_(GLuint shader) { + return shaders_.count(shader) && !shaders_[shader].markedForDeletion; +} + +bool ProgramState::ValidateProgram_(GLuint program) { + return programs_.count(program) && !programs_[program].markedForDeletion; +} + +void ProgramState::CleanupShaders_() { + auto it = shaders_.begin(); + while (it != shaders_.end()) { + if (it->second.markedForDeletion) { + bool inUse = false; + for (auto& [progId, program] : programs_) { + if (std::find(program.attachedShaders.begin(), + program.attachedShaders.end(), it->first) + != program.attachedShaders.end()) { + inUse = true; + break; + } + } + if (!inUse) { + freeShaderIds_.insert(it->first); + it = shaders_.erase(it); + } else { + ++it; + } + } else { + ++it; + } + } +} + +GLuint ProgramState::GetCurrentProgram() const { + return currentProgram_; +} \ No newline at end of file diff --git a/MG/MG_GL/State/Program/ProgramState.h b/MG/MG_GL/State/Program/ProgramState.h new file mode 100644 index 00000000..6fc292c5 --- /dev/null +++ b/MG/MG_GL/State/Program/ProgramState.h @@ -0,0 +1,68 @@ +// +// Created by BZLZHH on 2025/5/1. +// + +#ifndef MOBILEGL_PROGRAMSTATE_H +#define MOBILEGL_PROGRAMSTATE_H +#define MOBILEGL_GLSTATE_H + +#include "../../../Includes.h" + +struct ShaderObject { + GLenum type; + std::string source; + UncertainBool compiled; + GLint compileStatus; + std::string infoLog; + bool markedForDeletion; +}; + +struct ProgramObject { + std::vector attachedShaders; + UncertainBool linked; + GLint linkStatus; + std::string infoLog; + std::unordered_map attribBindings; + std::unordered_map attribLocations; + std::unordered_map uniformLocations; + bool markedForDeletion; +}; + +class ProgramState { +private: + std::unordered_map shaders_; + std::unordered_map programs_; + std::set freeShaderIds_; + std::set freeProgramIds_; + GLuint lastShaderId_ = 0; + GLuint lastProgramId_ = 0; + GLuint currentProgram_ = 0; + +public: + // Return: the validity of the operation, according to OpenGL 3 standard + GLenum CreateShader(GLenum type, GLuint* shader); + GLenum CreateProgram(GLuint* program); + GLenum DeleteShader(GLuint shader); + GLenum DeleteProgram(GLuint program); + GLenum LinkShaderToProgram(GLuint program, GLuint shader); + GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); + GLenum BuildShaderStage(GLuint shader); + GLenum FinalizeProgramPipeline(GLuint program); + GLenum ActivateRenderProgram(GLuint program); + GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name); + GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name); + GLint QueryProgramUniformLocation(GLuint program, const GLchar* name); + GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params); + GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params); + + GLuint GetCurrentProgram() const; + bool SetProgramStatus(GLuint program, GLboolean status); + bool SetShaderStatus(GLuint shader, GLboolean status); + +private: + bool ValidateShader_(GLuint shader); + bool ValidateProgram_(GLuint program); + void CleanupShaders_(); +}; + +#endif // MOBILEGL_PROGRAMSTATE_H diff --git a/MG/MG_GL/State/Texture/TextureState.cpp b/MG/MG_GL/State/Texture/TextureState.cpp index 59403933..0c2c48d2 100644 --- a/MG/MG_GL/State/Texture/TextureState.cpp +++ b/MG/MG_GL/State/Texture/TextureState.cpp @@ -38,7 +38,7 @@ TextureState::TextureState() { } GLint TextureState::GetUnpackParam_(GLenum pname) { - GLint result = MG_State::GetPixelStoreInt(pname); + GLint result = MG_State::QueryPixelStoreInt(pname); MG_Util::Debug::LogD("MG_State: Texture: GetUnpackParam_ pname=0x%x, returns %d", pname, result); return result; } @@ -574,31 +574,31 @@ GLenum TextureState::DeleteN(GLsizei n, const GLuint* textures) { } -GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) { - MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector called target=0x%x, level=%d, pname=0x%x", target, level, pname); +GLenum TextureState::QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) { + MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector called target=0x%x, level=%d, pname=0x%x", target, level, pname); if (MG_Constants::Texture::VALID_TARGETS.find(target) == MG_Constants::Texture::VALID_TARGETS.end()) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid target=0x%x", target); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid target=0x%x", target); return GL_INVALID_ENUM; } if (level < 0) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid level=%d", level); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid level=%d", level); return GL_INVALID_VALUE; } if (MG_Constants::Texture::VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES.find(pname) == MG_Constants::Texture::VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES.end()) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid pname=0x%x", pname); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid pname=0x%x", pname); return GL_INVALID_ENUM; } if ((target == GL_TEXTURE_RECTANGLE || target == GL_PROXY_TEXTURE_RECTANGLE) && level != 0) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid level for rectangle texture"); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid level for rectangle texture"); return GL_INVALID_VALUE; } GLuint activeUnit = activeTextureUnit_; if (activeUnit >= textureUnits_.size()) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector active texture unit out of range"); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector active texture unit out of range"); return GL_INVALID_OPERATION; } @@ -614,7 +614,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu if (!isProxyTexture && boundTexture == 0) { switch (pname) { case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector no texture bound for compressed image size"); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector no texture bound for compressed image size"); return GL_INVALID_OPERATION; case GL_TEXTURE_INTERNAL_FORMAT: *params = GL_NONE; @@ -626,7 +626,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu *params = 0; break; } - MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns default value for unbound texture"); + MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns default value for unbound texture"); return GL_NO_ERROR; } @@ -637,7 +637,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu if (texIt == textures.end()) { *params = 0; MG_Util::Debug::LogW( - "MG_State: Texture: GetLevelPropertyIntVector texture %u not found", + "MG_State: Texture: QueryLevelPropertyIntVector texture %u not found", boundTexture); return GL_NO_ERROR; } @@ -646,7 +646,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu TextureObject& tex = isProxyTexture ? proxyTextures_[target] : texIt->second; if (!isProxyTexture && tex.target != target && tex.target != GL_NONE) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector texture target mismatch: texture target=0x%x, expected=0x%x", tex.target, target); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector texture target mismatch: texture target=0x%x, expected=0x%x", tex.target, target); return GL_INVALID_OPERATION; } @@ -654,7 +654,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu if (mipIt == tex.params.mipmapData.end()) { switch (pname) { case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector no mipmap level %d for compressed image size", level); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector no mipmap level %d for compressed image size", level); return GL_INVALID_OPERATION; case GL_TEXTURE_INTERNAL_FORMAT: *params = GL_NONE; @@ -666,7 +666,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu *params = 0; break; } - MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns default value for missing mipmap level"); + MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns default value for missing mipmap level"); return GL_NO_ERROR; } @@ -707,16 +707,16 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if (!sizes.isCompressed) { - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector texture is not compressed"); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector texture is not compressed"); return GL_INVALID_OPERATION; } *params = static_cast(mip.pixelData.size()); break; default: - MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid pname=0x%x", pname); + MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid pname=0x%x", pname); return GL_INVALID_ENUM; } - MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns %d for pname=0x%x", *params, pname); + MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns %d for pname=0x%x", *params, pname); return GL_NO_ERROR; } diff --git a/MG/MG_GL/State/Texture/TextureState.h b/MG/MG_GL/State/Texture/TextureState.h index ccc1a96b..b192ca76 100644 --- a/MG/MG_GL/State/Texture/TextureState.h +++ b/MG/MG_GL/State/Texture/TextureState.h @@ -86,7 +86,7 @@ public: GLenum SetTexturePropertyFloat(GLenum target, GLenum pname, GLfloat param); GLenum Delete(GLuint texture); GLenum DeleteN(GLsizei n, const GLuint* textures); - GLenum GetLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params); + GLenum QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params); private: size_t CalculatePixelDataSize_(GLenum format, GLenum type, GLsizei width, GLsizei height);