예제 #1
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::Clear(ClearOptions options, Color const& color, float depth, std::uint8_t stencil)
{
    GLbitfield mask = 0;

    if ((options | ClearOptions::DepthBuffer) == options) {
        mask |= GL_DEPTH_BUFFER_BIT;
        auto clamped = std::min(std::max(depth, 0.0f), 1.0f);
        glClearDepthf(clamped);
        POMDOG_CHECK_ERROR_GL4("glClearDepthf");
    }
    if ((options | ClearOptions::Stencil) == options) {
        mask |= GL_STENCIL_BUFFER_BIT;
        glClearStencil(stencil);
        POMDOG_CHECK_ERROR_GL4("glClearStencil");
    }
    if ((options | ClearOptions::RenderTarget) == options) {
        mask |= GL_COLOR_BUFFER_BIT;
        auto colorVector = color.ToVector4();
        glClearColor(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
        POMDOG_CHECK_ERROR_GL4("glClearColor");
    }

    glClear(mask);
    POMDOG_CHECK_ERROR_GL4("glClear");
}
예제 #2
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetViewport(Viewport const& viewport)
{
    POMDOG_ASSERT(viewport.Width > 0);
    POMDOG_ASSERT(viewport.Height > 0);

    GLint viewportY = viewport.TopLeftY;

    if (renderTargets.empty()) {
        if (auto window = gameWindow.lock()) {
            viewportY = window->GetClientBounds().Height - (viewport.TopLeftY + viewport.Height);
        }
    }

    glViewport(viewport.TopLeftX, viewportY, viewport.Width, viewport.Height);
    POMDOG_CHECK_ERROR_GL4("glViewport");

    static_assert(std::is_same<GLfloat, decltype(viewport.MinDepth)>::value
                  && std::is_same<GLfloat, decltype(viewport.MaxDepth)>::value,
                  "NOTE: You can use glDepthRange instead of glDepthRangef");

    POMDOG_ASSERT(!std::isinf(viewport.MinDepth));
    POMDOG_ASSERT(!std::isinf(viewport.MaxDepth));
    POMDOG_ASSERT(!std::isnan(viewport.MinDepth));
    POMDOG_ASSERT(!std::isnan(viewport.MaxDepth));

    glDepthRangef(viewport.MinDepth, viewport.MaxDepth);
    POMDOG_CHECK_ERROR_GL4("glDepthRangef");
}
예제 #3
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetRenderTarget()
{
    POMDOG_ASSERT(frameBuffer);

    // Bind framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->value);
    POMDOG_CHECK_ERROR_GL4("glBindFramebuffer");

    // Unbind render targets
    {
        std::size_t index = 0;
        for (auto const& renderTarget: renderTargets)
        {
            POMDOG_ASSERT(renderTarget);
            renderTarget->UnbindFromFramebuffer(ToColorAttachment(index));
            ++index;
        }
    }
    renderTargets.clear();

    // Unbind depth stencil buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
    POMDOG_CHECK_ERROR_GL4("glFramebufferRenderbuffer");

    // Bind default framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    POMDOG_CHECK_ERROR_GL4("glBindFramebuffer");
}
예제 #4
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
BufferGL4<Tag>::BufferGL4(void const* sourceData, std::size_t sizeInBytes,
    BufferUsage bufferUsage)
{
    POMDOG_ASSERT(bufferUsage == BufferUsage::Immutable
        ? sourceData != nullptr : true);

    // Generate new buffer
    bufferObject = ([] {
        BufferObject buffer;
        glGenBuffers(1, buffer.Data());
        return std::move(buffer);
    })();
    POMDOG_CHECK_ERROR_GL4("glGenBuffers");

    auto const oldBuffer = TypesafeHelperGL4::Get<BufferObject>();
    ScopeGuard scope([&] { TypesafeHelperGL4::BindBuffer(oldBuffer); });

    POMDOG_ASSERT(bufferObject);
    TypesafeHelperGL4::BindBuffer(*bufferObject);
    POMDOG_CHECK_ERROR_GL4("glBindBuffer");

    POMDOG_ASSERT(sizeInBytes > 0);
    glBufferData(BufferTraits<Tag>::Buffer,
        sizeInBytes,
        sourceData,
        ToBufferUsage(bufferUsage));
    POMDOG_CHECK_ERROR_GL4("glBufferData");
}
예제 #5
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
void BufferGL4<Tag>::SetData(std::size_t offsetInBytes,
    void const* source, std::size_t sizeInBytes)
{
    POMDOG_ASSERT(source != nullptr);

    auto const oldBuffer = TypesafeHelperGL4::Get<BufferObject>();
    ScopeGuard scope([&] { TypesafeHelperGL4::BindBuffer(oldBuffer); });

    POMDOG_ASSERT(bufferObject);
    TypesafeHelperGL4::BindBuffer(*bufferObject);
    POMDOG_CHECK_ERROR_GL4("glBindBuffer");

#if defined(DEBUG) && !defined(NDEBUG)
    {
        GLint bufferSize = 0;
        glGetBufferParameteriv(BufferTraits<Tag>::Buffer,
            GL_BUFFER_SIZE, &bufferSize);
        POMDOG_ASSERT(sizeInBytes <= static_cast<std::size_t>(bufferSize));
    }
#endif

    POMDOG_ASSERT(sizeInBytes > 0);
    glBufferSubData(BufferTraits<Tag>::Buffer,
        offsetInBytes, sizeInBytes, source);
    POMDOG_CHECK_ERROR_GL4("glBufferSubData");
}
예제 #6
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::DrawIndexedInstanced(
    std::size_t indexCount,
    std::size_t instanceCount)
{
    ApplyPipelineState();

    // Bind index buffer
    POMDOG_ASSERT(indexBuffer);
    auto indexBufferGL = dynamic_cast<IndexBufferGL4*>(indexBuffer->NativeIndexBuffer());
    POMDOG_ASSERT(indexBufferGL != nullptr);
    indexBufferGL->BindBuffer();

    // Draw
    POMDOG_ASSERT(indexCount > 0);
    POMDOG_ASSERT(indexCount <= indexBuffer->IndexCount());
    POMDOG_ASSERT(instanceCount > 0);
    POMDOG_ASSERT(instanceCount < static_cast<decltype(instanceCount)>(std::numeric_limits<GLsizei>::max()));

    glDrawElementsInstanced(
        primitiveTopology.value,
        static_cast<GLsizei>(indexCount),
        ToIndexElementType(indexBuffer->ElementSize()),
        nullptr,
        static_cast<GLsizei>(instanceCount));
    POMDOG_CHECK_ERROR_GL4("glDrawElementsInstanced");
}
예제 #7
0
SamplerStateGL4::~SamplerStateGL4()
{
    if (samplerObject) {
        glDeleteSamplers(1, samplerObject->Data());
        POMDOG_CHECK_ERROR_GL4("glDeleteSamplers");
    }
}
예제 #8
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
BufferGL4<Tag>::~BufferGL4()
{
    if (bufferObject) {
        glDeleteBuffers(1, bufferObject->Data());
        POMDOG_CHECK_ERROR_GL4("glDeleteBuffers");
    }
}
예제 #9
0
void OpenGLContextWin32::SwapBuffers()
{
    glFlush();
    POMDOG_CHECK_ERROR_GL4("glFlush");

    POMDOG_ASSERT(hdc);
    ::SwapBuffers(hdc.get());
}
예제 #10
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetTexture(int textureUnit)
{
    POMDOG_ASSERT(!textures.empty());
    POMDOG_ASSERT(textureUnit >= 0);
    POMDOG_ASSERT(textureUnit < static_cast<int>(textures.size()));

    if (textures[textureUnit])
    {
        glActiveTexture(ToTextureUnitIndexGL4(textureUnit));
        POMDOG_CHECK_ERROR_GL4("glActiveTexture");

        glBindTexture(*textures[textureUnit], 0);
        POMDOG_CHECK_ERROR_GL4("glBindTexture");
    }

    textures[textureUnit] = Pomdog::NullOpt;
}
예제 #11
0
void SamplerStateGL4::Apply(int index)
{
    static_assert(GL_TEXTURE19 == (GL_TEXTURE0 + 19), "");
    POMDOG_ASSERT(index >= 0);
    POMDOG_ASSERT(index <= 19);

    POMDOG_ASSERT(samplerObject);
    glBindSampler(index, samplerObject->value);
    POMDOG_CHECK_ERROR_GL4("glBindSampler");
}
예제 #12
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetScissorRectangle(Rectangle const& rectangle)
{
    POMDOG_ASSERT(rectangle.Width > 0);
    POMDOG_ASSERT(rectangle.Height > 0);

    GLint lowerLeftCornerY = rectangle.Y;

    if (renderTargets.empty()) {
        if (auto window = gameWindow.lock()) {
            lowerLeftCornerY = window->GetClientBounds().Height - (rectangle.Y + rectangle.Height);
        }
    }

    glScissor(rectangle.X, lowerLeftCornerY, rectangle.Width, rectangle.Height);
    POMDOG_CHECK_ERROR_GL4("glScissor");
}
예제 #13
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::Draw(std::size_t vertexCount)
{
    ApplyPipelineState();

    // Draw
    POMDOG_ASSERT(!vertexBuffers.empty());
    POMDOG_ASSERT(vertexBuffers.front().VertexBuffer);
    POMDOG_ASSERT(vertexCount > 0);
    POMDOG_ASSERT(vertexCount <= vertexBuffers.front().VertexBuffer->VertexCount());

    glDrawArrays(
        primitiveTopology.value,
        0,
        static_cast<GLsizei>(vertexCount));
    POMDOG_CHECK_ERROR_GL4("glDrawArrays");
}
예제 #14
0
//-----------------------------------------------------------------------
GraphicsContextGL4::~GraphicsContextGL4()
{
    pipelineState.reset();
    vertexBuffers.clear();
    indexBuffer.reset();
    textures.clear();
    renderTargets.clear();

    if (frameBuffer) {
        glDeleteFramebuffers(1, frameBuffer->Data());
        POMDOG_CHECK_ERROR_GL4("glDeleteFramebuffers");
        frameBuffer = Pomdog::NullOpt;
    }

    nativeContext.reset();
    gameWindow.reset();
}
예제 #15
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::DrawInstanced(
    std::size_t vertexCount, std::size_t instanceCount)
{
    ApplyPipelineState();

    // Draw
    POMDOG_ASSERT(!vertexBuffers.empty());
    POMDOG_ASSERT(vertexBuffers.front().VertexBuffer);
    POMDOG_ASSERT(vertexCount > 0);
    POMDOG_ASSERT(vertexCount <= vertexBuffers.front().VertexBuffer->VertexCount());
    POMDOG_ASSERT(instanceCount > 0);
    POMDOG_ASSERT(instanceCount <= static_cast<decltype(instanceCount)>(std::numeric_limits<GLsizei>::max()));

    glDrawArraysInstanced(
        primitiveTopology.value,
        0,
        static_cast<GLsizei>(vertexCount),
        static_cast<GLsizei>(instanceCount));
    POMDOG_CHECK_ERROR_GL4("glDrawArraysInstanced");
}
예제 #16
0
//-----------------------------------------------------------------------
GraphicsContextGL4::GraphicsContextGL4(
    std::shared_ptr<OpenGLContext> const& openGLContextIn,
    std::weak_ptr<GameWindow> windowIn)
    : nativeContext(openGLContextIn)
    , gameWindow(std::move(windowIn))
    , needToApplyInputLayout(true)
    , needToApplyPipelineState(true)
{
    auto version = reinterpret_cast<char const*>(glGetString(GL_VERSION));
    Log::Stream(LogLevel::Internal) << "OpenGL Version: " << version;

    auto capabilities = GetCapabilities();
    if (capabilities.SamplerSlotCount > 0) {
        textures.resize(capabilities.SamplerSlotCount);
    }

    glFrontFace(GL_CW);
    POMDOG_CHECK_ERROR_GL4("glFrontFace");

    frameBuffer = CreateFrameBuffer();
    primitiveTopology = ToPrimitiveTopology(PrimitiveTopology::TriangleList);
}
예제 #17
0
SamplerStateGL4::SamplerStateGL4(const SamplerDescription& description)
{
    samplerObject = ([] {
        SamplerObjectGL4 sampler;
        glGenSamplers(1, sampler.Data());
        POMDOG_CHECK_ERROR_GL4("glGenSamplers");
        return sampler;
    })();

    glSamplerParameteri(samplerObject->value, GL_TEXTURE_WRAP_S, ToTextureAddressMode(description.AddressU));
    glSamplerParameteri(samplerObject->value, GL_TEXTURE_WRAP_T, ToTextureAddressMode(description.AddressV));
    glSamplerParameteri(samplerObject->value, GL_TEXTURE_WRAP_R, ToTextureAddressMode(description.AddressW));

    POMDOG_CHECK_ERROR_GL4("glSamplerParameteri");

    switch (description.Filter) {
    case TextureFilter::Linear:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        break;
    case TextureFilter::Point:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        break;
    case TextureFilter::LinearMipPoint:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        break;
    case TextureFilter::PointMipLinear:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        break;
    case TextureFilter::MinLinearMagPointMipLinear:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        break;
    case TextureFilter::MinLinearMagPointMipPoint:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        break;
    case TextureFilter::MinPointMagLinearMipLinear:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        break;
    case TextureFilter::MinPointMagLinearMipPoint:
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        break;
    case TextureFilter::Anisotropic: {
        // FIXME: Not implemented
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glSamplerParameteri(samplerObject->value, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        POMDOG_CHECK_ERROR_GL4("glSamplerParameteri");

        POMDOG_ASSERT(1 <= description.MaxAnisotropy && description.MaxAnisotropy <= 16);

        GLfloat deviceMaxAnisotropy = 1.0f;
        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &deviceMaxAnisotropy);
        POMDOG_CHECK_ERROR_GL4("glGetFloatv");

        deviceMaxAnisotropy = std::min(deviceMaxAnisotropy,
            static_cast<decltype(deviceMaxAnisotropy)>(description.MaxAnisotropy));

        glSamplerParameterf(samplerObject->value, GL_TEXTURE_MAX_ANISOTROPY_EXT, deviceMaxAnisotropy);
        POMDOG_CHECK_ERROR_GL4("glSamplerParameterf");
        break;
    }
    }

    {
        POMDOG_ASSERT(description.MinMipLevel <= description.MaxMipLevel);
        POMDOG_ASSERT(description.MaxMipLevel <= std::numeric_limits<GLfloat>::max());

        glSamplerParameterf(samplerObject->value, GL_TEXTURE_MIN_LOD, description.MaxMipLevel);
        glSamplerParameterf(samplerObject->value, GL_TEXTURE_MAX_LOD, description.MaxMipLevel);
        glSamplerParameterf(samplerObject->value, GL_TEXTURE_LOD_BIAS, description.MipMapLevelOfDetailBias);
        POMDOG_CHECK_ERROR_GL4("glSamplerParameterf");
    }
}
예제 #18
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::Present()
{
    nativeContext->SwapBuffers();
    POMDOG_CHECK_ERROR_GL4("SwapBuffers");
}
예제 #19
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetRenderTargets(std::vector<std::shared_ptr<RenderTarget2D>> const& renderTargetsIn)
{
    POMDOG_ASSERT(!renderTargetsIn.empty());
    POMDOG_ASSERT(frameBuffer);

    // Bind framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->value);
    POMDOG_CHECK_ERROR_GL4("glBindFramebuffer");

    // Unbind render targets
    {
        std::size_t index = 0;
        for (auto const& renderTarget: renderTargets)
        {
            POMDOG_ASSERT(renderTarget);
            renderTarget->UnbindFromFramebuffer(ToColorAttachment(index));
            ++index;
        }
    }
    renderTargets.clear();

    // Unbind depth stencil buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
    POMDOG_CHECK_ERROR_GL4("glFramebufferRenderbuffer");

    std::vector<GLenum> attachments;
    attachments.reserve(renderTargetsIn.size());
    renderTargets.reserve(renderTargetsIn.size());

    // Attach textures
    std::uint32_t index = 0;
    for (auto const& renderTarget: renderTargetsIn)
    {
        POMDOG_ASSERT(renderTarget);

        auto const nativeRenderTarget = static_cast<RenderTarget2DGL4*>(renderTarget->NativeRenderTarget2D());
        POMDOG_ASSERT(nativeRenderTarget != nullptr);
        POMDOG_ASSERT(nativeRenderTarget == dynamic_cast<RenderTarget2DGL4*>(renderTarget->NativeRenderTarget2D()));

        POMDOG_ASSERT(nativeRenderTarget);
        nativeRenderTarget->BindToFramebuffer(ToColorAttachment(index));

        renderTargets.emplace_back(renderTarget, nativeRenderTarget);

        attachments.push_back(ToColorAttachment(index));
        ++index;
    }

    // Attach depth stencil buffer
    {
        POMDOG_ASSERT(renderTargets.front());
        auto const& renderTarget = renderTargets.front();

        POMDOG_ASSERT(renderTarget);
        renderTarget->BindDepthStencilBuffer();
    }

    // Check framebuffer status
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        // FUS RO DAH!
        POMDOG_THROW_EXCEPTION(std::runtime_error,
                               "Failed to make complete framebuffer.");
    }

    POMDOG_ASSERT(!attachments.empty());
    POMDOG_ASSERT(attachments.size() <= static_cast<std::size_t>(std::numeric_limits<GLsizei>::max()));
    glDrawBuffers(static_cast<GLsizei>(attachments.size()), attachments.data());
    POMDOG_CHECK_ERROR_GL4("glDrawBuffers");
}
예제 #20
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
void BufferGL4<Tag>::BindBuffer()
{
    POMDOG_ASSERT(bufferObject);
    TypesafeHelperGL4::BindBuffer(*bufferObject);
    POMDOG_CHECK_ERROR_GL4("glBindBuffer");
}
예제 #21
0
//-----------------------------------------------------------------------
void GraphicsContextGL4::SetBlendFactor(Color const& blendFactor)
{
    auto colorVector = blendFactor.ToVector4();
    glBlendColor(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
    POMDOG_CHECK_ERROR_GL4("glBlendColor");
}