domingo, 30 de junio de 2013

6 .-. Texturizar.

Bien vamos a texturizar un cuadrado con una textura de tipo "tablones de madera" para lo que necesitaré una imagen con la textura. Antes de ponernos con el código, tenemos que entender qué estamos haciendo al texturizar, y para ello es necesario entender lo que son los Texels.

Un Texel es un píxel pero de una textura. Da igual el tamaño de la imagen de la textura, para nosotros tendrá unas coordenadas mínimas de (0,0) y una máxima de (1,1). A la parte vertical de la textura le llamaremos V y a la horizontal U. Espero que este gráfico explique un poco la cuestión.

Vamos ahora a por el código. Para poder emplear una textura necesitamos un objeto de tipo Texture que sea el que se encargue de contener a la textura. La textura está en un fichero JPG y tendremos que cargarla. La ruta al fichero de la textura es, desde la carpeta de la aplicacion "\3D\Texturas\Madera.jpg". Para esto vamos a la clase Motor y, arriba de todo definimos este objeto:

    Private TexturaMadera As Texture

A continuación cargamos la textura dentro de POSCONFIGURARDX en la misma clase Motor.

  TexturaMadera = TextureLoader.FromFile(DP3, Application.StartupPath & "\3D\Texturas\Madera.jpg")

Estamos empleando la clase TextureLoader propio de DX que implementa muchas funciones de carga de texturas. Bien, ahora vamos a crear un cuadrado que texturizar y entender qué es esto del u,v. Para crear este cuadrado voy a emplear una cosa nueva llamada VertexBuffer, que es un conjunto de vértices sobre los que quiero hacer algo. Hay varios tipos de VertexBuffer, los de solo posición y color, posición color y textura, posición y textura, posición textura y normal... Vamos a emplear uno de Posición Color y Textura por ahora. Arriba de todo, debado de TexturaMadera vamos a indicar esto:

      Private LosVertices(3) As CustomVertex.PositionTextured

Y vamos a crear un Sub para definir el cuadrado, dentro de la clase Motor.

    Private Sub HacerCuadrado()

        Try
           
LosVertices(0) = CrearVerticeConTextura(-100, 0, -100, Color.FromArgb(255, 0, 40).ToArgb, 0, 0)
           
LosVertices(1) = CrearVerticeConTextura(100, 0, -100, Color.FromArgb(255, 0, 40).ToArgb, 0, 1)
           
LosVertices(2) = CrearVerticeConTextura(-100, 0, 100, Color.FromArgb(0, 0, 180).ToArgb, 1, 0)
           
LosVertices(3) = CrearVerticeConTextura(100, 0, 100, Color.FromArgb(0, 0, 180).ToArgb, 1, 1)
        Catch ex As exception
        End Try
    End Sub

Nos queda por fijar qué es eso de CrearVérticeConTextura, pues es una función a la que pasaremos todos esos parámetros que veis ahí y que es algo como esto:

    Private Function CrearVerticeConTextura(ByVal X As Single, ByVal Y As Single, ByVal Z As Single, ByVal Color As Integer, tu As Single, tv As Single) As CustomVertex.PositionTextured

        Dim Vertex As CustomVertex.PositionTextured = New CustomVertex.PositionTextured

        Vertex.Position = New Vector3(X, Y, Z)
        Vertex.Tu = tu
        Vertex.Tv = tv

        Return Vertex

    End Function

Y esto qué es? Pues es una función a la que pasamos X,Y,Z como posiciones del vértice (punto) del cuadrado que queremos hacer. También le pasamos un color y unos valores de U y V para la textura. Recordad que este tipo de vértices guardan posiciones, colores y texturas. El vértice creado aquí se guarda en el array de LosVertices. Para poder usarlo, simplemente vamos a POSCONFIGURARDX y llamamos a HacerCuadrado.

            TexturaMadera = TextureLoader.FromFile(DP3, Application.StartupPath & "\3D\Texturas\Madera.jpg")
            Me.HacerCuadrado()

Esto creará los vértices y los valores de U y V para la textura. Pero ¿como hacemos para dibujar? Pues nos vamos al Render y ahí lo dejáis como este:

     Public Sub Render(ByRef DP3 As Direct3D.Device, vc As Vector3)
        Try

            DP3.Clear(ClearFlags.Target, Color.Black, 1.0F, 0)
            Me.Luces(DP3)
            DP3.BeginScene()
          
            PintaTexto(New Drawing.Point(20, 20), "Hola Render")

            DP3.Material = MAterial

            DP3.VertexFormat = CustomVertex.PositionColoredTextured.Format
            DP3.Transform.World = Matrix.Translation(0, 0, 0)
            DP3.SetTexture(0, TexturaMadera)
            DP3.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, Losvertices)

            DP3.VertexFormat = CustomVertex.PositionColored.Format
            DP3.SetTexture(0, Nothing)
            DP3.Transform.World = Matrix.Translation(0, 0, 0)
            Caja.DrawSubset(0)
            PintaTexto(New Drawing.Point(20, 80), "CAM:" & vc.X & "," & vc.Y & "," & vc.Z)

            DP3.EndScene()
            DP3.Present()
        Catch ex As DirectXException
            MessageBox.Show(ex.Message)
        End Try
    End Sub
 


Listo. Al ejecutar veréis la caja, ¿pero y el suelo? No aparece a menos que con la tecla Z bajéis la coordenada Y. Entonces aparece el suelo. Este se ve solamente desde "abajo" si aumentais la Y hacia Y+ ¿Qué está pasando?

No hay comentarios:

Publicar un comentario