X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fopengl%2Fcommands_backend.cpp;fp=source%2Fbackends%2Fopengl%2Fcommands_backend.cpp;h=fd66b99cacf35c63b2f0eb8394828d939aabb76a;hb=160e9eea29bd10034733d59507fa1bcca36be401;hp=0000000000000000000000000000000000000000;hpb=93448d16e72e38afbaecbccf6fdedd46d6a82a73;p=libs%2Fgl.git diff --git a/source/backends/opengl/commands_backend.cpp b/source/backends/opengl/commands_backend.cpp new file mode 100644 index 00000000..fd66b99c --- /dev/null +++ b/source/backends/opengl/commands_backend.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include "batch.h" +#include "commands_backend.h" +#include "error.h" +#include "framebuffer.h" +#include "gl.h" +#include "pipelinestate.h" +#include "query.h" + +using namespace std; + +namespace Msp { +namespace GL { + +OpenGLCommands::OpenGLCommands(): + pipeline_state(0) +{ } + +void OpenGLCommands::use_pipeline(const PipelineState *ps) +{ + pipeline_state = ps; + if(!pipeline_state) + OpenGLPipelineState::clear(); +} + +void OpenGLCommands::clear(const ClearValue *values) +{ + const Framebuffer *target = pipeline_state->get_framebuffer(); + if(!target) + throw invalid_operation("OpenGLCommands::clear"); + + if(!ARB_direct_state_access) + { + static Require _req(MSP_clear_buffer); + pipeline_state->apply(); + } + + unsigned i = 0; + for(FrameAttachment a: target->get_format()) + { + if(get_attach_point(a)==get_attach_point(DEPTH_ATTACHMENT)) + { + if(ARB_direct_state_access) + glClearNamedFramebufferfv(target->id, GL_DEPTH, 0, &values->depth_stencil.depth); + else + glClearBufferfv(GL_DEPTH, 0, &values->depth_stencil.depth); + } + else if(get_attach_point(a)==get_attach_point(STENCIL_ATTACHMENT)) + { + if(ARB_direct_state_access) + glClearNamedFramebufferiv(target->id, GL_STENCIL, 0, &values->depth_stencil.stencil); + else + glClearBufferiv(GL_STENCIL, 0, &values->depth_stencil.stencil); + } + else + { + if(ARB_direct_state_access) + glClearNamedFramebufferfv(target->id, GL_COLOR, i++, &values->color.r); + else + glClearBufferfv(GL_COLOR, i++, &values->color.r); + } + ++values; + } +} + +void OpenGLCommands::draw(const Batch &batch) +{ + pipeline_state->apply(); + void *data_ptr = reinterpret_cast(batch.get_offset()); + glDrawElements(batch.gl_prim_type, batch.size(), batch.gl_index_type, data_ptr); +} + +void OpenGLCommands::draw_instanced(const Batch &batch, unsigned count) +{ + static Require req(ARB_draw_instanced); + + pipeline_state->apply(); + void *data_ptr = reinterpret_cast(batch.get_offset()); + glDrawElementsInstanced(batch.gl_prim_type, batch.size(), batch.gl_index_type, data_ptr, count); +} + +void OpenGLCommands::resolve_multisample(Framebuffer &target) +{ + static Require _req(EXT_framebuffer_blit); + + const Framebuffer *source = pipeline_state->get_framebuffer(); + + unsigned width = min(source->get_width(), target.get_width()); + unsigned height = min(source->get_height(), target.get_height()); + unsigned buffers = get_gl_buffer_bits(source->get_format())&get_gl_buffer_bits(target.get_format()); + + if(ARB_direct_state_access) + glBlitNamedFramebuffer(source->id, target.id, 0, 0, width, height, 0, 0, width, height, buffers, GL_NEAREST); + else + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, source->id); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target.id); + + target.refresh(); + + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, buffers, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, source->id); + } +} + +void OpenGLCommands::begin_query(const QueryPool &pool, unsigned index) +{ + if(index>=pool.queries.size()) + throw out_of_range("OpenGLCommands::begin_query"); + glBeginQuery(pool.gl_type, pool.queries[index]); +} + +void OpenGLCommands::end_query(const QueryPool &pool, unsigned) +{ + glEndQuery(pool.gl_type); +} + +} // namespace GL +} // namespace Msp