Introducción a la Programación de Videojuegos y Gráficos

Tamaño: px
Comenzar la demostración a partir de la página:

Download "Introducción a la Programación de Videojuegos y Gráficos"

Transcripción

1 Introducción a la Programación de Videojuegos y Gráficos GRADO EN INGENIERÍA INFORMÁTICA Curso 2012/2013

2 T3: VIDEOJUEGOS 2D Y 3D 3.1. Estructura de un videojuego Motores gráficos(perspectivas, estructuras de datos y algoritmos de visualización, navegación) Física (conceptos, colisiones, proyectiles, motores de físicas) Programación gráfica 2D (APIs gráficas) Estructura de videojuegos 3D Programación gráfica 3D.

3 Programación gráfica en 3D XNA Permite el desarrollo de juegos en 3D. Sin embargo el desarrollo de juegos en 3D es ligeramente distinto del desarrollo en 2D. La principal diferencia se basa en el sistema de coordenadas utilizado. En 2D se usan dos coordenadas (obviamente), y la coordenada (0,0) coincide por defecto con la parte superior de la pantalla. En 3D se usan tres coordenadas (ninguna sorpresa aquí), sin embargo, la coordenada (0,0,0) no coincide, en principio con ningún punto de la pantalla, ya que su posición depende del punto en el que está situada la cámara, y del ángulo de dicha cámara. En el sistema de coordenadas 3D de XNA, la coordenada X, aumenta a la derecha, la coordenada Y hacia arriba y la coordenada Z hacia la camara (sistema right handed).

4 Cámaras Antes de dibujar una escena en 3D, es necesario definir las propiedades de una cámara: Donde está colocada. Dirección en la que apunta. Propiedades adicionales. Las cámaras almacenan estas propiedades en un objeto de tipo Matrix. Una cámara necesita dos objetos de tipo Matrix para ser representada. La matriz de vista. Contiene la situación de la matriz, donde apunta y cual es su orientación. La matriz de proyección. Define como es la transformación de coordenadas 3D a las coordenadas 2D de la pantalla.

5 Cámaras (I). Para crear una matriz de vista es necesario llamar al procedimiento CreateLookAt de la clase Matrix. La matriz de vista contiene los siguientes campos: cameraposition Vector3 Coordenadas de la posición de la cámara cameratarget Vector3 Coordenadas del punto hacia el que mira la cámara. cameraupvector Vector3 Vector que indica que dirección es arriba. Para crear una matriz de proyección es necesario llamar al procedimiento CreatePerspectiveFieldOfView de la clase Matrix. La matriz de proyección contiene los siguientes campos: fieldofview float Ángulo de vista la camara en radianes, usualemente 45 grados, o π/4. aspectratio float Relación de aspecto de la cámara, usualemente el ancho de la pantalla dividido por el alto. nearplanedistance float Punto más próximo a la camara en el cual un objeto aun se puede ver. farplanedistance float Punto más lejano a la camara en el cual un objeto aun se puede ver.

6 Cámaras (III). La matriz de proyección define el campo de visión de la cámara. Arriba Cerca Cámara Derecha Lejos No se representarán aquellos objetos que estén situados fuera del campo de visión de la camara.

7 Cámaras (IV). Vamos a crear una cámara. Para ello, cread un nuevo proyecto de XNA 4 denominado Camara3D. En esta ocasión vamos a usar los patrones, así como las propiedades de la programación orientada a objetos desde el primer momento. Cread una nueva clase Camara, usando el patrón GameComponent, dentro de los patrones de la ventana de la izquierda. Dentro de la clase, añadid las dos matrices de definición de la cámara. public Matrix view {get; protected set;} public Matrix projection { get; protected set; } Y sustiuid el constructor por defecto por el siguiente. public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up): base(game) { view = Matrix.CreateLookAt(pos, target, up); projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)game.window.clientbounds.width /(float)game.window.clientbounds.height,1, 100); }

8 Cámaras (V). Ahora es necesario añadir la cámara a la lista de componentes del juego. Para ello declarad un variable Camera como variable de la clase Screen o de la clase Game1. Camera camara; Y añadid la cámara al conjunto de componentes dentro del procedimiento Initialize() de la clase Game1 camara = new Camera(this, new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up); Components.Add(camara); Compilad y ejecutad. No aparece nada, pero acabamos de crear una cámara que está en la posición (0,0,5), que mira al origen de coordenadas (Vector3.zero), y que tiene una orientación paralela al eje Y (Vector3.Up).

9 Primitivas de dibujo (I). Vamos a dibujar ahora algunos objetos en la pantalla, en particular vamos a empezar dibujando un triangulo. Para ello necesitamos primero definir la posición de sus vértices mediante un objeto de tipo VertexPositionColor. También es necesario definir un buffer de vértices de tipo VertexBuffer en el que se almacena la información necesaria para dibujar en el dispositivo gráfico y un objeto de tipo BasicEffect necesario para las primitivas de dibujo Añadid las siguientes variables a la clase Game1 VertexPositionColor[] verts; VertexBuffer vertexbuffer; BasicEffect effect;

10 Primitivas de dibujo (II). Ahora creamos los vértices del triángulo y los añadimos al buffer de vértices en el procedimiento LoadContent() de la clase Game1 verts = new VertexPositionColor[3]; verts[0] = new VertexPositionColor(new Vector3(0, 1, 0), Color.Blue); verts[1] = new VertexPositionColor(new Vector3(1, -1, 0), Color.Red); verts[2] = new VertexPositionColor(new Vector3(-1, -1, 0), Color.Green); vertexbuffer = new VertexBuffer(GraphicsDevice, typeof(vertexpositioncolor),verts.length, BufferUsage.None); vertexbuffer.setdata(verts); Una vez inicializado los datos del buffer de datos es necesario crear los efectos, para ello añadid el siguiente código en el procedimiento LoadContent() effect = new BasicEffect(GraphicsDevice); Finalmente añadimos el código de dibujo del triángulo en el prodimiento Draw() GraphicsDevice.SetVertexBuffer(vertexBuffer); effect.world = Matrix.Identity; effect.view = camara.view; effect.projection = camera.projection; effect.vertexcolorenabled = true; foreach (EffectPass pass in effect.currenttechnique.passes) { pass.apply(); GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1); } Compilad y ejecutad.

11 Primitivas de dibujo (III). La situación actual de la escena es la siguiente: y (0,1,0) x (0,0,5) (-1,-1,0) z (1,-1,0)

12 Primitivas de dibujo (IV). En XNA todos los objetos 3D se dibujan usando un lenguaje de alto nivel basado en C (el High Level Shader Language HLSL). Para poder acceder a dicho lenguaje es necesario crear un objeto de tipo Effect. En XNA existe la clase BasicEffect derivada de Effect que permite utilizar algunas funciones del HLSL sin necesidad de conocer el lenguaje. El campo world del objeto effect representa la posición donde los objetos van a ser dibujados. Usar la matriz identidad (Matriz.Identitiy) indica que el objeto se dibujará en el origen de coordenadas. Los campos view y projection los obtenemos a partir de los campos correspondientes del objeto camara que hemos creado. El campo VertexColorEnabled indica si los vértices tienen información de color o no.

13 Primitivas de dibujo (V). Cada efecto consta de una o mas técnicas (techniques), que a su vez constan de uno o mas pases (passes). Para aplicar una técnica es necesario implementar un bucle que aplica cada uno de los pases de la técnica. Dentro del bucle es necesario llamar al procedimiento Apply del pase (similar al SpriteBatch.Begin de 2D) antes de utilizar cualquier primitiva de dibujo. Finalmente dibujamos el triángulo llamando al procedimiento DrawUserPrimitives del objeto GraphicsDevice. public void DrawUserPrimitives<T> ( PrimitiveType primitivetype, T[] vertexdata, int vertexoffset, int primitivecount ) where T : struct Parámetros de tipo T Tipo de datos por vértice. Parámetros primitivetype Describe el tipo primitivo que se representa. vertexdata Datos de vértice. vertexoffset Desplazamiento (en vértices) desde el principio del búfer hasta que se empiezan a leer los datos. primitivecount Número de primitivas que se van a representar.