mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (MG_Backend/DirectGLES|MG_Impl/Program): Correct UBO binding.
This commit is contained in:
@@ -14,7 +14,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
namespace BufferImpl {
|
namespace BufferImpl {
|
||||||
void SyncNeccessaryBuffers() {
|
void SyncNeccessaryBuffers() {
|
||||||
// All buffers we need are:
|
// All buffers we need are:
|
||||||
// 1.VBOs 2.IBO 3.UBOs (TODO) 4.SSBOs (TODO)
|
// 1.VBO 2.IBO 3.UBO 4.PBO 5.SSBO (TODO)
|
||||||
|
|
||||||
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
||||||
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
||||||
@@ -43,11 +43,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
|
for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
|
||||||
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
|
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
|
||||||
auto obj = point.GetBoundObject();
|
auto obj = point.GetBoundObject();
|
||||||
if (obj)
|
if (obj) buffersToSync.push_back(obj);
|
||||||
buffersToSync.push_back(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PBO
|
// PBO
|
||||||
const auto& pbo = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
const auto& pbo = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||||
if (pbo) {
|
if (pbo) {
|
||||||
@@ -141,22 +139,20 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
MG_State::GLState::FramebufferObject* lastUpdatedFBO = nullptr;
|
MG_State::GLState::FramebufferObject* lastUpdatedFBO = nullptr;
|
||||||
|
|
||||||
for (auto target: fboTargets) {
|
for (auto target : fboTargets) {
|
||||||
auto currentFBO =
|
auto currentFBO = MG_State::pGLContext->GetFramebufferBindingSlot(target).GetBoundObject();
|
||||||
MG_State::pGLContext->GetFramebufferBindingSlot(target).GetBoundObject();
|
|
||||||
|
|
||||||
if (!currentFBO) {
|
if (!currentFBO) {
|
||||||
MGLOG_E("No FBO is currently bound, cannot sync current FBO.");
|
MGLOG_E("No FBO is currently bound, cannot sync current FBO.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentFBO ==
|
if (currentFBO == MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) {
|
||||||
MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) {
|
|
||||||
// Default FBO, nothing to sync
|
// Default FBO, nothing to sync
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &backendFBOIt = g_backendFramebufferObjects.find(currentFBO);
|
const auto& backendFBOIt = g_backendFramebufferObjects.find(currentFBO);
|
||||||
SharedPtr<BackendFramebufferObject> backendFBOObject;
|
SharedPtr<BackendFramebufferObject> backendFBOObject;
|
||||||
if (backendFBOIt == g_backendFramebufferObjects.end()) {
|
if (backendFBOIt == g_backendFramebufferObjects.end()) {
|
||||||
backendFBOObject = MakeShared<BackendFramebufferObject>();
|
backendFBOObject = MakeShared<BackendFramebufferObject>();
|
||||||
@@ -266,12 +262,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO);
|
const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO);
|
||||||
if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) {
|
if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) {
|
||||||
backendFBOIt->second->Bind(target);
|
backendFBOIt->second->Bind(target);
|
||||||
|
} else {
|
||||||
|
MGLOG_E("No backend FBO found (maybe not synced) for current %s FBO, cannot bind FBO.",
|
||||||
|
(target == FramebufferTarget::Read ? "READ" : "DRAW"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (target == FramebufferTarget::Read)
|
MGLOG_D("Binding default framebuffer as %s FBO", (target == FramebufferTarget::Read ? "READ" : "DRAW"));
|
||||||
MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
MG_External::GLES::glBindFramebuffer(
|
||||||
else
|
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0);
|
||||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +334,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
|
auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
|
||||||
// Global UBO
|
// Global UBO
|
||||||
if (currentProgram->GetUBOSize() > 0) {
|
if (currentProgram->GetUBOSize() > 0) {
|
||||||
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, backendProgramIt->second->GetBackendGlobalUBOId());
|
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER,
|
||||||
|
backendProgramIt->second->GetBackendGlobalUBOId());
|
||||||
MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(),
|
MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(),
|
||||||
currentProgram->MapUBO());
|
currentProgram->MapUBO());
|
||||||
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
@@ -351,24 +350,38 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
// Normal UBO
|
// Normal UBO
|
||||||
auto uboCount = currentProgram->GetActiveUniformBlocksCount();
|
auto uboCount = currentProgram->GetActiveUniformBlocksCount();
|
||||||
|
Uint lastUBOBinding = 0; // to prevent overlapping bindings between global UBO and normal UBOs
|
||||||
for (Int i = 0; i < uboCount; ++i) {
|
for (Int i = 0; i < uboCount; ++i) {
|
||||||
// state binding point == backend binding point
|
++lastUBOBinding;
|
||||||
|
// program state binding index == backend binding index
|
||||||
|
|
||||||
// Connect program ubo index to backend binding point
|
// Connect program ubo index to backend binding point
|
||||||
auto binding = currentProgram->GetUniformBlockBinding(i);
|
auto binding = currentProgram->GetUniformBlockBinding(i);
|
||||||
auto& name = currentProgram->GetUniformBlockName(i);
|
auto& name = currentProgram->GetUniformBlockName(i);
|
||||||
GLuint backendBlkIdx = MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str());
|
GLuint backendBlkIdx = MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str());
|
||||||
MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, binding);
|
MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, lastUBOBinding);
|
||||||
|
|
||||||
// Connect buffer to backend binding point
|
// Connect buffer to backend binding point
|
||||||
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
|
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
|
||||||
auto bufferObj = point.GetBoundObject();
|
auto bufferObj = point.GetBoundObject();
|
||||||
auto range = point.GetRange();
|
auto range = point.GetRange();
|
||||||
if (range.end > bufferObj->GetSize()) {
|
|
||||||
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, binding, BufferImpl::g_backendBufferObjects[bufferObj]->GetBackendBufferId());
|
if (bufferObj) {
|
||||||
} else {
|
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObj);
|
||||||
MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, binding, BufferImpl::g_backendBufferObjects[bufferObj]->GetBackendBufferId(),
|
if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) {
|
||||||
range.start, range.end - range.start);
|
const auto& backendBufferObject = backendBufferIt->second;
|
||||||
|
backendBufferObject->Bind(GL_UNIFORM_BUFFER);
|
||||||
|
if (range.end == 0) {
|
||||||
|
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding,
|
||||||
|
backendBufferObject->GetBackendBufferId());
|
||||||
|
} else {
|
||||||
|
MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding,
|
||||||
|
backendBufferObject->GetBackendBufferId(),
|
||||||
|
range.start, range.end - range.start);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,6 +397,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MG_External::GLES::glUseProgram(0);
|
MG_External::GLES::glUseProgram(0);
|
||||||
|
MGLOG_E("No backend program found (maybe not synced) for current program, cannot use program.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,12 +530,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!stateProgramObject->GetLinkStatus()) {
|
if (!stateProgramObject->GetLinkStatus()) {
|
||||||
MGLOG_E("Program object is not linked, skipping backend sync. Program: %p", stateProgramObject.get());
|
MGLOG_E("Program object is not linked, skipping backend sync. State program ID: %u",
|
||||||
|
stateProgramObject->GetExternalIndex());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MGLOG_D("Syncing program to backend. State program: %p, Backend ID: %p", stateProgramObject.get(),
|
MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u",
|
||||||
m_backendProgramId);
|
stateProgramObject->GetExternalIndex(), m_backendProgramId);
|
||||||
|
|
||||||
// Detach all existing shaders
|
// Detach all existing shaders
|
||||||
GLint attachedCount = 0;
|
GLint attachedCount = 0;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`shader` is not a value generated by OpenGL."));
|
std::to_string(shader) + " is not a valid name."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -25,7 +25,8 @@ namespace MobileGL {
|
|||||||
if (!shaderObject) {
|
if (!shaderObject) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`shader` is not a shader object."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(shader) + " is not a shader object."));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return shaderObject;
|
return shaderObject;
|
||||||
@@ -36,7 +37,7 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`program` is not a value generated by OpenGL"));
|
std::to_string(program) + " is not a valid name."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -49,7 +50,8 @@ namespace MobileGL {
|
|||||||
if (!programObject) {
|
if (!programObject) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(program) + " is not a program object."));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return programObject;
|
return programObject;
|
||||||
@@ -71,10 +73,11 @@ namespace MobileGL {
|
|||||||
auto shaderObject = TryToGetShaderObject(shader);
|
auto shaderObject = TryToGetShaderObject(shader);
|
||||||
if (!shaderObject) return;
|
if (!shaderObject) return;
|
||||||
if (!programObject->AttachShader(shaderObject)) {
|
if (!programObject->AttachShader(shaderObject)) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||||
ErrorCode::InvalidOperation,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
std::to_string(shader) +
|
||||||
"`shader` is already attached to `program`."));
|
" is already attached to " +
|
||||||
|
std::to_string(program) + "."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +87,8 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`index` is greater than or equal to `GL_MAX_VERTEX_ATTRIBS`."));
|
"index " + std::to_string(index) +
|
||||||
|
" is greater than or equal to `GL_MAX_VERTEX_ATTRIBS`."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +96,8 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`name` starts with the reserved prefix `gl_`."));
|
"name " + std::string(name) +
|
||||||
|
" starts with the reserved prefix `gl_`."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +159,8 @@ namespace MobileGL {
|
|||||||
if (bufSize < 0) {
|
if (bufSize < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"bufSize " + std::to_string(bufSize) + " is less than 0."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
@@ -165,7 +171,9 @@ namespace MobileGL {
|
|||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>(
|
MakeShared<GenericErrorInfo>(
|
||||||
"MG_Impl/GLImpl", __func__,
|
"MG_Impl/GLImpl", __func__,
|
||||||
"`index` is greater than or equal to the number of active attribute variables in `program`."));
|
"index " + std::to_string(index) +
|
||||||
|
" is greater than or equal to the number of active attribute variables in " +
|
||||||
|
std::to_string(program) + "."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type != nullptr) *type = programObject->GetAttribType(index);
|
if (type != nullptr) *type = programObject->GetAttribType(index);
|
||||||
@@ -179,7 +187,8 @@ namespace MobileGL {
|
|||||||
if (bufSize < 0) {
|
if (bufSize < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"bufSize " + std::to_string(bufSize) + " is less than 0."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
@@ -190,7 +199,9 @@ namespace MobileGL {
|
|||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>(
|
MakeShared<GenericErrorInfo>(
|
||||||
"MG_Impl/GLImpl", __func__,
|
"MG_Impl/GLImpl", __func__,
|
||||||
"`index` is greater than or equal to the number of active uniform variables in `program`."));
|
"index " + std::to_string(index) +
|
||||||
|
" is greater than or equal to the number of active uniform variables in " +
|
||||||
|
std::to_string(program) + "."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +215,8 @@ namespace MobileGL {
|
|||||||
if (maxCount < 0) {
|
if (maxCount < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`maxCount` is less than 0."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"maxCount " + std::to_string(maxCount) + " is less than 0."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
@@ -296,7 +308,8 @@ namespace MobileGL {
|
|||||||
MGLOG_D("%s: %s", __func__, MG_Util::ConvertGLEnumToString(pname).c_str());
|
MGLOG_D("%s: %s", __func__, MG_Util::ConvertGLEnumToString(pname).c_str());
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidEnum,
|
ErrorCode::InvalidEnum,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"pname " + std::to_string(pname) + " is not an accepted value."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,7 +345,8 @@ namespace MobileGL {
|
|||||||
default:
|
default:
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidEnum,
|
ErrorCode::InvalidEnum,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"pname " + std::to_string(pname) + " is not an accepted value."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,7 +363,8 @@ namespace MobileGL {
|
|||||||
if (bufSize < 0) {
|
if (bufSize < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"bufSize " + std::to_string(bufSize) + " is less than 0."));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shaderObject = TryToGetShaderObject(shader);
|
auto shaderObject = TryToGetShaderObject(shader);
|
||||||
@@ -375,7 +390,7 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`program` has not been successfully linked."));
|
std::to_string(program) + " has not been successfully linked."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,8 +399,9 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` does not correspond to a valid uniform variable location "
|
"location " + std::to_string(location) +
|
||||||
"for the specified program object."));
|
" does not correspond to a valid uniform variable location "
|
||||||
|
"for the specified program object."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,8 +411,9 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` does not correspond to a valid uniform variable location "
|
"location " + std::to_string(location) +
|
||||||
"for the specified program object."));
|
" does not correspond to a valid uniform variable location "
|
||||||
|
"for the specified program object."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +463,8 @@ namespace MobileGL {
|
|||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`count` is less than 0."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"count " + std::to_string(count) + " is less than 0."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,8 +522,10 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` is an invalid uniform location for the current program "
|
"location " + std::to_string(location) +
|
||||||
"object and `location` is not equal to -1."));
|
" is an invalid uniform location for the current program "
|
||||||
|
"object and location " +
|
||||||
|
std::to_string(location) + " is not equal to -1."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,8 +651,10 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` is an invalid uniform location for the current program "
|
"location " + std::to_string(location) +
|
||||||
"object and `location` is not equal to -1."));
|
" is an invalid uniform location for the current program "
|
||||||
|
"object and location " +
|
||||||
|
std::to_string(location) + " is not equal to -1."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,8 +689,10 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` is an invalid uniform location for the current program "
|
"location " + std::to_string(location) +
|
||||||
"object and `location` is not equal to -1."));
|
" is an invalid uniform location for the current program "
|
||||||
|
"object and location " +
|
||||||
|
std::to_string(location) + " is not equal to -1."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,8 +727,10 @@ namespace MobileGL {
|
|||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`location` is an invalid uniform location for the current program "
|
"location " + std::to_string(location) +
|
||||||
"object and `location` is not equal to -1."));
|
" is an invalid uniform location for the current program "
|
||||||
|
"object and location " +
|
||||||
|
std::to_string(location) + " is not equal to -1."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,133 +749,147 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLuint GetUniformBlockIndex_State(GLuint program, const GLchar* uniformBlockName) {
|
GLuint GetUniformBlockIndex_State(GLuint program, const GLchar* uniformBlockName) {
|
||||||
auto programObject = TryToGetProgramObject(program);
|
const auto& programObject = TryToGetProgramObject(program);
|
||||||
if (!programObject) return GL_INVALID_INDEX;
|
if (!programObject) return GL_INVALID_INDEX;
|
||||||
if (!programObject->GetLinkStatus()) {
|
if (!programObject->GetLinkStatus()) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(program) +
|
||||||
|
" is not a program object that has been linked."));
|
||||||
return GL_INVALID_INDEX;
|
return GL_INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& index = programObject->GetUniformBlockIndex(uniformBlockName);
|
||||||
auto index = programObject->GetUniformBlockIndex(uniformBlockName);
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBlockBinding_State(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
|
void UniformBlockBinding_State(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
|
||||||
auto programObject = MG_State::pGLContext->GetCurrentProgram();
|
const auto& programObject = TryToGetProgramObject(program);
|
||||||
if (programObject == nullptr) {
|
|
||||||
MG_State::pGLContext->RecordError(
|
|
||||||
ErrorCode::InvalidOperation,
|
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "There is no current program object."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!programObject->GetLinkStatus()) {
|
if (!programObject->GetLinkStatus()) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||||
ErrorCode::InvalidOperation,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
|
"Program object" +
|
||||||
|
std::to_string(program) +
|
||||||
|
" that has been linked."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
|
MakeShared<GenericErrorInfo>(
|
||||||
|
"MG_Impl/GLImpl", __func__,
|
||||||
|
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
|
||||||
|
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
|
||||||
|
"not the index of an active uniform block in program" +
|
||||||
|
std::to_string(program) + "."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
programObject->SetUniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
|
programObject->SetUniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetActiveUniformBlockiv_State(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
|
void GetActiveUniformBlockiv_State(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
|
||||||
auto programObject = MG_State::pGLContext->GetCurrentProgram();
|
const auto& programObject = TryToGetProgramObject(program);
|
||||||
if (programObject == nullptr) {
|
|
||||||
MG_State::pGLContext->RecordError(
|
|
||||||
ErrorCode::InvalidOperation,
|
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "There is no current program object."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!programObject->GetLinkStatus()) {
|
if (!programObject->GetLinkStatus()) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||||
ErrorCode::InvalidOperation,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
|
"Program object" +
|
||||||
|
std::to_string(program) +
|
||||||
|
" that has been linked."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
|
MakeShared<GenericErrorInfo>(
|
||||||
|
"MG_Impl/GLImpl", __func__,
|
||||||
|
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
|
||||||
|
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
|
||||||
|
"not the index of an active uniform block in program" +
|
||||||
|
std::to_string(program) + "."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_UNIFORM_BLOCK_DATA_SIZE: {
|
case GL_UNIFORM_BLOCK_DATA_SIZE: {
|
||||||
*params = programObject->GetUBOSizeAt(uniformBlockIndex);
|
*params = programObject->GetUBOSizeAt(uniformBlockIndex);
|
||||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_DATA_SIZE = %d", __func__, *params);
|
MGLOG_D("%s: GL_UNIFORM_BLOCK_DATA_SIZE = %d", __func__, *params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_UNIFORM_BLOCK_NAME_LENGTH: {
|
case GL_UNIFORM_BLOCK_NAME_LENGTH: {
|
||||||
*params = programObject->GetUniformBlockName(uniformBlockIndex).length() + 1;
|
*params = programObject->GetUniformBlockName(uniformBlockIndex).length() + 1;
|
||||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_NAME_LENGTH = %d", __func__, *params);
|
MGLOG_D("%s: GL_UNIFORM_BLOCK_NAME_LENGTH = %d", __func__, *params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
|
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
|
||||||
// TODO: deduct global ubo?
|
// TODO: deduct global ubo?
|
||||||
*params = programObject->GetActiveUniformBlocksCount();
|
*params = programObject->GetActiveUniformBlocksCount();
|
||||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
|
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_UNIFORM_BLOCK_BINDING: {
|
case GL_UNIFORM_BLOCK_BINDING: {
|
||||||
// TODO
|
// TODO
|
||||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = <TODO>", __func__, *params);
|
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = <TODO>", __func__, *params);
|
||||||
}
|
}
|
||||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
|
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
|
||||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
|
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
|
||||||
default:
|
default:
|
||||||
MGLOG_E("%s: unknown pname = %p %s", __func__, pname, MG_Util::ConvertGLEnumToString(pname).c_str());
|
MGLOG_E("%s: unknown pname = %p %s", __func__, pname, MG_Util::ConvertGLEnumToString(pname).c_str());
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidEnum,
|
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not one of the accepted tokens."));
|
"pname " + std::to_string(pname) +
|
||||||
break;
|
" is not one of the accepted tokens."));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetActiveUniformBlockName_State(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
|
void GetActiveUniformBlockName_State(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
|
||||||
|
GLchar* uniformBlockName) {
|
||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
if (!programObject) return;
|
if (!programObject) return;
|
||||||
if (!programObject->GetLinkStatus()) {
|
if (!programObject->GetLinkStatus()) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(program) +
|
||||||
|
" is not a program object that has been linked."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidValue,
|
ErrorCode::InvalidValue,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
|
MakeShared<GenericErrorInfo>(
|
||||||
|
"MG_Impl/GLImpl", __func__,
|
||||||
|
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
|
||||||
|
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
|
||||||
|
"not the index of an active uniform block in program."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto& name = programObject->GetUniformBlockName(uniformBlockIndex);
|
const auto& name = programObject->GetUniformBlockName(uniformBlockIndex);
|
||||||
CopyStr(bufSize, length, uniformBlockName, name.c_str(), name.length());
|
CopyStr(bufSize, length, uniformBlockName, name.c_str(), name.length());
|
||||||
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex, *length);
|
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex,
|
||||||
|
*length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindFragDataLocation_State(GLuint program, GLuint colorNumber, const char* name) {
|
void BindFragDataLocation_State(GLuint program, GLuint colorNumber, const char* name) {
|
||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
if (programObject == nullptr) {
|
if (programObject == nullptr) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not the name of a program object."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(program) + " is not the name of a program object."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strncmp(name, "gl_", 3) == 0) {
|
if (strncmp(name, "gl_", 3) == 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
"`name` starts with the reserved prefix `gl_`."));
|
"name " + std::string(name) +
|
||||||
|
" starts with the reserved prefix `gl_`."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: Emit error "if `colorNumber` is greater than or equal to `GL_MAX_DRAW_BUFFERS`"
|
// TODO: Emit error "if `colorNumber` is greater than or equal to `GL_MAX_DRAW_BUFFERS`"
|
||||||
@@ -862,16 +902,16 @@ namespace MobileGL {
|
|||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
if (programObject == nullptr) {
|
if (programObject == nullptr) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidOperation,
|
ErrorCode::InvalidOperation,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not the name of a program object."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::to_string(program) + " is not the name of a program object."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return programObject->GetFragmentDataLocation(name);
|
return programObject->GetFragmentDataLocation(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ValidateProgram_State(GLuint program) {
|
void ValidateProgram_State(GLuint program) {
|
||||||
// THROW_UNIMPL_EXCEPTION;
|
// THROW_UNIMPL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachShader(GLuint program, GLuint shader) {
|
void AttachShader(GLuint program, GLuint shader) {
|
||||||
@@ -1068,7 +1108,8 @@ namespace MobileGL {
|
|||||||
GetActiveUniformBlockiv_State(program, uniformBlockIndex, pname, params);
|
GetActiveUniformBlockiv_State(program, uniformBlockIndex, pname, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
|
void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
|
||||||
|
GLchar* uniformBlockName) {
|
||||||
GetActiveUniformBlockName_State(program, uniformBlockIndex, bufSize, length, uniformBlockName);
|
GetActiveUniformBlockName_State(program, uniformBlockIndex, bufSize, length, uniformBlockName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user