Compartilhar via


Introdução ao OpenTK no Xamarin.Mac

OpenTK (The Open Toolkit) é uma biblioteca C# avançada e de baixo nível que facilita o trabalho com OpenGL, OpenCL e OpenAL. OpenTK pode ser usado para jogos, aplicações científicas ou outros projetos que exigem gráficos 3D, áudio ou funcionalidade computacional. Este artigo fornece uma breve introdução ao uso do OpenTK em um aplicativo Xamarin.Mac.

Uma execução de aplicativo de exemplo

Neste artigo, abordaremos os conceitos básicos do OpenTK em um aplicativo Xamarin.Mac. É altamente recomendável que você trabalhe primeiro no artigo Olá, Mac, especificamente nas seções Introdução ao Xcode e ao Construtor de Interface e Saídas e Ações, pois ele aborda os principais conceitos e técnicas que usaremos neste artigo.

Você pode querer dar uma olhada na seção Expondo classes C# / métodos para Objective-C do documento Xamarin.Mac Internals também, ele explica os Register comandos e Export usados para conectar suas classes C# a Objective-C objetos e elementos da interface do usuário.

Sobre o OpenTK

Como dito acima, OpenTK (The Open Toolkit) é uma biblioteca C# avançada e de baixo nível que facilita o trabalho com OpenGL, OpenCL e OpenAL. Usar o OpenTK em um aplicativo Xamarin.Mac fornece os seguintes recursos:

  • Desenvolvimento rápido - O OpenTK fornece tipos de dados fortes e documentação em linha para melhorar seu fluxo de trabalho de codificação e detectar erros com mais facilidade e rapidez.
  • Fácil integração - O OpenTK foi projetado para se integrar facilmente com aplicativos .NET.
  • Licença Permissiva - OpenTK é distribuído sob as licenças MIT/X11 e é totalmente gratuito.
  • Ligações ricas e seguras para o tipo - O OpenTK suporta as versões mais recentes do OpenGL, OpenGL|ES, OpenAL e OpenCL com carregamento automático de extensão, verificação de erros e documentação em linha.
  • Opções de GUI flexíveis - O OpenTK fornece a janela de jogo nativa e de alto desempenho projetada especificamente para jogos e Xamarin.Mac.
  • Código totalmente gerenciado e compatível com CLS - O OpenTK suporta versões de 32 bits e 64 bits do macOS sem bibliotecas não gerenciadas.
  • 3D Math Toolkit OpenTK fornece Vector, MatrixQuaternion e Bezier structs através de seu 3D Math Toolkit.

OpenTK pode ser usado para jogos, aplicações científicas ou outros projetos que exigem gráficos 3D, áudio ou funcionalidade computacional.

Para obter mais informações, consulte o site do Open Toolkit .

Guia de início rápido do OpenTK

Como uma introdução rápida ao uso do OpenTK em um aplicativo Xamarin.Mac, vamos criar um aplicativo simples que abre uma Visualização de Jogo, renderiza um triângulo simples nessa visualização e anexa a Visualização de Jogo à Janela Principal do aplicativo Mac para exibir o triângulo ao usuário.

Iniciando um novo projeto

Inicie o Visual Studio para Mac e crie uma nova solução Xamarin.Mac. Selecione Mac>App>General>Cocoa App:

Adicionando um novo aplicativo Cocoa

Digite MacOpenTK o Nome do Projeto:

Definindo o nome do projeto

Clique no botão Criar para criar o novo projeto.

Incluindo OpenTK

Antes de usar o Open TK em um aplicativo Xamarin.Mac, você precisa incluir uma referência ao assembly OpenTK. No Gerenciador de Soluções, clique com o botão direito do mouse na pasta Referências e selecione Editar Referências....

Faça uma verificação e OpenTK clique no botão OK :

Editando as referências do projeto

Usando o OpenTK

Com o novo projeto criado, clique duas vezes no MainWindow.cs arquivo no Gerenciador de Soluções para abri-lo para edição. Faça com que a MainWindow classe tenha a seguinte aparência:

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform.MacOS;
using Foundation;
using AppKit;
using CoreGraphics;

namespace MacOpenTK
{
    public partial class MainWindow : NSWindow
    {
        #region Computed Properties
        public MonoMacGameView Game { get; set; }
        #endregion

        #region Constructors
        public MainWindow (IntPtr handle) : base (handle)
        {
        }

        [Export ("initWithCoder:")]
        public MainWindow (NSCoder coder) : base (coder)
        {
        }
        #endregion

        #region Override Methods
        public override void AwakeFromNib ()
        {
            base.AwakeFromNib ();

            // Create new Game View and replace the window content with it
            Game = new MonoMacGameView(ContentView.Frame);
            ContentView = Game;
            Game.OpenGLContext.View = Game;

            // Wire-up any required Game events
            Game.Load += (sender, e) =>
            {
                // TODO: Initialize settings, load textures and sounds here
            };

            Game.Resize += (sender, e) =>
            {
                // Adjust the GL view to be the same size as the window
                GL.Viewport(0, 0, Game.Size.Width, Game.Size.Height);
            };

            Game.UpdateFrame += (sender, e) =>
            {
                // TODO: Add any game logic or physics
            };

            Game.RenderFrame += (sender, e) =>
            {
                // Setup buffer
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                GL.MatrixMode(MatrixMode.Projection);

                // Draw a simple triangle
                GL.LoadIdentity();
                GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
                GL.Begin(BeginMode.Triangles);
                GL.Color3(Color.MidnightBlue);
                GL.Vertex2(-1.0f, 1.0f);
                GL.Color3(Color.SpringGreen);
                GL.Vertex2(0.0f, -1.0f);
                GL.Color3(Color.Ivory);
                GL.Vertex2(1.0f, 1.0f);
                GL.End();

            };

            // Run the game at 60 updates per second
            Game.Run(60.0);
        }
        #endregion
    }
}

Vamos analisar esse código em detalhes abaixo.

APIs necessárias

Várias referências são necessárias para usar o OpenTK em uma classe Xamarin.Mac. No início da definição, incluímos as seguintes using afirmações:

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform.MacOS;
using Foundation;
using CoreGraphics;

Este conjunto mínimo será necessário para qualquer classe usando OpenTK.

Adicionando o modo de exibição do jogo

Em seguida, precisamos criar uma Visualização de Jogo para conter toda a nossa interação com o OpenTK e exibir os resultados. Utilizamos o seguinte código:

public MonoMacGameView Game { get; set; }
...

// Create new Game View and replace the window content with it
Game = new MonoMacGameView(ContentView.Frame);
ContentView = Game;

Aqui, fizemos a Visualização do Jogo do mesmo tamanho que a nossa Janela Principal do Mac e substituímos a Visualização de Conteúdo da janela pela nova MonoMacGameView. Como substituímos o conteúdo da janela existente, nosso Modo de Exibição Dado será redimensionado automaticamente quando as Janelas Principais forem redimensionadas.

Respondendo a eventos

Há vários eventos padrão aos quais cada Exibição de Jogo deve responder. Nesta seção serão abordados os principais eventos necessários.

O evento Load

O Load evento é o local para carregar recursos do disco, como imagens, texturas ou música. Para o nosso aplicativo de teste simples, não estamos usando o Load evento, mas o incluímos como referência:

Game.Load += (sender, e) =>
{
    // TODO: Initialize settings, load textures and sounds here
};

O evento Resize

O Resize evento deve ser chamado toda vez que o Game View for redimensionado. Para o nosso aplicativo de exemplo, estamos tornando o GL Viewport do mesmo tamanho que o nosso Game View (que é redimensionado automaticamente pela janela principal do Mac) com o seguinte código:

Game.Resize += (sender, e) =>
{
    // Adjust the GL view to be the same size as the window
    GL.Viewport(0, 0, Game.Size.Width, Game.Size.Height);
};

O evento UpdateFrame

O UpdateFrame evento é usado para manipular a entrada do usuário, atualizar posições de objetos, executar cálculos de física ou IA. Para o nosso aplicativo de teste simples, não estamos usando o UpdateFrame evento, mas o incluímos como referência:

Game.UpdateFrame += (sender, e) =>
{
    // TODO: Add any game logic or physics
};

Importante

A implementação Xamarin.Mac do OpenTK não inclui o Input API, então você precisará usar as APIs fornecidas pela Apple para adicionar suporte a teclado e mouse. Opcionalmente, você pode criar uma instância personalizada do MonoMacGameView e substituir os KeyDown métodos e KeyUp .

O evento RenderFrame

O RenderFrame evento contém o código que é usado para renderizar (desenhar) seus elementos gráficos. Para o nosso aplicativo de exemplo, estamos preenchendo a Visualização do Jogo com um triângulo simples:

Game.RenderFrame += (sender, e) =>
{
    // Setup buffer
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    GL.MatrixMode(MatrixMode.Projection);

    // Draw a simple triangle
    GL.LoadIdentity();
    GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
    GL.Begin(BeginMode.Triangles);
    GL.Color3(Color.MidnightBlue);
    GL.Vertex2(-1.0f, 1.0f);
    GL.Color3(Color.SpringGreen);
    GL.Vertex2(0.0f, -1.0f);
    GL.Color3(Color.Ivory);
    GL.Vertex2(1.0f, 1.0f);
    GL.End();

};

Normalmente, o código de renderização estará com uma chamada para GL.Clear remover quaisquer elementos existentes antes de desenhar os novos elementos.

Importante

Para a versão Xamarin.Mac do OpenTK , não chame o SwapBuffers método da instância MonoMacGameView no final do código de renderização. Isso fará com que a Visualização do Jogo seja rápida em vez de exibir sua visualização renderizada.

Executando a visualização do jogo

Com todos os eventos necessários definidos e a Visualização do Jogo anexada à Janela Principal do Mac do nosso aplicativo, somos lidos para executar a Visualização do Jogo e exibir nossos gráficos. Use o seguinte código:

// Run the game at 60 updates per second
Game.Run(60.0);

Passamos a taxa de quadros desejada que queremos que o Game View atualize, para o nosso exemplo, escolhemos 60 quadros por segundo (a mesma taxa de atualização da TV normal).

Vamos executar nosso aplicativo e ver a saída:

Uma amostra da saída dos aplicativos

Se redimensionarmos nossa janela, a Visualização do Jogo também será redimensionada e o triângulo também será redimensionado e atualizado em tempo real.

Qual o próximo passo?

Com o básico de trabalhar com OpenTk em um aplicativo Xamarin.mac feito, aqui estão algumas sugestões do que experimentar a seguir:

  • Tente alterar a cor do triângulo e a cor de fundo da Visualização do Jogo nos Load eventos e RenderFrame .
  • Faça o triângulo mudar de cor quando o usuário pressionar uma tecla nos eventos e RenderFrame ou faça sua própria classe personalizada MonoMacGameView e substitua UpdateFrame os KeyUp métodos eKeyDown.
  • Faça o triângulo se mover pela tela usando as teclas de reconhecimento no UpdateFrame evento. Dica: use o Matrix4.CreateTranslation método para criar uma matriz de tradução e chame o GL.LoadMatrix método para carregá-lo no RenderFrame evento.
  • Use um for loop para renderizar vários triângulos no RenderFrame evento.
  • Gire a câmera para dar uma visão diferente do triângulo no espaço 3D. Dica: use o Matrix4.CreateTranslation método para criar uma matriz de tradução e chame o GL.LoadMatrix método para carregá-lo. Você também pode usar as classes , Vector4Vector3e Matrix4 para manipulações de Vector2câmera.

Para obter mais exemplos, consulte o repositório GitHub de amostras do OpenTK. Ele contém uma lista oficial de exemplos de uso do OpenTK. Você terá que adaptar esses exemplos para usar com a versão Xamarin.Mac do OpenTK.

Resumo

Este artigo deu uma olhada rápida no trabalho com OpenTK em um aplicativo Xamarin.Mac. Vimos como criar uma Janela de Jogo, como anexar a Janela de Jogo a uma Janela de Mac e como renderizar uma forma simples na Janela de Jogo.