65.9K
CodeProject 正在变化。 阅读更多。
Home

在MONO/.NET中基于OpenGL/OpenTK的GUI工具包用于严肃应用的思考

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2016年1月25日

CPOL

4分钟阅读

viewsIcon

18034

downloadIcon

175

探讨OpenGL作为开发非游戏类炫酷应用的基础。

下载适用于Linux、.NET/MONO 4.0 和 OpenGL 的解决方案

引言

尽管微软在2010年10月宣布将从Silverlight转向HTML 5以实现跨平台解决方案,并且Moonlight(2011年12月)已被放弃,但使用.NET开发跨平台应用的需求似乎在不断增长。MonoMonoDevelop依然活跃且状态良好,微软在2014年11月宣布并于2015年11月发布了.NET Core 5.0以改进跨平台和开源支持,而Xamarin则通过Mono和Xamarin.Forms以及Xamarin.iOS & Xamarin.Android成功支持iOS和Android。

鉴于这种情况,为Linux/Unix桌面开发MVVM/XAML应用,难道不是一个绝佳的主意吗?共享尽可能多的代码难道不会带来益处吗?

背景

目前,主导Linux/Unix领域的GTK+和Qt都不支持MVVM/XAML。Roma Widget Set对MVVM/XAML的支持是一个不错的概念验证,但从一开始就仅限于控件功能。(它基于Xlib/X11和X11扩展。)

为了提供与微软基于DirectX的MVVM/XAML实现WPF相竞争的补充,需要一个等效的基础,例如OpenGL

已经进行了两次初步调查来验证这种方法

  1. 在MONO/.NET中开始使用OpenGL/OpenTK用于严肃应用,以及
  2. 在MONO/.NET中,使用OpenGL/OpenTK进行文本渲染的摘要

结果看起来非常有前景,因此,我开始追随这一愿景:OpenGL Presentation Foundation

您对此有何看法? 如果您能对这个想法发表评论,我将非常高兴!

Using the Code

请阅读文章 在MONO/.NET中开始使用OpenGL/OpenTK用于严肃应用,了解有关最小开发环境设置(Mesa、Mono+MonoDevelop、OpenTK)的信息。

与此同时,我已切换到openSUSE Leap 42,并将MonoDevelop更新到5.10版本。(我建议仔细阅读下载信息——并通过“一键安装”下载“Mono:Factory”中的Linux发行版软件包,而不是Xamarin软件包。)

openSUSE Leap 42自带的MonoDevelop 5.0.1版本在调试会话中经常崩溃。MonoDevelop 5.10版本则稳定得多(即使它被宣布为一个可能不稳定的软件包)。我希望不久的将来能有一个与旧的32位版本2.4.1一样稳定且高效的MonoDevelop 64位版本。

对于文本输出,使用了增强版的FtFont类(请阅读文章 在MONO/.NET中,使用OpenGL/OpenTK进行文本渲染的摘要 以获取详细信息)。

首个严肃外观应用:OpenGL Presentation Foundation - OpfDesigner-01

示例应用程序演示了DockPanelMenuMenuItemButton控件的基本实现,以及MouseOver行为和Click回调。

该解决方案包含两个项目

  • OpfPreprocessor,包含XAML预处理器的源代码
  • OpfDesigner,包含示例应用程序的源代码

以及References文件夹,其中包含OpenTKOpenGLPresentationFoundation的引用程序集。

要理解OpfPreprocessor的工作原理,请阅读文章 为X11编写XAML对话框应用程序 中的分步说明章节。

示例应用程序的解决方案是64位,并链接到.NET/MONO 4.0。所有必需的引用都包含在解决方案的子文件夹References中。OpenGL Presentation Foundation程序集未在源代码中提供,并且仅提供64位版本,因为目前源代码更改很大。

应用程序文件内容

XAML (App.xaml)

要查看的第一个XAML文件是App.xaml

<Application x:Class="OpfDesigner.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:OpfDesigner"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- <ResourceDictionary Source="RTheme.xaml"/> -->
    </Application.Resources>
</Application>

XAML代码完全兼容Microsoft® WPF。

代码隐藏 (App.xaml.cs)

对应的C#代码隐藏文件是App.xaml.cs

using System;
using System.Diagnostics;

// Replica
using System.Windows;

namespace OpfDesigner
{
    /// <summary>Interaction logic for App.xaml</summary>
    public partial class App : Application
    {
        
        // ###############################################################################
        // ### M E T H O D S
        // ###############################################################################

        #region Methods

        #endregion Methods
    }
}

完整的代码隐藏完全兼容Microsoft® WPF。

主视图文件内容

XAML (MainWindow.xaml)

要查看的第二个XAML文件是MainWindow.xaml

<Window x:Class="OpfDesigner.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:OpfDesigner"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel Name="MainDock">
        <Menu x:Name="MainMenu" DockPanel.Dock="Top">
            <MenuItem Name="File_MainMenuItem" Header="File"></MenuItem>
            <MenuItem Name="Edit_MainMenuItem" Header="Edit"></MenuItem>
        </Menu>
        <Button Name="Button1" Content="Button 1" IsEnabled="False"></Button>
        <Button Name="Button2" Content="Button 2"></Button>
        <Button Name="Button3" Content="Click me to close the window!"
                FontSize="16" Click="Button3_Click"></Button>
    </DockPanel>
</Window>

完整的XAML代码完全兼容Microsoft® WPF。

后端代码 (MainWindow.xaml.cs)

对应的C#代码文件是MainWindow.xaml.cs。它包含Button控件的Click委托。

using System;

// Replica
using  System.Windows;
using  System.Windows.Controls;

namespace OpfDesigner
{
    public partial class MainWindow : Window
    {
        
        /// <summary>The default constructor.</summary>
        public MainWindow ()
        {
            InitializeComponent ();
            // will be called after construction by generated code!
        }

        private void Button3_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}

完整的代码隐藏完全兼容Microsoft® WPF。

后续挑战

  • 对话框窗口
  • 弹出菜单等

关注点

使用OpenGL和XAML,是否可能创建基于MVVM设计模式的X11应用程序?目前,我的回答是:是的,可以!

历史

  • 2015年1月25日:首个版本
© . All rights reserved.