void GraphicsCommandListImmediate::SortCommandsForMetal()
{
    static_assert(static_cast<int>(GraphicsCommandType::DrawCommand) == 0, "");
    static_assert(static_cast<int>(GraphicsCommandType::DrawIndexedCommand) == 1, "");
    static_assert(static_cast<int>(GraphicsCommandType::DrawInstancedCommand) == 2, "");
    static_assert(static_cast<int>(GraphicsCommandType::DrawIndexedInstancedCommand) == 3, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetPrimitiveTopologyCommand) == 4, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetBlendFactorCommand) == 5, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetVertexBuffersCommand) == 6, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetIndexBufferCommand) == 7, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetPipelineStateCommand) == 8, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetConstantBufferCommand) == 9, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetSamplerStateCommand) == 10, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetTextureCommand) == 11, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetTextureRenderTarget2DCommand) == 12, "");
    static_assert(static_cast<int>(GraphicsCommandType::SetRenderPassCommand) == 13, "");

    constexpr std::int8_t priorityDrawCommand = 31;
    constexpr std::int8_t priorityDefault = 30;

    const std::array<std::int8_t, 14> priorities = {{
        priorityDrawCommand, // DrawCommand
        priorityDrawCommand, // DrawIndexedCommand
        priorityDrawCommand, // DrawInstancedCommand
        priorityDrawCommand, // DrawIndexedInstancedCommand
        priorityDefault, // SetPrimitiveTopologyCommand
        priorityDefault, // SetBlendFactorCommand
        priorityDefault, // SetVertexBuffersCommand
        priorityDefault, // SetIndexBufferCommand
        priorityDefault, // SetPipelineStateCommand
        priorityDefault, // SetConstantBufferCommand
        priorityDefault, // SetSamplerStateCommand
        priorityDefault, // SetTextureCommand
        priorityDefault, // SetTextureRenderTarget2DCommand
        0, // SetRenderPassCommand
    }};

    // NOTE: Sort commands for MTLRenderCommandEncoder by using odd-even sort.
    for (size_t k = 0; k < commands.size(); ++k) {
        bool swapped = false;
        for (size_t i = 1 + (k % 2); i < commands.size(); i += 2) {
            auto & a = commands[i - 1];
            auto & b = commands[i];
            const auto x = static_cast<std::int8_t>(a->commandType);
            const auto y = static_cast<std::int8_t>(b->commandType);
            POMDOG_ASSERT(x <= static_cast<std::int8_t>(priorities.size()));
            POMDOG_ASSERT(y <= static_cast<std::int8_t>(priorities.size()));
            if ((priorities[x] > priorities[y]) && (priorities[x] != priorityDrawCommand)) {
                std::swap(a, b);
                swapped = true;
            }
        }
        if (!swapped && (k > 0)) {
            break;
        }
    }

#if 0
    // NOTE: Remove a redundant 'SetRenderPassCommand' command.
    bool isPrevRenderPassCommand = false;
    for (auto iter = commands.rbegin(); iter != commands.rend();) {
        if ((*iter)->commandType == GraphicsCommandType::SetRenderPassCommand) {
            if (isPrevRenderPassCommand) {
                std::advance(iter, 1);
                commands.erase(iter.base());
                continue;
            }
            isPrevRenderPassCommand = true;
        }
        else {
            isPrevRenderPassCommand = false;
        }
        ++iter;
    }
#endif

    // NOTE: Duplicate missing commands for MTLRenderCommandEncoder.
    std::size_t renderPassCommandIndex = 0;
    std::optional<std::size_t> setPipelineStateCommand;
    std::optional<std::size_t> setPrimitiveTopologyCommand;
    std::optional<std::size_t> setBlendFactorCommand;
    std::optional<std::size_t> setVertexBuffersCommand;
    std::optional<std::size_t> setIndexBufferCommand;
    std::vector<std::optional<std::size_t>> setConstantBufferCommands;
    std::vector<std::optional<std::size_t>> setSamplerCommands;
    std::vector<std::optional<std::size_t>> setTextureCommands;

    setConstantBufferCommands.resize(8, std::nullopt);
    setSamplerCommands.resize(8, std::nullopt);
    setTextureCommands.resize(8, std::nullopt);

    std::vector<std::shared_ptr<GraphicsCommand>> oldCommands;
    bool needToFlushCommands = true;

    std::swap(commands, oldCommands);

    for (auto & command : oldCommands) {
        POMDOG_ASSERT(command != nullptr);

        bool isDrawCommand = false;

        switch (command->commandType) {
        case GraphicsCommandType::SetRenderPassCommand:
            renderPassCommandIndex = commands.size();
            needToFlushCommands = true;
            break;
        case GraphicsCommandType::SetPipelineStateCommand:
            setPipelineStateCommand = commands.size();
            break;
        case GraphicsCommandType::SetPrimitiveTopologyCommand:
            setPrimitiveTopologyCommand = commands.size();
            break;
        case GraphicsCommandType::SetBlendFactorCommand:
            setBlendFactorCommand = commands.size();
            break;
        case GraphicsCommandType::SetVertexBuffersCommand:
            setVertexBuffersCommand = commands.size();
            break;
        case GraphicsCommandType::SetIndexBufferCommand:
            setIndexBufferCommand = commands.size();
            break;
        case GraphicsCommandType::SetConstantBufferCommand: {
            auto c = std::static_pointer_cast<SetConstantBufferCommand>(command);
            POMDOG_ASSERT(c->slotIndex < static_cast<int>(setConstantBufferCommands.size()));
            setConstantBufferCommands[c->slotIndex] = commands.size();
            break;
        }
        case GraphicsCommandType::SetSamplerStateCommand: {
            auto c = std::static_pointer_cast<SetSamplerStateCommand>(command);
            POMDOG_ASSERT(c->slotIndex < static_cast<int>(setSamplerCommands.size()));
            setSamplerCommands[c->slotIndex] = commands.size();
            break;
        }
        case GraphicsCommandType::SetTextureCommand: {
            auto c = std::static_pointer_cast<SetTextureCommand>(command);
            POMDOG_ASSERT(c->slotIndex < static_cast<int>(setTextureCommands.size()));
            setTextureCommands[c->slotIndex] = commands.size();
            break;
        }
        case GraphicsCommandType::SetTextureRenderTarget2DCommand: {
            auto c = std::static_pointer_cast<SetTextureRenderTarget2DCommand>(command);
            POMDOG_ASSERT(c->slotIndex < static_cast<int>(setTextureCommands.size()));
            setTextureCommands[c->slotIndex] = commands.size();
            break;
        }
        case GraphicsCommandType::DrawCommand:
        case GraphicsCommandType::DrawIndexedCommand:
        case GraphicsCommandType::DrawInstancedCommand:
        case GraphicsCommandType::DrawIndexedInstancedCommand: {
            isDrawCommand = true;
            break;
        }
        }

        if (isDrawCommand && needToFlushCommands) {
            if (setPipelineStateCommand && (*setPipelineStateCommand < renderPassCommandIndex)) {
                commands.push_back(commands[*setPipelineStateCommand]);
            }
            if (setPrimitiveTopologyCommand && (*setPrimitiveTopologyCommand < renderPassCommandIndex)) {
                commands.push_back(commands[*setPrimitiveTopologyCommand]);
            }
            if (setBlendFactorCommand && (*setBlendFactorCommand < renderPassCommandIndex)) {
                commands.push_back(commands[*setBlendFactorCommand]);
            }
            if (setVertexBuffersCommand && (*setVertexBuffersCommand < renderPassCommandIndex)) {
                commands.push_back(commands[*setVertexBuffersCommand]);
            }
            if (setIndexBufferCommand && (*setIndexBufferCommand < renderPassCommandIndex)) {
                commands.push_back(commands[*setIndexBufferCommand]);
            }
            for (auto & commandIndex : setConstantBufferCommands) {
                if (commandIndex && (*commandIndex < renderPassCommandIndex)) {
                    commands.push_back(commands[*commandIndex]);
                }
            }
            for (auto & commandIndex : setSamplerCommands) {
                if (commandIndex && (*commandIndex < renderPassCommandIndex)) {
                    commands.push_back(commands[*commandIndex]);
                }
            }
            for (auto & commandIndex : setTextureCommands) {
                if (commandIndex && (*commandIndex < renderPassCommandIndex)) {
                    commands.push_back(commands[*commandIndex]);
                }
            }
            needToFlushCommands = false;
        }
        commands.push_back(std::move(command));
    }
}
예제 #2
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::SetBool(std::string const& name, bool value)
{
    POMDOG_ASSERT(impl);
    impl->SetBool(name, value);
}
예제 #3
0
void AudioEngineAL::SetMasterVolume(float volume)
{
    POMDOG_ASSERT(volume >= 0.0f);
    alListenerf(AL_GAIN, volume);
}
예제 #4
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::Play(std::string const& state)
{
    POMDOG_ASSERT(impl);
    impl->Play(state);
}
예제 #5
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::PlaybackRate(float playbackRate)
{
    POMDOG_ASSERT(impl);
    impl->PlaybackRate(playbackRate);
}
예제 #6
0
void OpenGLContextWin32::MakeCurrent()
{
    POMDOG_ASSERT(hdc);
    POMDOG_ASSERT(glrc);
    wglMakeCurrent(hdc.get(), glrc.get());
}
예제 #7
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::Update(Duration const& frameDuration)
{
    POMDOG_ASSERT(impl);
    impl->Update(frameDuration);
}
예제 #8
0
bool FileSystem::CreateDirectory(const std::string& path)
{
    // 'CreateDirectory' means 'CreateDirectoryA' in Win32.
    POMDOG_ASSERT(!path.empty());
    return fs::create_directory(path);
}
예제 #9
0
bool FileSystem::CreateDirectories(const std::string& path)
{
    POMDOG_ASSERT(!path.empty());
    return fs::create_directories(path);
}
예제 #10
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
GLuint BufferGL4<Tag>::GetBuffer() const
{
    POMDOG_ASSERT(bufferObject);
    return bufferObject->value;
}
예제 #11
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
BufferGL4<Tag>::BufferGL4(std::size_t sizeInBytes, BufferUsage bufferUsage)
    : BufferGL4(nullptr, sizeInBytes, bufferUsage)
{
    POMDOG_ASSERT(bufferUsage != BufferUsage::Immutable);
}
예제 #12
0
파일: BufferGL4.cpp 프로젝트: Mourtz/pomdog
void BufferGL4<Tag>::BindBuffer()
{
    POMDOG_ASSERT(bufferObject);
    TypesafeHelperGL4::BindBuffer(*bufferObject);
    POMDOG_CHECK_ERROR_GL4("glBindBuffer");
}
예제 #13
0
 ~ScopeGuard()
 {
     POMDOG_ASSERT(func);
     func();
 }
예제 #14
0
Connection LogChannel::Connect(std::function<void(const LogEntry&)> && slot)
{
    POMDOG_ASSERT(slot);
    return signal.Connect(std::move(slot));
}
예제 #15
0
void AudioEngine::SetMasterVolume(float volume)
{
    POMDOG_ASSERT(volume >= 0);
    POMDOG_ASSERT(nativeAudioEngine);
    nativeAudioEngine->SetMasterVolume(volume);
}
예제 #16
0
bool FileSystem::Exists(const std::string& path)
{
    POMDOG_ASSERT(!path.empty());
    return fs::exists(path);
}
예제 #17
0
Detail::SoundSystem::NativeAudioEngine* AudioEngine::GetNativeAudioEngine()
{
    POMDOG_ASSERT(nativeAudioEngine);
    return nativeAudioEngine.get();
}
예제 #18
0
bool FileSystem::IsDirectory(const std::string& path)
{
    POMDOG_ASSERT(!path.empty());
    return fs::is_directory(path);
}
예제 #19
0
void PolygonShapeBuilder::DrawSphere(
    const Vector3& position,
    float radius,
    const Color& color,
    int segments)
{
    POMDOG_ASSERT(segments >= 4);
    POMDOG_ASSERT(radius >= 0);

    if (radius <= 0) {
        return;
    }

    const auto rings = std::max(static_cast<int>(segments), 4);
    const auto sectors = std::max(static_cast<int>(segments), 4);

    std::vector<Vector3> sphereVertices;
    sphereVertices.reserve(rings * sectors);

    const auto R = 1.0f / static_cast<float>(rings - 1);
    const auto S = 1.0f / static_cast<float>(sectors - 1);

    for (int ring = 0; ring < rings; ++ring) {
        const auto latitude = Math::Pi<float> * ring * R;
        const auto y = std::cos(latitude);
        const auto r = std::sin(latitude);
        for (int s = 0; s < sectors; ++s) {
            const auto longitude = Math::TwoPi<float> * s * S;
            const auto x = r * std::cos(longitude);
            const auto z = r * std::sin(longitude);
            sphereVertices.push_back(Vector3{x, y, z} * radius + position);
        }
    }

    const auto colorVector = color.ToVector4();
    const auto drawIndices = [&](std::size_t a, std::size_t b, std::size_t c, std::size_t d) {
        POMDOG_ASSERT(a < sphereVertices.size());
        POMDOG_ASSERT(b < sphereVertices.size());
        POMDOG_ASSERT(c < sphereVertices.size());
        POMDOG_ASSERT(d < sphereVertices.size());
        DrawTriangle(
            sphereVertices[a],
            sphereVertices[c],
            sphereVertices[b],
            colorVector,
            colorVector,
            colorVector);
        DrawTriangle(
            sphereVertices[c],
            sphereVertices[a],
            sphereVertices[d],
            colorVector,
            colorVector,
            colorVector);
    };

    for (int r = 0; r < rings - 1; ++r) {
        for (int s = 0; s < sectors - 1; ++s) {
            drawIndices(
                r * sectors + s,
                (r + 1) * sectors + s,
                (r + 1) * sectors + (s + 1),
                r * sectors + (s + 1));
        }
    }
}
예제 #20
0
파일: Skeleton.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
Joint const& Skeleton::Root() const
{
    POMDOG_ASSERT(!joints.empty());
    return joints.front();
}
예제 #21
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::CrossFade(std::string const& state, Duration const& transitionDuration)
{
    POMDOG_ASSERT(impl);
    impl->CrossFade(state, transitionDuration);
}
예제 #22
0
파일: Skeleton.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
Joint const& Skeleton::Joints(JointIndex const& jointIndex) const
{
    POMDOG_ASSERT(jointIndex);
    POMDOG_ASSERT(*jointIndex < joints.size());
    return joints[*jointIndex];
}
예제 #23
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
float Animator::PlaybackRate() const
{
    POMDOG_ASSERT(impl);
    return impl->PlaybackRate();
}
예제 #24
0
파일: Skeleton.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
std::uint16_t Skeleton::JointCount() const
{
    POMDOG_ASSERT(joints.size() < std::numeric_limits<std::uint16_t>::max());
    return static_cast<std::uint16_t>(joints.size());
}
예제 #25
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
void Animator::SetFloat(std::string const& name, float value)
{
    POMDOG_ASSERT(impl);
    impl->SetFloat(name, value);
}
예제 #26
0
 CompressedFloat(float scalar)
     : data(scalar * Denominator)
 {
     POMDOG_ASSERT(scalar < Max());
     POMDOG_ASSERT(scalar >= Min());
 }
예제 #27
0
파일: Animator.cpp 프로젝트: bis83/pomdog
//-----------------------------------------------------------------------
std::string Animator::GetCurrentStateName() const
{
    POMDOG_ASSERT(impl);
    return impl->GetCurrentStateName();
}
예제 #28
0
float AudioEngine::GetMasterVolume() const
{
    POMDOG_ASSERT(nativeAudioEngine);
    return nativeAudioEngine->GetMasterVolume();
}
예제 #29
0
void LightningTestGame::Initialize()
{
    window->SetTitle("TestApp - Enjoy Game Dev, Have Fun.");
    window->SetAllowUserResizing(true);

    auto assets = gameHost->AssetManager();
    auto clientBounds = window->GetClientBounds();

    {
        gameEditor = std::make_unique<SceneEditor::InGameEditor>(gameHost);
        editorBackground = std::make_unique<SceneEditor::EditorBackground>(gameHost);
    }
    {
        commandList = std::make_shared<GraphicsCommandList>(*graphicsDevice);

        //samplerPoint = SamplerState::CreatePointWrap(graphicsDevice);

        texture = assets->Load<Texture2D>("Particles/lightning.png");
    }
    {
        renderTarget = std::make_shared<RenderTarget2D>(graphicsDevice,
            clientBounds.Width, clientBounds.Height,
            false, SurfaceFormat::R8G8B8A8_UNorm, DepthFormat::None);
    }
    {
        spriteBatch = std::make_unique<SpriteBatch>(graphicsDevice, *assets);
        spriteRenderer = std::make_unique<SpriteRenderer>(graphicsDevice, *assets);
        fxaa = std::make_unique<FXAA>(graphicsDevice, *assets);
        fxaa->SetViewport(clientBounds.Width, clientBounds.Height);
        screenQuad = std::make_unique<ScreenQuad>(graphicsDevice);
    }
    {
        mainCamera = gameWorld.CreateObject();
        mainCamera.AddComponent<Transform2D>();
        mainCamera.AddComponent<Camera2D>();
    }
//    {
//        auto gameObject = gameWorld.CreateObject();
//
//        auto & sprite = gameObject->AddComponent<Sprite>();
//        sprite.Origin = Vector2{0.5f, 0.5f};
//        sprite.Subrect = Rectangle(0, 0, texture->Width(), texture->Height());
//
//        gameObject->AddComponent<Transform2D>();
//        gameObject->AddComponent<CanvasItem>();
//
//        auto transform = gameObject->Component<Transform2D>();
//        transform->Position = {0, 0};
//        transform->Scale = {2, 2};
//
//        auto node = std::make_shared<HierarchyNode>(gameObject);
//        rootNode->AddChild(node);
//    }
//
//    for (int i = 0; i < 10; ++i)
//    {
//        auto gameObject = gameWorld.CreateObject();
//        gameObject->AddComponent<CanvasItem>();
//
//        auto & sprite = gameObject->AddComponent<Sprite>();
//        auto & transform = gameObject->AddComponent<Transform2D>();
//
//        transform.Position = {i * 64 * 2.0f, 0};
//        transform.Scale = {2.0f, 2.0f};
//        transform.Rotation = (0.5f * i) * Math::PiOver4<float>;
//        sprite.Origin = Vector2{0.5f, 0.5f};
//        sprite.Subrect = Rectangle(0, 0, texture->Width(), texture->Height());//Rectangle(0, 0, 16, 28);
//
//        auto node = std::make_shared<HierarchyNode>(gameObject);
//        rootNode->AddChild(node);
//    }

    touchPoint = {0, -300};

    {
        scenePanel = std::make_shared<UI::ScenePanel>(clientBounds.Width, clientBounds.Height);
        scenePanel->cameraObject = mainCamera;
        gameEditor->AddView(scenePanel);
    }
    {
        auto stackPanel = std::make_shared<UI::StackPanel>(124, 170);
        stackPanel->Transform(Matrix3x2::CreateTranslation(Vector2{5, 10}));
        gameEditor->AddView(stackPanel);

        {
            auto navigator = std::make_shared<UI::DebugNavigator>(gameHost->Clock());
            stackPanel->AddChild(navigator);
        }
        {
            slider1 = std::make_shared<UI::Slider>(0, 100);
            slider1->Value(34);
            stackPanel->AddChild(slider1);
        }
        {
            slider2 = std::make_shared<UI::Slider>(0.1, 4.0);
            slider2->Value(1.2);
            stackPanel->AddChild(slider2);
        }
        {
            slider3 = std::make_shared<UI::Slider>(0.0f, 1.0f);
            slider3->Value(0.2f);
            stackPanel->AddChild(slider3);
        }
        {
            slider4 = std::make_shared<UI::Slider>(0.0f, 70.0f);
            slider4->Value(8.0f);
            stackPanel->AddChild(slider4);
        }
        {
            slider5 = std::make_shared<UI::Slider>(0.0f, 70.0f);
            slider5->Value(8.0f);
            stackPanel->AddChild(slider5);
        }
    }

    clientViewport = Viewport{0, 0, clientBounds.Width, clientBounds.Height};

    connections.Connect(scenePanel->SceneTouch, [this](Vector2 const& positionInView) {
        auto transform = mainCamera.Component<Transform2D>();
        auto camera = mainCamera.Component<Camera2D>();

        POMDOG_ASSERT(transform && camera);
        auto inverseViewMatrix3D = Matrix4x4::Invert(SandboxHelper::CreateViewMatrix(*transform, *camera));

        auto position = Vector3::Transform(Vector3(
            positionInView.X - clientViewport.Width / 2,
            positionInView.Y - clientViewport.Height / 2,
            0), inverseViewMatrix3D);

        touchPoint = Vector2{position.X, position.Y};
    });

    connections.Connect(window->ClientSizeChanged, [this](int width, int height) {
        clientViewport = Viewport{0, 0, width, height};

        renderTarget = std::make_shared<RenderTarget2D>(
            graphicsDevice, width, height,
            false, SurfaceFormat::R8G8B8A8_UNorm, DepthFormat::None);

        fxaa->SetViewport(width, height);
        spriteRenderer->SetProjectionMatrix(Matrix4x4::CreateOrthographicLH(width, height, 1.0f, 100.0f));
    });
}
예제 #30
0
파일: AudioClip.cpp 프로젝트: Mourtz/pomdog
//-----------------------------------------------------------------------
Detail::SoundSystem::NativeAudioClip* AudioClip::NativeAudioClip()
{
    POMDOG_ASSERT(nativeAudioClip);
    return nativeAudioClip.get();
}