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.
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
,Matrix
Quaternion
eBezier
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:
Digite MacOpenTK
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 :
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:
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 eRenderFrame
. - 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 personalizadaMonoMacGameView
e substituaUpdateFrame
osKeyUp
métodos eKeyDown
. - Faça o triângulo se mover pela tela usando as teclas de reconhecimento no
UpdateFrame
evento. Dica: use oMatrix4.CreateTranslation
método para criar uma matriz de tradução e chame oGL.LoadMatrix
método para carregá-lo noRenderFrame
evento. - Use um
for
loop para renderizar vários triângulos noRenderFrame
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 oGL.LoadMatrix
método para carregá-lo. Você também pode usar as classes ,Vector4
Vector3
eMatrix4
para manipulações deVector2
câ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.