mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_State/BufferState, VertexArrayState): Correct IBO binding slot.
This commit is contained in:
@@ -384,13 +384,6 @@ namespace MobileGL {
|
||||
|
||||
auto& bindingSlot = MG_State::pGLContext->GetBufferBindingSlot(bufferTarget);
|
||||
bindingSlot.Bind(bufferObject);
|
||||
|
||||
if (bufferTarget == BufferTarget::Index) {
|
||||
auto currentVAO = MG_State::pGLContext->GetBoundVertexArray();
|
||||
if (currentVAO) {
|
||||
currentVAO->BindElementBuffer(bufferObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenBuffers_State(GLsizei n, GLuint* buffers) {
|
||||
|
||||
@@ -3,17 +3,25 @@
|
||||
namespace MobileGL::MG_Impl::GLImpl {
|
||||
namespace BufferImpl {
|
||||
bool ValidateBufferTarget(BufferTarget target) {
|
||||
if (target != BufferTarget::Unknown)
|
||||
return true;
|
||||
if (target == BufferTarget::Unknown) {
|
||||
using namespace MG_Util;
|
||||
String bufferTargetStr = ConvertBufferTargetToString(target);
|
||||
String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
|
||||
std::format("Target {} ({}) is not valid.",
|
||||
bufferTargetStr, glTargetStr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target == BufferTarget::Index && MG_State::pGLContext->GetBoundVertexArray() == nullptr) {
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
|
||||
"No vertex array object is bound."));
|
||||
return false;
|
||||
}
|
||||
|
||||
using namespace MG_Util;
|
||||
String bufferTargetStr = ConvertBufferTargetToString(target);
|
||||
String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
|
||||
std::format("Target {} ({}) is not valid.",
|
||||
bufferTargetStr, glTargetStr)));
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateBufferName(Uint index) {
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
|
||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayName",
|
||||
std::format("Vertex array name {} is not valid.", index)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace MobileGL {
|
||||
namespace GLState {
|
||||
BufferState::BufferState()
|
||||
: m_indexGenerator(1024, 1) {
|
||||
for (SizeT i = 0; i < (SizeT)BufferTarget::BufferTargetCount; ++i) {
|
||||
m_bindingSlots[i] = BindingSlot<BufferObject>((BufferTarget)i);
|
||||
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
|
||||
m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,18 @@ namespace MobileGL {
|
||||
}
|
||||
|
||||
BindingSlot<BufferObject>& BufferState::GetBindingSlot(BufferTarget target) {
|
||||
return m_bindingSlots[(SizeT)target];
|
||||
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
|
||||
if (m_bindingSlots[i].GetTarget() == target) {
|
||||
return m_bindingSlots[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BufferState::MarkBufferObjectForDeletion(Uint index) {
|
||||
if (m_indexGenerator.IsValid(index)) {
|
||||
auto it = m_bufferObjects.find(index);
|
||||
if (it != m_bufferObjects.end()) {
|
||||
for (SizeT i = 0; i < (SizeT)BufferTarget::BufferTargetCount; ++i) {
|
||||
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
|
||||
if (m_bindingSlots[i].GetBoundObject() == it->second) {
|
||||
m_bindingSlots[i].Bind(nullptr);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,21 @@
|
||||
namespace MobileGL {
|
||||
namespace MG_State {
|
||||
namespace GLState {
|
||||
constexpr const auto GlobalBufferTargets = ToArray(
|
||||
BufferTarget::Vertex,
|
||||
BufferTarget::Uniform,
|
||||
BufferTarget::CopyRead,
|
||||
BufferTarget::CopyWrite,
|
||||
BufferTarget::PixelPack,
|
||||
BufferTarget::PixelUnpack,
|
||||
BufferTarget::Query,
|
||||
BufferTarget::Texture,
|
||||
BufferTarget::TransformFeedback,
|
||||
BufferTarget::AtomicCounter,
|
||||
BufferTarget::DispatchIndirect,
|
||||
BufferTarget::DrawIndirect,
|
||||
BufferTarget::ShaderStorage);
|
||||
|
||||
class BufferState {
|
||||
public:
|
||||
BufferState();
|
||||
@@ -18,7 +33,7 @@ namespace MobileGL {
|
||||
private:
|
||||
UnorderedMap<Uint, SharedPtr<BufferObject>> m_bufferObjects;
|
||||
IndexGenerator<Uint> m_indexGenerator;
|
||||
Array<BindingSlot<BufferObject>, (SizeT)BufferTarget::BufferTargetCount> m_bindingSlots;
|
||||
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ namespace MobileGL {
|
||||
}
|
||||
|
||||
BindingSlot<BufferObject>& GLContext::GetBufferBindingSlot(BufferTarget target) {
|
||||
if (target == BufferTarget::Index) {
|
||||
return m_vertexArrayState.GetBoundVertexArray()->GetIndexBufferBindingSlot();
|
||||
}
|
||||
|
||||
return m_bufferState.GetBindingSlot(target);
|
||||
}
|
||||
|
||||
@@ -54,6 +58,21 @@ namespace MobileGL {
|
||||
}
|
||||
|
||||
void GLContext::MarkBufferObjectForDeletion(Uint index) {
|
||||
if (ValidateBufferObject(index)) {
|
||||
auto bufferObject = m_bufferState.GetBufferObject(index);
|
||||
for (SizeT i = 0; i < m_vertexArrayState.GetAllVertexArrays().size(); ++i) {
|
||||
auto vao = m_vertexArrayState.GetAllVertexArrays()[i];
|
||||
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
|
||||
vao->GetIndexBufferBindingSlot().Bind(nullptr);
|
||||
}
|
||||
for (SizeT j = 0; j < VertexArrayObject::MAX_VERTEX_ATTRIBS; ++j) {
|
||||
if (vao->GetAttribute(j).Buffer == bufferObject) {
|
||||
vao->BindAttributeBuffer(j, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_bufferState.MarkBufferObjectForDeletion(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,12 +53,8 @@ namespace MobileGL {
|
||||
m_attributes[index].Buffer = buffer;
|
||||
}
|
||||
|
||||
void VertexArrayObject::BindElementBuffer(const SharedPtr<BufferObject>& buffer) {
|
||||
m_elementBuffer = buffer;
|
||||
}
|
||||
|
||||
SharedPtr<BufferObject> VertexArrayObject::GetElementBuffer() const {
|
||||
return m_elementBuffer;
|
||||
BindingSlot<BufferObject>& VertexArrayObject::GetIndexBufferBindingSlot() {
|
||||
return m_indexBufferBindingSlot;
|
||||
}
|
||||
|
||||
const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const {
|
||||
|
||||
@@ -28,14 +28,13 @@ namespace MobileGL {
|
||||
|
||||
void BindAttributeBuffer(Uint index, const SharedPtr<BufferObject>& buffer);
|
||||
|
||||
void BindElementBuffer(const SharedPtr<BufferObject>& buffer);
|
||||
SharedPtr<BufferObject> GetElementBuffer() const;
|
||||
BindingSlot<BufferObject>& GetIndexBufferBindingSlot();
|
||||
|
||||
const VertexAttribute& GetAttribute(Uint index) const;
|
||||
|
||||
private:
|
||||
Array<VertexAttribute, MAX_VERTEX_ATTRIBS> m_attributes;
|
||||
SharedPtr<BufferObject> m_elementBuffer;
|
||||
BindingSlot<BufferObject> m_indexBufferBindingSlot;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,15 @@ namespace MobileGL {
|
||||
SharedPtr<VertexArrayObject> VertexArrayState::GetBoundVertexArray() {
|
||||
return m_boundVertexArray;
|
||||
}
|
||||
|
||||
Vector<SharedPtr<VertexArrayObject>> VertexArrayState::GetAllVertexArrays() {
|
||||
Vector<SharedPtr<VertexArrayObject>> arrays;
|
||||
arrays.reserve(m_vertexArrays.size());
|
||||
for (const auto& pair : m_vertexArrays) {
|
||||
arrays.push_back(pair.second);
|
||||
}
|
||||
return arrays;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace MobileGL {
|
||||
bool ValidateName(Uint index) const;
|
||||
bool ValidateVertexArrayObject(Uint index) const;
|
||||
SharedPtr<VertexArrayObject> GetBoundVertexArray();
|
||||
Vector<SharedPtr<VertexArrayObject>> GetAllVertexArrays();
|
||||
|
||||
private:
|
||||
UnorderedMap<Uint, SharedPtr<VertexArrayObject>> m_vertexArrays;
|
||||
|
||||
@@ -15,7 +15,7 @@ protected:
|
||||
TEST_F(BufferTest, Binding) {
|
||||
auto bufferNames = glContext.GenBufferNames(3);
|
||||
auto& arraySlot = glContext.GetBufferBindingSlot(BufferTarget::Vertex);
|
||||
auto& indexSlot = glContext.GetBufferBindingSlot(BufferTarget::Index);
|
||||
auto& indexSlot = glContext.GetBufferBindingSlot(BufferTarget::Uniform);
|
||||
|
||||
auto obj0 = glContext.CreateBufferObject(bufferNames[0]);
|
||||
auto obj1 = glContext.CreateBufferObject(bufferNames[1]);
|
||||
@@ -73,7 +73,7 @@ TEST_F(BufferTest, GenerateManyNames_NoPrematureCreation) {
|
||||
for (SizeT idx : indices) {
|
||||
GLuint name = names[idx];
|
||||
auto bufObj = glContext.CreateBufferObject(name);
|
||||
auto& slot = glContext.GetBufferBindingSlot(BufferTarget::Index);
|
||||
auto& slot = glContext.GetBufferBindingSlot(BufferTarget::Uniform);
|
||||
slot.Bind(bufObj);
|
||||
|
||||
Vector<Int> data = { static_cast<Int>(idx + 1), static_cast<Int>(idx + 2) };
|
||||
@@ -483,12 +483,12 @@ TEST_F(GeneralBufferTest, General_GeneralTest_1) {
|
||||
const float vertexData[] = { 0.1f, 0.2f, 0.3f, 1.0f };
|
||||
BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexData), vertexData);
|
||||
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
BindBuffer(GL_UNIFORM_BUFFER, ibo);
|
||||
const uint16_t indexData[] = { 0, 1, 2, 3, 0 };
|
||||
BufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
|
||||
BufferData(GL_UNIFORM_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
|
||||
|
||||
const uint16_t newIndices[] = { 4, 5 };
|
||||
BufferSubData(GL_ELEMENT_ARRAY_BUFFER, 2 * sizeof(uint16_t),
|
||||
BufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(uint16_t),
|
||||
sizeof(newIndices), newIndices);
|
||||
|
||||
BindBuffer(GL_COPY_READ_BUFFER, staging);
|
||||
@@ -498,14 +498,14 @@ TEST_F(GeneralBufferTest, General_GeneralTest_1) {
|
||||
CopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER,
|
||||
0, 40, sizeof(stagingData));
|
||||
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
void* fullMap = MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE);
|
||||
BindBuffer(GL_UNIFORM_BUFFER, ibo);
|
||||
void* fullMap = MapBuffer(GL_UNIFORM_BUFFER, GL_READ_WRITE);
|
||||
ASSERT_NE(fullMap, nullptr);
|
||||
|
||||
uint16_t* indices = static_cast<uint16_t*>(fullMap);
|
||||
indices[0] = 10;
|
||||
|
||||
EXPECT_TRUE(UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
|
||||
EXPECT_TRUE(UnmapBuffer(GL_UNIFORM_BUFFER));
|
||||
|
||||
BindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
void* partialMap = MapBufferRange(GL_ARRAY_BUFFER, 20, 8,
|
||||
@@ -535,12 +535,12 @@ TEST_F(GeneralBufferTest, General_GeneralTest_1) {
|
||||
|
||||
EXPECT_TRUE(UnmapBuffer(GL_ARRAY_BUFFER));
|
||||
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
void* iboMap = MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
|
||||
BindBuffer(GL_UNIFORM_BUFFER, ibo);
|
||||
void* iboMap = MapBuffer(GL_UNIFORM_BUFFER, GL_READ_ONLY);
|
||||
const uint16_t* finalIndices = static_cast<const uint16_t*>(iboMap);
|
||||
EXPECT_EQ(finalIndices[0], 10);
|
||||
EXPECT_EQ(finalIndices[2], 4);
|
||||
EXPECT_TRUE(UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
|
||||
EXPECT_TRUE(UnmapBuffer(GL_UNIFORM_BUFFER));
|
||||
|
||||
DeleteBuffers(1, &staging);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ TEST_F(VertexArrayTest, VertexAttributeSetup) {
|
||||
ASSERT_FALSE(vao->IsAttributeEnabled(1));
|
||||
}
|
||||
|
||||
TEST_F(VertexArrayTest, ElementBufferBinding) {
|
||||
TEST_F(VertexArrayTest, IndexBufferBinding) {
|
||||
auto vaoNames = glContext.GenVertexArrayNames(1);
|
||||
auto vao = glContext.CreateVertexArrayObject(vaoNames[0]);
|
||||
glContext.BindVertexArray(vaoNames[0]);
|
||||
@@ -86,13 +86,13 @@ TEST_F(VertexArrayTest, ElementBufferBinding) {
|
||||
DataPtr ptr{ .data = indices.data(), .size = byteSize };
|
||||
ebo->UploadData(ptr, 0);
|
||||
|
||||
vao->BindElementBuffer(ebo);
|
||||
ASSERT_EQ(vao->GetElementBuffer(), ebo);
|
||||
glContext.GetBufferBindingSlot(BufferTarget::Index).Bind(ebo);
|
||||
ASSERT_EQ(glContext.GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(), ebo);
|
||||
|
||||
auto newEboNames = glContext.GenBufferNames(1);
|
||||
auto newEbo = glContext.CreateBufferObject(newEboNames[0]);
|
||||
vao->BindElementBuffer(newEbo);
|
||||
ASSERT_EQ(vao->GetElementBuffer(), newEbo);
|
||||
glContext.GetBufferBindingSlot(BufferTarget::Index).Bind(newEbo);
|
||||
ASSERT_EQ(glContext.GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(), newEbo);
|
||||
}
|
||||
|
||||
TEST_F(VertexArrayTest, DeleteVAO) {
|
||||
@@ -281,25 +281,18 @@ TEST_F(GeneralVertexArrayTest, General_VertexAttributeConfiguration) {
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
TEST_F(GeneralVertexArrayTest, General_ElementBufferBinding) {
|
||||
TEST_F(GeneralVertexArrayTest, General_IndexBufferBinding) {
|
||||
GLuint vao = CreateVAO();
|
||||
GLuint ebo = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 256);
|
||||
|
||||
auto vaoObj = MG_State::pGLContext->GetVertexArrayObject(vao);
|
||||
ASSERT_NE(vaoObj, nullptr);
|
||||
ASSERT_NE(vaoObj->GetElementBuffer(), nullptr);
|
||||
|
||||
|
||||
GLuint newEbo;
|
||||
GenBuffers(1, &newEbo);
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEbo);
|
||||
|
||||
EXPECT_EQ(vaoObj->GetElementBuffer(), MG_State::pGLContext->GetBufferObject(newEbo));
|
||||
|
||||
GLuint vao2 = CreateVAO();
|
||||
GLuint ebo2 = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 128);
|
||||
|
||||
auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2);
|
||||
EXPECT_NE(vaoObj->GetElementBuffer(), vaoObj2->GetElementBuffer());
|
||||
EXPECT_EQ(MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(), MG_State::pGLContext->GetBufferObject(newEbo));
|
||||
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
}
|
||||
@@ -394,17 +387,17 @@ TEST_F(GeneralVertexArrayTest, General_ComplexUsage) {
|
||||
EnableVertexAttribArray(2);
|
||||
|
||||
BindVertexArray(vao1);
|
||||
|
||||
auto vaoObj1 = MG_State::pGLContext->GetVertexArrayObject(vao1);
|
||||
EXPECT_TRUE(vaoObj1->IsAttributeEnabled(0));
|
||||
EXPECT_TRUE(vaoObj1->IsAttributeEnabled(1));
|
||||
EXPECT_FALSE(vaoObj1->IsAttributeEnabled(2));
|
||||
EXPECT_NE(vaoObj1->GetElementBuffer(), nullptr);
|
||||
EXPECT_NE(MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(), nullptr);
|
||||
|
||||
BindVertexArray(vao2);
|
||||
auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2);
|
||||
EXPECT_TRUE(vaoObj2->IsAttributeEnabled(2));
|
||||
EXPECT_FALSE(vaoObj2->IsAttributeEnabled(0));
|
||||
EXPECT_NE(vaoObj2->GetElementBuffer(), nullptr);
|
||||
EXPECT_NE(MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(), nullptr);
|
||||
|
||||
DeleteVertexArrays(1, &vao1);
|
||||
DeleteVertexArrays(1, &vao2);
|
||||
@@ -444,4 +437,68 @@ TEST_F(GeneralVertexArrayTest, General_DeleteBoundVAO) {
|
||||
EXPECT_EQ(GetError(), GL_INVALID_OPERATION);
|
||||
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(GeneralVertexArrayTest, General_ElementBufferBindingPoint) {
|
||||
GLuint vao1, vao2;
|
||||
GenVertexArrays(1, &vao1);
|
||||
GenVertexArrays(1, &vao2);
|
||||
|
||||
GLuint ebo1, ebo2;
|
||||
GenBuffers(1, &ebo1);
|
||||
GenBuffers(1, &ebo2);
|
||||
|
||||
BindVertexArray(vao1);
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo1);
|
||||
|
||||
BindVertexArray(vao2);
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo2);
|
||||
|
||||
auto vaoObj1 = MG_State::pGLContext->GetVertexArrayObject(vao1);
|
||||
auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2);
|
||||
EXPECT_EQ(vaoObj1->GetIndexBufferBindingSlot().GetBoundObject(), MG_State::pGLContext->GetBufferObject(ebo1));
|
||||
EXPECT_EQ(vaoObj2->GetIndexBufferBindingSlot().GetBoundObject(), MG_State::pGLContext->GetBufferObject(ebo2));
|
||||
|
||||
BindVertexArray(vao1);
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo2);
|
||||
|
||||
EXPECT_EQ(MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(),
|
||||
MG_State::pGLContext->GetBufferObject(ebo2));
|
||||
|
||||
BindVertexArray(vao2);
|
||||
EXPECT_EQ(MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(),
|
||||
MG_State::pGLContext->GetBufferObject(ebo2));
|
||||
|
||||
BindVertexArray(0);
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo1);
|
||||
|
||||
EXPECT_EQ(GetError(), GL_INVALID_OPERATION);
|
||||
|
||||
BindVertexArray(vao1);
|
||||
DeleteVertexArrays(1, &vao1);
|
||||
|
||||
BindVertexArray(vao1);
|
||||
EXPECT_EQ(GetError(), GL_INVALID_OPERATION);
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
|
||||
EXPECT_EQ(MG_State::pGLContext->GetVertexArrayObject(vao1).get(), nullptr);
|
||||
|
||||
BindVertexArray(vao2);
|
||||
DeleteBuffers(1, &ebo2);
|
||||
|
||||
EXPECT_EQ(vaoObj2->GetIndexBufferBindingSlot().GetBoundObject().get(), nullptr);
|
||||
|
||||
GLuint ebo3;
|
||||
GenBuffers(1, &ebo3);
|
||||
BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo3);
|
||||
|
||||
EXPECT_EQ(vaoObj2->GetIndexBufferBindingSlot().GetBoundObject(), MG_State::pGLContext->GetBufferObject(ebo3));
|
||||
|
||||
DeleteVertexArrays(1, &vao2);
|
||||
DeleteBuffers(1, &ebo1);
|
||||
DeleteBuffers(1, &ebo3);
|
||||
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace MobileGL {
|
||||
inline constexpr void Copy(const T* src, T* dest, SizeT count) {
|
||||
std::copy(src, src + count, dest);
|
||||
}
|
||||
template<typename... Ts>
|
||||
constexpr auto ToArray(Ts&&... elems) {
|
||||
using E = std::common_type_t<Ts...>;
|
||||
return std::array<E, sizeof...(Ts)>{ { std::forward<Ts>(elems)... } };
|
||||
}
|
||||
class RuntimeError : public std::runtime_error {
|
||||
public:
|
||||
using std::runtime_error::runtime_error;
|
||||
|
||||
Reference in New Issue
Block a user