Introducción a OpenTK en Xamarin.Mac
OpenTK (Open Toolkit) es una biblioteca avanzada de C# de bajo nivel que facilita el trabajo con OpenGL, OpenCL y OpenAL. OpenTK se puede usar para juegos, aplicaciones científicas u otros proyectos que requieren gráficos 3D, audio o funcionalidad computacional. En este artículo se ofrece una breve introducción al uso de OpenTK en una aplicación de Xamarin.Mac.
En este artículo, trataremos los conceptos básicos de OpenTK en una aplicación de Xamarin.Mac. Se recomienda encarecidamente trabajar primero en el artículo Hello, Mac, específicamente en las secciones Introducción a Xcode e Interface Builder y Salidas y acciones, ya que trata conceptos clave y técnicas que usaremos en este artículo.
Es posible que quiera echar un vistazo a la sección Exponer clases o métodos de C# a Objective-C del documento sobre Aspecto internos de Xamarin.Mac, ya que explica los comandos Register
y Export
que se usan para conectar las clases de C# a objetos Objective-C y elementos de la interfaz de usuario.
Acerca de OpenTK
Como se indicó anteriormente, OpenTK (The Open Toolkit) es una biblioteca avanzada de C# de bajo nivel que facilita el trabajo con OpenGL, OpenCL y OpenAL. El uso de OpenTK en una aplicación de Xamarin.Mac proporciona las siguientes características:
- Desarrollo rápido: OpenTK proporciona tipos de datos sólidos y documentación insertada para mejorar su flujo de trabajo de codificación y detectar errores más fácil y rápidamente.
- Integración sencilla: OpenTK se diseñó para integrarse fácilmente con aplicaciones .NET.
- Licencia permisiva: OpenTK se distribuye bajo las licencias MIT/X11 y es totalmente gratuita.
- Enlaces ricos y con seguridad de tipos: OpenTK es compatible con las últimas versiones de OpenGL, OpenGL|ES, OpenAL y OpenCL con carga automática de extensiones, comprobación de errores y documentación insertada.
- Opciones de GUI flexibles: OpenTK proporciona la ventana de juegos nativa y de alto rendimiento diseñada específicamente para juegos y Xamarin.Mac.
- Código totalmente administrado compatible con CLS: OpenTK admite versiones de 32 y 64 bits de macOS sin bibliotecas no administradas.
- Kit de herramientas 3D Math OpenTK proporciona estructuras
Vector
,Matrix
,Quaternion
yBezier
a través de su Kit de herramientas 3D Math.
OpenTK se puede usar para juegos, aplicaciones científicas u otros proyectos que requieren gráficos 3D, audio o funcionalidad computacional.
Para más información, consulte el sitio web de The Open Toolkit.
Inicio rápido de OpenTK
Como introducción rápida al uso de OpenTK en una aplicación para Xamarin.Mac, vamos a crear una aplicación sencilla que abra una vista de juego, represente un triángulo sencillo en esa vista y adjunte la vista de juego a la ventana principal de la aplicación para Mac para mostrar el triángulo al usuario.
Iniciar un nuevo proyecto
Inicie Visual Studio para Mac y cree una nueva solución de Xamarin.Mac. Seleccione Mac>App>General>Cocoa App:
Escriba MacOpenTK
para el Nombre del proyecto:
Haga clic en el botón Crear para compilar el nuevo proyecto.
Inclusión de OpenTK
Para poder usar Open TK en una aplicación de Xamarin.Mac, debe incluir una referencia al ensamblado de OpenTK. En el Explorador de soluciones, haga clic con el botón derecho del ratón en la carpeta Referencias y seleccione Editar referencias....
Coloque una comprobación junto a OpenTK
y haga clic en el botón Aceptar:
Uso de OpenTK
Con el nuevo proyecto creado, haga doble clic en el archivo MainWindow.cs
del Explorador de soluciones para abrirlo y editarlo. Haga que la clase MainWindow
se parezca a lo siguiente:
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 a repasar este código en detalle a continuación.
API necesarias
Se requieren varias referencias para usar OpenTK en una clase Xamarin.Mac. Al principio de la definición hemos incluido las siguientes instrucciones using
:
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á necesario para cualquier clase que use OpenTK.
Adición de la Vista de juego
A continuación, necesitamos crear una Vista de juego para que contenga toda nuestra interacción con OpenTK y mostrar los resultados. Hemos usado el código siguiente:
public MonoMacGameView Game { get; set; }
...
// Create new Game View and replace the window content with it
Game = new MonoMacGameView(ContentView.Frame);
ContentView = Game;
Aquí hemos hecho que la vista del juego sea del mismo tamaño que la ventana principal de Mac y ha reemplazado la vista de contenido de la ventana por la nueva MonoMacGameView
. Como hemos reemplazado el contenido de la ventana existente, nuestra vista dada cambiará de tamaño automáticamente cuando se cambie el tamaño de la ventana principal.
Respuesta a eventos
Hay varios eventos predeterminados a los que debería responder cada Vista de juego. En esta sección se tratarán los eventos principales necesarios.
Evento Load
En el evento Load
se cargan recursos del disco como imágenes, texturas o música. Para nuestra sencilla aplicación de prueba, no estamos usando el evento Load
, pero lo hemos incluido como referencia:
Game.Load += (sender, e) =>
{
// TODO: Initialize settings, load textures and sounds here
};
Evento Resize
El evento Resize
debería ser llamado cada vez que se cambie el tamaño de la Vista del juego. Para nuestra aplicación de ejemplo, estamos haciendo que GL Viewport tenga el mismo tamaño que nuestra Vista de juego (que la ventana principal de Mac cambia automáticamente de tamaño) con el siguiente 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);
};
Evento UpdateFrame
El evento UpdateFrame
se usa para controlar la entrada del usuario, actualizar las posiciones de los objetos, ejecutar cálculos físicos o de inteligencia artificial. Para nuestra sencilla aplicación de prueba, no usamos el evento UpdateFrame
, pero lo hemos incluido como referencia:
Game.UpdateFrame += (sender, e) =>
{
// TODO: Add any game logic or physics
};
Importante
La implementación de Xamarin.Mac de OpenTK no incluye la Input API
, por lo que tendrá que usar las API proporcionadas por Apple para agregar compatibilidad con teclado y ratón. Opcionalmente puede crear una instancia personalizada de la MonoMacGameView
e invalidar los métodos KeyDown
y KeyUp
.
Evento RenderFrame
El evento RenderFrame
contiene el código que se usa para representar (dibujar) los gráficos. Para nuestra aplicación de ejemplo, estamos rellenando la Vista de juego con un triángulo simple:
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, el código de representación comenzará con una llamada a GL.Clear
para eliminar cualquier elemento existente antes de dibujar los nuevos elementos.
Importante
Para la versión Xamarin.Mac de OpenTK no llame al método SwapBuffers
de su instancia MonoMacGameView
al final de su código de representación. Si lo hace, la vista del juego se mostrará rápidamente en lugar de mostrar la vista representada.
Ejecutar la vista de juego
Con todos los eventos necesarios definidos y la Vista de juego adjunta a la ventana principal de Mac de nuestra aplicación, estamos listos para ejecutar la Vista de juego y mostrar nuestros gráficos. Use el código siguiente:
// Run the game at 60 updates per second
Game.Run(60.0);
Pasamos la velocidad de fotogramas deseada a la que queremos que se actualice la Vista de juego, para nuestro ejemplo hemos elegido 60
fotogramas por segundo (la misma velocidad de actualización que la TV normal).
Vamos a ejecutar nuestra aplicación y ver la salida:
Si cambiamos el tamaño de nuestra ventana, la Vista de juego también cambiará de tamaño y el triángulo también cambiará de tamaño y se actualizará en tiempo real.
¿Y ahora qué?
Una vez hechos los conceptos básicos para trabajar con OpenTk en una aplicación Xamarin.mac, aquí tiene algunas sugerencias de lo que puede probar a continuación:
- Pruebe a cambiar el color del triángulo y el color de fondo de la Vista de juego en los eventos
Load
yRenderFrame
. - Haga que el triángulo cambie de color cuando el usuario pulse una tecla en los eventos
UpdateFrame
yRenderFrame
o cree su propia claseMonoMacGameView
personalizada e invalide los métodosKeyUp
yKeyDown
. - Haga que el triángulo se mueva por la pantalla usando las teclas de reconocimiento en el evento
UpdateFrame
. Sugerencia: use el métodoMatrix4.CreateTranslation
para crear una matriz de traducción y llame al métodoGL.LoadMatrix
para cargarla en el eventoRenderFrame
. - Use un bucle
for
para representar varios triángulos en el eventoRenderFrame
. - Gire la cámara para dar una vista diferente del triángulo en el espacio 3D. Sugerencia: use el método
Matrix4.CreateTranslation
para crear una matriz de traducción y llamar al métodoGL.LoadMatrix
para cargarlo. También puede usar las clasesVector2
,Vector3
,Vector4
yMatrix4
para manipulaciones de cámara.
Para obtener más ejemplos, consulte el repositorio Ejemplos de OpenTK de GitHub. Contiene una lista oficial de ejemplos de uso de OpenTK. Tendrá que adaptar estos ejemplos para usarlos con la versión de Xamarin.Mac de OpenTK.
Resumen
En este artículo se ha echado un vistazo rápido al trabajo con OpenTK en una aplicación Xamarin.Mac. Hemos visto cómo crear una Ventana de juego, cómo unir la Ventana de juego a una Ventana de Mac y cómo representar una forma sencilla en la Ventana de juego.
Vínculos relacionados
- Hello, Mac
- Trabajar con Windows
- The Open Toolkit
- OS X Human Interface Guidelines (Directrices de interfaz humana de OS X)
- Introducción a las ventanas