gl_state: Remove VAO cache and tracking
This commit is contained in:
parent
2a662fea36
commit
d5ab0358b6
|
@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
|
||||||
state.draw.shader_program = 0;
|
state.draw.shader_program = 0;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
|
|
||||||
CheckExtensions();
|
CheckExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint RasterizerOpenGL::SetupVertexFormat() {
|
void RasterizerOpenGL::SetupVertexFormat() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_VAO);
|
MICROPROFILE_SCOPE(OpenGL_VAO);
|
||||||
|
|
||||||
auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
|
// Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. Enables
|
||||||
auto& vao_entry = iter->second;
|
// the first 16 vertex attributes always, as we don't know which ones are actually used until
|
||||||
|
// shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now to
|
||||||
if (is_cache_miss) {
|
// avoid OpenGL errors.
|
||||||
vao_entry.Create();
|
|
||||||
const GLuint vao = vao_entry.handle;
|
|
||||||
|
|
||||||
// Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob
|
|
||||||
// that fails to properly create the vertex array if it's not bound even after creating it
|
|
||||||
// with glCreateVertexArrays
|
|
||||||
state.draw.vertex_array = vao;
|
|
||||||
state.ApplyVertexArrayState();
|
|
||||||
|
|
||||||
// Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
|
|
||||||
// Enables the first 16 vertex attributes always, as we don't know which ones are actually
|
|
||||||
// used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
|
|
||||||
// for now to avoid OpenGL errors.
|
|
||||||
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
|
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
|
||||||
// assume every shader uses them all.
|
// assume every shader uses them all.
|
||||||
for (u32 index = 0; index < 16; ++index) {
|
for (u32 index = 0; index < 16; ++index) {
|
||||||
const auto& attrib = regs.vertex_attrib_format[index];
|
const auto& attrib = regs.vertex_attrib_format[index];
|
||||||
|
|
||||||
// Ignore invalid attributes.
|
// Ignore invalid attributes.
|
||||||
if (!attrib.IsValid())
|
if (!attrib.IsValid()) {
|
||||||
|
glDisableVertexAttribArray(index);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
glEnableVertexAttribArray(index);
|
||||||
|
|
||||||
const auto& buffer = regs.vertex_array[attrib.buffer];
|
if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
|
||||||
LOG_TRACE(Render_OpenGL,
|
attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
|
||||||
"vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
|
glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
||||||
index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
|
attrib.offset);
|
||||||
attrib.offset.Value(), attrib.IsNormalized());
|
|
||||||
|
|
||||||
ASSERT(buffer.IsEnabled());
|
|
||||||
|
|
||||||
glEnableVertexArrayAttrib(vao, index);
|
|
||||||
if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
|
|
||||||
attrib.type ==
|
|
||||||
Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
|
|
||||||
glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
|
|
||||||
MaxwellToGL::VertexType(attrib), attrib.offset);
|
|
||||||
} else {
|
} else {
|
||||||
glVertexArrayAttribFormat(
|
glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
||||||
vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
|
||||||
attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
|
attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
|
||||||
}
|
}
|
||||||
glVertexArrayAttribBinding(vao, index, attrib.buffer);
|
glVertexAttribBinding(index, attrib.buffer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
state.draw.vertex_array = vao_entry.handle;
|
|
||||||
return vao_entry.handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
|
void RasterizerOpenGL::SetupVertexBuffer() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
|
@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
|
||||||
// Upload all guest vertex arrays sequentially to our buffer
|
// Upload all guest vertex arrays sequentially to our buffer
|
||||||
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||||
const auto& vertex_array = regs.vertex_array[index];
|
const auto& vertex_array = regs.vertex_array[index];
|
||||||
if (!vertex_array.IsEnabled())
|
if (!vertex_array.IsEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const GPUVAddr start = vertex_array.StartAddress();
|
const GPUVAddr start = vertex_array.StartAddress();
|
||||||
const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
|
const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
|
||||||
|
@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
|
||||||
|
|
||||||
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
|
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
|
||||||
// Enable vertex buffer instancing with the specified divisor.
|
// Enable vertex buffer instancing with the specified divisor.
|
||||||
glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
|
glVertexBindingDivisor(index, vertex_array.divisor);
|
||||||
} else {
|
} else {
|
||||||
// Disable the vertex buffer instancing.
|
// Disable the vertex buffer instancing.
|
||||||
glVertexArrayBindingDivisor(vao, index, 0);
|
glVertexBindingDivisor(index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
|
void RasterizerOpenGL::SetupVertexInstances() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
|
@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
|
||||||
if (regs.instanced_arrays.IsInstancingEnabled(index) &&
|
if (regs.instanced_arrays.IsInstancingEnabled(index) &&
|
||||||
regs.vertex_array[index].divisor != 0) {
|
regs.vertex_array[index].divisor != 0) {
|
||||||
// Enable vertex buffer instancing with the specified divisor.
|
// Enable vertex buffer instancing with the specified divisor.
|
||||||
glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor);
|
glVertexBindingDivisor(index, regs.vertex_array[index].divisor);
|
||||||
} else {
|
} else {
|
||||||
// Disable the vertex buffer instancing.
|
// Disable the vertex buffer instancing.
|
||||||
glVertexArrayBindingDivisor(vao, index, 0);
|
glVertexBindingDivisor(index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
buffer_cache.Map(buffer_size);
|
buffer_cache.Map(buffer_size);
|
||||||
|
|
||||||
// Prepare vertex array format.
|
// Prepare vertex array format.
|
||||||
const GLuint vao = SetupVertexFormat();
|
SetupVertexFormat();
|
||||||
vertex_array_pushbuffer.Setup(vao);
|
vertex_array_pushbuffer.Setup();
|
||||||
|
|
||||||
// Upload vertex and index data.
|
// Upload vertex and index data.
|
||||||
SetupVertexBuffer(vao);
|
SetupVertexBuffer();
|
||||||
SetupVertexInstances(vao);
|
SetupVertexInstances();
|
||||||
|
|
||||||
GLintptr index_buffer_offset;
|
GLintptr index_buffer_offset;
|
||||||
if (is_indexed) {
|
if (is_indexed) {
|
||||||
index_buffer_offset = SetupIndexBuffer();
|
index_buffer_offset = SetupIndexBuffer();
|
||||||
|
|
|
@ -194,11 +194,11 @@ private:
|
||||||
|
|
||||||
std::size_t CalculateIndexBufferSize() const;
|
std::size_t CalculateIndexBufferSize() const;
|
||||||
|
|
||||||
/// Updates and returns a vertex array object representing current vertex format
|
/// Updates the current vertex format
|
||||||
GLuint SetupVertexFormat();
|
void SetupVertexFormat();
|
||||||
|
|
||||||
void SetupVertexBuffer(GLuint vao);
|
void SetupVertexBuffer();
|
||||||
void SetupVertexInstances(GLuint vao);
|
void SetupVertexInstances();
|
||||||
|
|
||||||
GLintptr SetupIndexBuffer();
|
GLintptr SetupIndexBuffer();
|
||||||
|
|
||||||
|
@ -217,10 +217,6 @@ private:
|
||||||
ScreenInfo& screen_info;
|
ScreenInfo& screen_info;
|
||||||
|
|
||||||
std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
|
std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
|
||||||
std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute,
|
|
||||||
Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>,
|
|
||||||
OGLVertexArray>
|
|
||||||
vertex_array_cache;
|
|
||||||
|
|
||||||
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
||||||
OGLBufferCache buffer_cache;
|
OGLBufferCache buffer_cache;
|
||||||
|
|
|
@ -189,24 +189,6 @@ void OGLSync::Release() {
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLVertexArray::Create() {
|
|
||||||
if (handle != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
|
|
||||||
glCreateVertexArrays(1, &handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLVertexArray::Release() {
|
|
||||||
if (handle == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
|
|
||||||
glDeleteVertexArrays(1, &handle);
|
|
||||||
OpenGLState::GetCurState().ResetVertexArray(handle).Apply();
|
|
||||||
handle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLFramebuffer::Create() {
|
void OGLFramebuffer::Create() {
|
||||||
if (handle != 0)
|
if (handle != 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -241,31 +241,6 @@ public:
|
||||||
GLsync handle = 0;
|
GLsync handle = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OGLVertexArray : private NonCopyable {
|
|
||||||
public:
|
|
||||||
OGLVertexArray() = default;
|
|
||||||
|
|
||||||
OGLVertexArray(OGLVertexArray&& o) noexcept : handle(std::exchange(o.handle, 0)) {}
|
|
||||||
|
|
||||||
~OGLVertexArray() {
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
OGLVertexArray& operator=(OGLVertexArray&& o) noexcept {
|
|
||||||
Release();
|
|
||||||
handle = std::exchange(o.handle, 0);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
|
||||||
void Create();
|
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
|
||||||
void Release();
|
|
||||||
|
|
||||||
GLuint handle = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OGLFramebuffer : private NonCopyable {
|
class OGLFramebuffer : private NonCopyable {
|
||||||
public:
|
public:
|
||||||
OGLFramebuffer() = default;
|
OGLFramebuffer() = default;
|
||||||
|
|
|
@ -98,12 +98,6 @@ void OpenGLState::ApplyFramebufferState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ApplyVertexArrayState() {
|
|
||||||
if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) {
|
|
||||||
glBindVertexArray(draw.vertex_array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLState::ApplyShaderProgram() {
|
void OpenGLState::ApplyShaderProgram() {
|
||||||
if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
|
if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
|
||||||
glUseProgram(draw.shader_program);
|
glUseProgram(draw.shader_program);
|
||||||
|
@ -338,7 +332,6 @@ void OpenGLState::ApplyImages() {
|
||||||
void OpenGLState::Apply() {
|
void OpenGLState::Apply() {
|
||||||
MICROPROFILE_SCOPE(OpenGL_State);
|
MICROPROFILE_SCOPE(OpenGL_State);
|
||||||
ApplyFramebufferState();
|
ApplyFramebufferState();
|
||||||
ApplyVertexArrayState();
|
|
||||||
ApplyShaderProgram();
|
ApplyShaderProgram();
|
||||||
ApplyProgramPipeline();
|
ApplyProgramPipeline();
|
||||||
ApplyClipDistances();
|
ApplyClipDistances();
|
||||||
|
@ -411,13 +404,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) {
|
|
||||||
if (draw.vertex_array == handle) {
|
|
||||||
draw.vertex_array = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
|
OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
|
||||||
if (draw.read_framebuffer == handle) {
|
if (draw.read_framebuffer == handle) {
|
||||||
draw.read_framebuffer = 0;
|
draw.read_framebuffer = 0;
|
||||||
|
|
|
@ -74,7 +74,6 @@ public:
|
||||||
struct {
|
struct {
|
||||||
GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
|
GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
|
||||||
GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
|
GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
|
||||||
GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING
|
|
||||||
GLuint shader_program = 0; // GL_CURRENT_PROGRAM
|
GLuint shader_program = 0; // GL_CURRENT_PROGRAM
|
||||||
GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
|
GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
|
||||||
} draw;
|
} draw;
|
||||||
|
@ -117,7 +116,6 @@ public:
|
||||||
void Apply();
|
void Apply();
|
||||||
|
|
||||||
void ApplyFramebufferState();
|
void ApplyFramebufferState();
|
||||||
void ApplyVertexArrayState();
|
|
||||||
void ApplyShaderProgram();
|
void ApplyShaderProgram();
|
||||||
void ApplyProgramPipeline();
|
void ApplyProgramPipeline();
|
||||||
void ApplyClipDistances();
|
void ApplyClipDistances();
|
||||||
|
@ -142,7 +140,6 @@ public:
|
||||||
OpenGLState& ResetSampler(GLuint handle);
|
OpenGLState& ResetSampler(GLuint handle);
|
||||||
OpenGLState& ResetProgram(GLuint handle);
|
OpenGLState& ResetProgram(GLuint handle);
|
||||||
OpenGLState& ResetPipeline(GLuint handle);
|
OpenGLState& ResetPipeline(GLuint handle);
|
||||||
OpenGLState& ResetVertexArray(GLuint handle);
|
|
||||||
OpenGLState& ResetFramebuffer(GLuint handle);
|
OpenGLState& ResetFramebuffer(GLuint handle);
|
||||||
OpenGLState& ResetRenderbuffer(GLuint handle);
|
OpenGLState& ResetRenderbuffer(GLuint handle);
|
||||||
|
|
||||||
|
|
|
@ -441,22 +441,8 @@ void RendererOpenGL::InitOpenGLObjects() {
|
||||||
// Generate VBO handle for drawing
|
// Generate VBO handle for drawing
|
||||||
vertex_buffer.Create();
|
vertex_buffer.Create();
|
||||||
|
|
||||||
// Generate VAO
|
|
||||||
vertex_array.Create();
|
|
||||||
state.draw.vertex_array = vertex_array.handle;
|
|
||||||
|
|
||||||
// Attach vertex data to VAO
|
// Attach vertex data to VAO
|
||||||
glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
|
glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
|
||||||
glVertexArrayAttribFormat(vertex_array.handle, PositionLocation, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
offsetof(ScreenRectVertex, position));
|
|
||||||
glVertexArrayAttribFormat(vertex_array.handle, TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
offsetof(ScreenRectVertex, tex_coord));
|
|
||||||
glVertexArrayAttribBinding(vertex_array.handle, PositionLocation, 0);
|
|
||||||
glVertexArrayAttribBinding(vertex_array.handle, TexCoordLocation, 0);
|
|
||||||
glEnableVertexArrayAttrib(vertex_array.handle, PositionLocation);
|
|
||||||
glEnableVertexArrayAttrib(vertex_array.handle, TexCoordLocation);
|
|
||||||
glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0,
|
|
||||||
sizeof(ScreenRectVertex));
|
|
||||||
|
|
||||||
// Allocate textures for the screen
|
// Allocate textures for the screen
|
||||||
screen_info.texture.resource.Create(GL_TEXTURE_2D);
|
screen_info.texture.resource.Create(GL_TEXTURE_2D);
|
||||||
|
@ -581,6 +567,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
|
|
||||||
|
glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
|
||||||
|
offsetof(ScreenRectVertex, position));
|
||||||
|
glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
|
||||||
|
offsetof(ScreenRectVertex, tex_coord));
|
||||||
|
glVertexAttribBinding(PositionLocation, 0);
|
||||||
|
glVertexAttribBinding(TexCoordLocation, 0);
|
||||||
|
glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
|
||||||
|
|
||||||
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
// Restore default state
|
// Restore default state
|
||||||
|
|
|
@ -96,7 +96,6 @@ private:
|
||||||
OpenGLState state;
|
OpenGLState state;
|
||||||
|
|
||||||
// OpenGL object IDs
|
// OpenGL object IDs
|
||||||
OGLVertexArray vertex_array;
|
|
||||||
OGLBuffer vertex_buffer;
|
OGLBuffer vertex_buffer;
|
||||||
OGLProgram shader;
|
OGLProgram shader;
|
||||||
OGLFramebuffer screenshot_framebuffer;
|
OGLFramebuffer screenshot_framebuffer;
|
||||||
|
|
|
@ -24,8 +24,7 @@ VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
|
||||||
|
|
||||||
VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
|
VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
|
||||||
|
|
||||||
void VertexArrayPushBuffer::Setup(GLuint vao_) {
|
void VertexArrayPushBuffer::Setup() {
|
||||||
vao = vao_;
|
|
||||||
index_buffer = nullptr;
|
index_buffer = nullptr;
|
||||||
vertex_buffers.clear();
|
vertex_buffers.clear();
|
||||||
}
|
}
|
||||||
|
@ -41,13 +40,12 @@ void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint*
|
||||||
|
|
||||||
void VertexArrayPushBuffer::Bind() {
|
void VertexArrayPushBuffer::Bind() {
|
||||||
if (index_buffer) {
|
if (index_buffer) {
|
||||||
glVertexArrayElementBuffer(vao, *index_buffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *index_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Rodrigo): Find a way to ARB_multi_bind this
|
// TODO(Rodrigo): Find a way to ARB_multi_bind this
|
||||||
for (const auto& entry : vertex_buffers) {
|
for (const auto& entry : vertex_buffers) {
|
||||||
glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset,
|
glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
|
||||||
entry.stride);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ public:
|
||||||
explicit VertexArrayPushBuffer();
|
explicit VertexArrayPushBuffer();
|
||||||
~VertexArrayPushBuffer();
|
~VertexArrayPushBuffer();
|
||||||
|
|
||||||
void Setup(GLuint vao_);
|
void Setup();
|
||||||
|
|
||||||
void SetIndexBuffer(const GLuint* buffer);
|
void SetIndexBuffer(const GLuint* buffer);
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ public:
|
||||||
private:
|
private:
|
||||||
struct Entry;
|
struct Entry;
|
||||||
|
|
||||||
GLuint vao{};
|
|
||||||
const GLuint* index_buffer{};
|
const GLuint* index_buffer{};
|
||||||
std::vector<Entry> vertex_buffers;
|
std::vector<Entry> vertex_buffers;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue