Fecha y hora actual: Sábado 19 Ene 2019 07:14
Índice del Foro

Foros de programación informática, diseño gráfico y Web

En esta comunidad intentaremos dar soporte de programación a todos los niveles, desde principiantes a profesionales de la informática, desarrollo de programas, programación web y mucho más.

Tutorial de DirectX para VB .NET (DirectX8+)

Responder al Tema Ir a página 123Siguiente

Índice del Foro > Visual Basic .NET > Tutorial de DirectX para VB .NET (DirectX8+)

Autor Mensaje
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Jueves 08 Oct 2009 19:33

Título del mensaje: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Introducción

Pues nada, a raíz de un "jueguillo" hecho por uno de nuestros colaboradores, el compañero joxeduke12, he seguido intentando mejorarlo usando el mismo lenguaje pero con .NET de fondo. Las siguientes mejoras de dicho juego y el original, pueden ser descargados en éste enlace, http://lospillaos.es/foro/siguiente-vt2792.html?amp;postdays=0&postorder=asc&start=15. El problema que surgía es que los componentes gráficos convencionales son muy lentos, incluso usando un componente llamado ASPRITE que supuestamente usa las DirectX y el cual es posible descargarse por algún lugar de la red. Ello es debido a que la petición gráfica pasa por diferentes capas hasta llegar al hardware, así que se hace necesario prescindir de los intermediarios y pasar "directamente" por su "manager" o "encargado".
En éste tutorial se intentará enseñar los métodos básicos para desarrollar "jueguillos" 2D con DirectX en VBasic, para que otro, si puede, continúe el legado o lo use a su antojo.


Comienzo

Primeramente me decanté por .NET, no sólo por la sencilles de uso de sus componentes, cómo Microsoft.DirectX.Direct3D el cual hay que referenciar. Si no porque además no conseguía hacer funcionar algunas funciones de la vieja dx8vb.dll, sólo consiguiendo usar un método de vértices que creaban un polígono con textura (que es posible que más adelante explique), a pesar de que existe una función Sprite en la DLL antes citada.
Comencemos pues. Primeramente debemos referenciar el componente .NET Microsoft.DirectX.Direct3D , para aquel que no lo sepa, una vez creado el proyecto clikeamos en la barra del menú, en Proyectos->Agregar referencia (versión española) y buscamos la citación comentada. Luego incluimos en la cabecera del código más de lo mismo:

Código:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D




Y ya estamos listos para empezar.


Primer paso, incialización

La inicialización y configuración del dispositivo abstracto, que accede al hardware por nosostros, requiere del uso de un objeto clave, que será declarado de la siguiente forma, para ello usamos un nombre significativo:

Dim dispositivo As Direct3D.Device

Dicho dispositivo representará a la parte gráfica, encargándose éste de buscarse la vida para poner imágenes y hacer todo lo que le pidamos. Antes de asignarle el dispositivo, pues de momento sólo lo hemos "declarado", hay que pasarle unos parámetros, los cuales enseñaremos los mínimos indispensables, ya que son muchos. Siendo los siguientes: El SwapEffect, BackBufferWidth, BackBufferHeight y Windowed. Para ello declaramos e incializamos los parámetros de la siguiente forma:

Código:
        Dim parametro As PresentParameters = New PresentParameters
        parametro.SwapEffect = SwapEffect.Discard ' Descartamos efectos en el volcado
        parametro.BackBufferWidth = Me.Width ' Asignamos ancho del formulario
        parametro.BackBufferHeight = Me.Height ' Asignamos la altura del formulario
        parametro.Windowed = True ' Se ejecutará en modo ventana
...
...

seguidamente asignamos el dispositivo...

Código:
...
dispositivo = New Direct3D.Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, parametro)


Ya está... ven que fácil. Ya tenemos una aplicación DirectX, que no hace nada.


Dibujar Sprites

La forma para declarar e inicializar un objeto Sprite se puede resumir todo en una sóla línea.

Dim MiSprite As Sprite=New Sprite(dispositivo)

Ahora disponemos de un objeto Sprite, pero el Sprite por si sólo no hace nada, necesitamos la textura o imagen que queramos mostrar. Por lo tanto habrá que declarar e inicializar la textura que vestirá nuestro Sprite. Hay que añadir que es posible usar todo tipo de formatos bitmaps, pero para evitar embrollos innecesarios yo recomendaría usar para Sprites que usan Canal Alpha o transparencia, un fichero PNG, que previamente desde un editor gráfico hayamos asignado el color transparente.

Dim textura As Texture = TextureLoader.FromFile(dispositivo, Fichero)

Habrá que incluir estás tres líneas después de crear el dispositivo, si queremos que funcionen las transparencias.

Código:
        dispositivo.RenderState.AlphaBlendEnable = True
        dispositivo.RenderState.SourceBlend = Blend.SourceAlpha
        dispositivo.RenderState.DestinationBlend = Blend.InvSourceAlpha


Bueno, una vez que ya tenemos preparados el Sprite con su correspondiente textura, ya sólo nos falta pasar al Render. El Render, es el proceso de pintado en el buffer, y el volcado de éste a la pantalla visible. Para ello DirectX usa un método muy similar a OpenGl, por si alguien no lo ha usado lo explicaré. Consiste en dos métodos del objeto dispositivo, una de comienzo, BeginScene, y otra de fin, EndScene. Dentro de éstos dos métodos, se registrarán todas las peticiones gráficas y todas las peticiones gráficas que se encuentren fuera de los mencionados métodos se omitirá. Luego hay un tercer método, Present, que se encarga de llevar estas peticiones al "sumo sacerdote" o "manager" que invocará con su magia todo lo necesario para que veamos los gráficos por la pantalla.

Código:
...
...
' Bucle infinito

dispositivo.BeginScene() ' Comienzo del buffer

' Aqui dibujamos lo que queramos

dispositivo.EndScene() ' Fin del buffer

dispositivo.Present() ' Muestra por pantalla el resultado
...
...


Ahora que ya sabemos el procedimiento del Render, sólo falta sustituir la línea ' Aqui dibujamos lo que queramos del ejemplo anterior, por éstas líneas, que muestran el procedimiento para dibujar un Sprite.

Código:
MiSprite.Begin(SpriteFlags.None) ' comenzamos a pintar nuestro sprite
MiSprite.Draw2D(textura _ ' Obviamente, la textura
                  , New Point(0, 0) _ ' El centro del Sprite, tiene su explicacion
                  , 0 _ ' El angulo de rotacion (lo podemos girar)
                  , New Point(100, 50) ' Las coordenadas X e Y de la pantalla
                  , Color.White) ' Filtro de color
MiSprite.Flush()
MiSprite.End() ' Fin del pintado


Aparte de Draw2D, Sprite incluye otro método más complejo que permite hacer más filigranas cómo escalados, recortes, etc... Draw, pero eso ya lo dejo a ustedes para que practiquen e investiguen por cuenta propia. Próximamente o cuando tenga ganas explicaré otras historias de las DirectX. Espero que les sea util, chao!! Ordenador Ordenador

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
weirdmix
Moderador Global


Registrado: 08 May 2008
Mensajes: 1372
Ubicación: Cancún - MEXICO

Mensaje Publicado: Lunes 12 Oct 2009 17:57

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

te has ganado un seguidor!!!!
excelente!!!

Aplauso Aplauso Aplauso

por cierto, yo lo voy a hacer con C#, no creo q existe mucha diferencia o si?


------------------------------
WeirdMix
Colaborador y Moderador Global
Volver arriba
Ver perfil del usuario Enviar mensaje privado Enviar correo MSN Messenger
Tesis
Administrador


Registrado: 04 Mar 2007
Mensajes: 3200
Ubicación: Valencia - España

Mensaje Publicado: Lunes 12 Oct 2009 19:12

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Sencillo, pero realmente bueno Ok Ok Ok

Excelente.


Normas del foro
Aprende a postear correctamente usando las etiquetas
Volver arriba
Ver perfil del usuario Enviar mensaje privado
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Lunes 12 Oct 2009 19:19

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

No hay ninguna diferencia, es más, casi toda la documentación que encontraba sobre DirectX para .NET estaba para C sharp, realmente, es desarrollarlo donde uno esté más cómodo... si bien es verdad que no se puede comparar, un ejecutable .NET con un binario Win32, en lo que se refiere a velocidad de ejecución (aunque Microsoft presuma que en Vista .NET corre más rápido que en XP)...

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
Arael25
Colaborador


Registrado: 13 Mar 2007
Mensajes: 611
Ubicación: Lima - Peru

Mensaje Publicado: Martes 13 Oct 2009 04:17

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

a ver si no me equivoco...
este sub foro es vb 6.0 y aqui se ventila en .net

disculpen que sea espezo pero no deberia ir a .net

Amigos Ordenador


Me olvide de ustedes pero ya volvi para quedarme
Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor MSN Messenger
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Martes 13 Oct 2009 19:21

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Tienes razón Azrael, y no tengo reparo en que lo muevas a .NET...

...gracias por su atención (ding dong)

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
Tesis
Administrador


Registrado: 04 Mar 2007
Mensajes: 3200
Ubicación: Valencia - España

Mensaje Publicado: Martes 13 Oct 2009 21:20

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Lo muevo yo Fumao


Normas del foro
Aprende a postear correctamente usando las etiquetas
Volver arriba
Ver perfil del usuario Enviar mensaje privado
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Jueves 25 Feb 2010 01:57

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

LUCES Y OBJETOS 3D

Introducción

Bueno, brevemente explicaré cómo usar gráficos 3D y cómo aplicar luces en las escenas usando cómo no, las DirectX en .NET. Increiblemente después de haberme regalado a mi mismo la Xbox 360, me puse a probar la librería XNA, que supuestamente es un wrapper (un envolvente) de las DirectX y supuestamente sus creadores (El equipo de Brian Keller y cia) creen que el desarrollo de videojuegos con esa cosa será el no va más. Y cómo comentaba, increíblemente, porque las XNA, para quien no haya tenido contacto, repito, con esa cosa, es lo peor de lo peor. Sencillamente es más fácil usar directamente las X que trabajar con eso. Sobre todo porque mucho del trabajo se realiza directamente con los shaders. Ya en otra ocasión haré también otro tutorial de las XNA, y ya comprobareis la tremenda diferencia. Pero antes del XNA, mostraré mis pequeños conocimientos con Tao-FrameWork, usando OpenGl en .NET, si si, cómo han leído, OPENGL. Pero cómo decía el narrador de "Conan el barbaro" al final de la peli; "..eso es otra historia..".

Comienzo

Vamos a lo que vamos. Básicamente lo mismo que explique anteriormente, inicializar el dispositivo, parámetros, etc.. es casi todo idéntico.

Código:
        Dim Parametros As PresentParameters = New PresentParameters
        Parametros.SwapEffect = SwapEffect.Discard
        Parametros.BackBufferHeight = Me.Height
        Parametros.BackBufferWidth = Me.Width
        Parametros.AutoDepthStencilFormat = DepthFormat.D16
        Parametros.EnableAutoDepthStencil = True
        Parametros.Windowed = True

        ' Creamos dispositivo
        dispositivo = New Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, Parametros)

        ' Transparencias
        dispositivo.RenderState.AlphaBlendEnable = True
        dispositivo.RenderState.SourceBlend = Blend.SourceAlpha
        dispositivo.RenderState.DestinationBlend = Blend.InvSourceAlpha


Ya tenemos el dispositivo a punto y listo.

Luces

Para escenas estáticas, no necesitaremos actualizar las luces, es más solo debemos inicializarlas y éstas se aplicaran con la escena. Para trabajar con las luces se usará el dispositivo (Microsoft.DirectX.Direct3D.Device) que previamente ya habíamos inicializado y declarado (no por este orden). El dispositivo contiene un miembro de nombre Light que contiene una serie de propiedades elementales para habilitar dicha luz.

Primero me olvidaba comentar que hay que habilitar el render de la luz

Código:
        dispositivo.RenderState.Lighting = True


Luego parametrizamos la luz, en éste caso pondremos una luz puntual de color violeta

Código:
        dispositivo.Lights(0).Type = LightType.Point
        dispositivo.Lights(0).Diffuse = Color.Violet
        dispositivo.Lights(0).Range = 100
        dispositivo.Lights(0).Specular = Color.Violet
        dispositivo.Lights(0).Position = New Vector3(0, 5, 0)
        dispositivo.Lights(0).Attenuation0 = 0.1
        dispositivo.Lights(0).Update()
        dispositivo.Lights(0).Enabled = True


Pero ojo, no sólo por contener luz en una escena los objetos se iluminaran. Entre otras cosas será necesario aplicar un material. En éste caso lo aplicaremos a toda la escena de ésta forma, para ello lo haremos transparente, luego ya vosotros podréis jugar con los parámetros y sacar vuestras propias conclusiones.

Código:
        ' Configura el efecto producido por la luz sobre el objeto
        ' de lo contrario lo veriamos en Negro si activamos la Luz
        Dim mat As Material = New Material()
        mat.Ambient = Color.Transparent
        mat.Diffuse = Color.Transparent
        dispositivo.Material = mat


Ya está. Y se hizo la luz...

Vertices 3D

Por lo general, los objetos 3D nos lo tendremos que currar. Para ello podremos usar primitivas, al igual que en Open-Gl, podremos hacer objetos basados en triángulos, cuadrados o polígonos. Creando para ello una lista de vértices que se procesaran con los métodos adecuados del dispositivo. Para simplificar el tutorial, trataremos con la clase CustomVertex. Los vértices podrán contener datos necesarios para aplicar una textura, colores sólidos o ambas cosas. Cómo nos moveremos en un espacio 3D, habrá que fijar los vértices con coordenadas XYZ.

Código:
        ' Creamos un objeto3D que lo almacenamos en un array
        Dim verts() As CustomVertex.PositionColoredTextured = New CustomVertex.PositionColoredTextured(3) {}
        verts(0) = New CustomVertex.PositionColoredTextured(0, 0, 0, Color.Red.ToArgb(), 0, 0)
        verts(1) = New CustomVertex.PositionColoredTextured(10, 0, 0, Color.Green.ToArgb(), 1, 0)
        verts(2) = New CustomVertex.PositionColoredTextured(5, 10, 0, Color.Yellow.ToArgb(), 1, 1)


Bueno aquí he creado unos tres puntos casi al boleo. Pero vale para entender cómo funciona el tema. Ahora sólo falta pasarlo al render, recordad cómo expliqué anteriormente, tiene que estar dentro del BeginScene y EndScene.

Código:
                    dispositivo.VertexFormat = CustomVertex.PositionColoredTextured.Format
                    dispositivo.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts)


Cómo veis hemos usado el método DrawUserPrimitive, al cual le decimos que tipo de primitivas, en éste caso es un triangulito (o eso parece), luego le decimos cuantos polígonos, lógicamente uno y al final le pasamos la matriz de vértices.

Mallas

Y ya por último acabamos con las mallas. Una malla es la representación consistente de varios polígonos. Aunque podríamos hacer mallas dibujando polígono por polígono, ésto nos llevaría mucho tiempo. Por lo que para trabajar con gráficos 3D muchos se deciden por emplear herramientas de diseño. Para nuestro ejemplo, usaremos el tigre que trae las SDK de DirectX 8, es un tigre muy bonito y sencillo. De momento no lo animaremos, eso lo dejamos para más adelante. Junto con el fichero X, además nos encontraremos con una textura. Si vais a usar otro fichero para éste tutorial, intentar que sea un objeto con una única textura.

Entonces lo primero es cargar la textura.

Código:
Dim tex As Texture = TextureLoader.FromFile(dispositivo, "Tiger.bmp")


Y ahora cargamos la malla o el objeto 3d.

Código:
        Dim Malla As Mesh
        Malla = Mesh.FromFile("Tiger.X", MeshFlags.DoNotClip, dispositivo)
        Malla = Malla.Clone(Malla.Options.Value, CustomVertex.PositionNormalTextured.Format, dispositivo)
        Malla.ComputeNormals()


Ya tenemos el objeto y la textura. Y ya para finalizar lo renderizamos, y vuelvo a recordar a la peña, que debe estar entre el BeginScene y el EndScene. Para renderizar la malla usamos el método DrawSubset de la Malla, y para texturizar SetTexture del dispositivo.

Código:
                    ' Objeto 3D
                    dispositivo.SetTexture(0, tex)
                    Malla.DrawSubset(0)


Podremos usar SetTexture también para el ejemplo anterior de los vértices.

Para los incrédulos, adjunto un enlace con un par de ejemplos:
http://ge.tt/8vBpaaB?c



Ultima edición por WhiteSkull el Sábado 24 Dic 2011 01:46; editado 2 veces
Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
Vila
Usuario Inquieto


Registrado: 14 May 2010
Mensajes: 137
Ubicación: Vulpesheim

Mensaje Publicado: Jueves 01 Jul 2010 22:35

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Estimado White Skull.
Muy bueno su tutorial sobre Direct X. Yo también lo pienso utilizar con el lenguaje C#, que me parece mucho más cómodo para la POO, pero de hecho el VB.NET es equivalente a él en potencia.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
Vila
Usuario Inquieto


Registrado: 14 May 2010
Mensajes: 137
Ubicación: Vulpesheim

Mensaje Publicado: Jueves 01 Jul 2010 22:43

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

WhiteSkull escribió:
LUCES Y OBJETOS 3D

Introducción

Bueno, brevemente explicaré cómo usar gráficos 3D y cómo aplicar luces en las escenas usando cómo no, las DirectX en .NET.

[...]

Para los incrédulos, adjunto un enlace con un par de ejemplos:
http://rapidshare.com/files/355415599/MisejemplosDirectX.rar.html
MD5: F8B54F3BD1A7AC25847A487411974372


Intenté descargar el ejemplo del sitio mencionado, pero me salió el sgte mensaje de error:

Cita:
Error

This file is neither allocated to a Premium Account, or a Collector's Account, and can therefore only be downloaded 10 times.

This limit is reached.

To download this file, the uploader either needs to transfer this file into his/her Collector's Account, or upload the file again. The file can later be moved to a Collector's Account. The uploader just needs to click the delete link of the file to get further information.


¿A qué se debe?

Volver arriba
Ver perfil del usuario Enviar mensaje privado
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Domingo 04 Jul 2010 22:34

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Vila agradezco tu interés por mi trabajo, volví a resubir el fichero, en cuanto al mensaje de rapidshare, limita las bajadas de ficheros, bien si lo descargas más de 10 veces o si pasan 60 días, mientras no disponga de cuenta en el mismo... algo que no pienso hacer, ya que no subo todos los días ficheros a la red... Guitarra

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Miércoles 28 Jul 2010 05:06

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

ANIMAR UN OBJETO 3D ANIMADO

Introducción

Que tal! Pues aquí de vuelta con los DirectX, que cómo indica el título de éste capítulo, vamos animar un fichero X animado, porque anteriormente ya habíamos tratado las luces, carga de ficheros X 'estáticcos', Sprites y fundamentos 3D. Entonces ahora toca ésto y luego pues se tocará para acabar el sonido y el control de datos de los dispositivos de entrada, suficiente pienso, para comenzar un modesto juego 3D completo, pero lo trataremos a su tiempo, así que tranquilos.

Antes que nada, el trabajo no es mío al cien por cien, realmente es una clase adaptada de RobyDx que a su vez extrajo la información del libro Managed DirectX 9 Kick Start de Tom Miller, así que las flores nos las repartimos todos Risa .

Comienzo

Para comenzar, tenemos que tener suficientemente claros los conceptos que aprendimos en los anteriores capítulos, y tener un buen nivel de programación en .NET. Entonces nos comeremos el paso de inicialización y declaración del dispositivo, aunque lo resumiremos con código, cualquier duda, repasen los capítulos anteriores.

Código:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Public Class Form1
    Private dispositivo As Device
    Private Parametros As PresentParameters

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

        Parametros = New PresentParameters()
        Parametros.AutoDepthStencilFormat = DepthFormat.D16
        Parametros.SwapEffect = SwapEffect.Discard
        Parametros.EnableAutoDepthStencil = True
        Parametros.BackBufferHeight = Me.Height
        Parametros.BackBufferWidth = Me.Width
        Parametros.Windowed = True

        dispositivo = New Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, Parametros)

        Me.SetStyle(ControlStyles.Opaque Or ControlStyles.AllPaintingInWmPaint, True)

    End Sub
...
...


Ya tenemos el dispositivo a punto y listo.

El material personalizado

Necesitaremos personalizar algunas de las clases ya existentes en la librería DirectX. Dado que no existe ninguna Clase que por si sola anime un objeto X animado. Entonces lo primero será empezar por crear un contenedor de materiales, que cómo indica su nombre, contendrá los materiales de la malla animada. El contenedor podrá contener materiales texturizados y sin texturizar.

Creamos una clase llamada MaterialPersonalizado, que contendrá el siguiente código:
Código:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

' Creamos nuestra clase para almacenar nuestros materiales personalizados
Public MustInherit Class ContenedorDeMaterial
    Public MustOverride Sub inicializa(ByVal dispositivo As Device, ByVal material As ExtendedMaterial, ByVal rutaDeLaTextura As String)
    Public MustOverride Sub aplica(ByVal dispositivo As Device)
    Public MustOverride Sub dispose()
End Class

Public Class SinMaterial
    Inherits ContenedorDeMaterial

    Public Overrides Sub inicializa(ByVal dispositivo As Device, ByVal material As ExtendedMaterial, ByVal rutaDeLaTextura As String)
    End Sub
    Public Overrides Sub aplica(ByVal dispositivo As Device)
    End Sub
    Public Overrides Sub dispose()
    End Sub
End Class

Public Class MaterialSinTexturizar
    Inherits SinMaterial
    Protected materia As Material

    Public Overrides Sub inicializa(ByVal dispositivo As Device, ByVal material As ExtendedMaterial, ByVal rutaDeLaTextura As String)
        MyBase.inicializa(dispositivo, material, rutaDeLaTextura)
        Me.materia = material.Material3D
        Me.materia.AmbientColor = Me.materia.DiffuseColor
    End Sub

    Public Overrides Sub aplica(ByVal dispositivo As Device)
        dispositivo.Material = Me.materia
    End Sub

    Public Overrides Sub dispose()
    End Sub
End Class

Public Class MaterialTexturizado
    Inherits MaterialSinTexturizar
    Private textura As Texture

    Public Overrides Sub inicializa(ByVal dispositivo As Device, ByVal material As ExtendedMaterial, ByVal rutaDeLaTextura As String)
        MyBase.inicializa(dispositivo, material, rutaDeLaTextura)

        If material.TextureFilename Is Nothing Then
            Return
        End If
        If rutaDeLaTextura = "" Then
            Me.textura = TextureLoader.FromFile(dispositivo, material.TextureFilename)
        Else
            Me.textura = TextureLoader.FromFile(dispositivo, rutaDeLaTextura & "\" & Convert.ToString(material.TextureFilename))
        End If
    End Sub

    Public Overrides Sub aplica(ByVal dispositivo As Device)
        dispositivo.SetTexture(0, textura)
        dispositivo.Material = materia
    End Sub

    Public Overrides Sub dispose()
        If textura IsNot Nothing Then
            textura.Dispose()
        End If
    End Sub
End Class


La malla personalizada

Al igual que con el contenedor de materiales, necesitaremos una malla especial que soporte animaciones, para ello usaremos un Mesh para crear nuestra malla personalizada, que soportará de momento nuestro material personalizado.

Creamos una clase llamada MallaPersonalizada, que contendrá el siguiente código:
Código:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Public MustInherit Class MallaBase(Of MallaPersonalizada As BaseMesh, MaterialPersonalizado As {ContenedorDeMaterial, New})
    Protected miMalla_ As MallaPersonalizada
    Protected listaDeMaterial As MaterialPersonalizado()
    Public Property miMalla() As MallaPersonalizada
        Get
            Return miMalla_
        End Get
        Set(ByVal valor As MallaPersonalizada)
            miMalla_ = valor
        End Set
    End Property
End Class

Public Class Malla(Of MaterialPersonalizado As {ContenedorDeMaterial, New})
    Inherits MallaBase(Of Mesh, MaterialPersonalizado)
    Public Sub New()
    End Sub

    Protected Overrides Sub Finalize()
        Try
            miMalla.Dispose()
            For i As Integer = 0 To listaDeMaterial.Length - 1
                listaDeMaterial(i).dispose()
            Next
        Finally
            MyBase.Finalize()
        End Try
    End Sub
End Class


Nuestra clase MallaAnimada

Y por último personalizamos AllocateHierarchy, el MeshContainer y el Frame, clases nativas de DirectX. Para luego dar paso a nuestra clase, MallaAnimada.

Creamos una clase llamada MallaAnimada, y metemos el código:
Código:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Public Class MallaAnimada(Of TMaterial As {ContenedorDeMaterial, New})
    Inherits BaseDeLaAnimacion(Of TMaterial, MallaAnimadaPersonalizada(Of TMaterial))
    Public Sub New(ByVal dispositivo As Device, ByVal filesrc As String, ByVal texRuta As String)
        MyBase.New(dispositivo, filesrc, texRuta)
    End Sub
End Class

Public MustInherit Class BaseDeLaAnimacion(Of MaterialPersonalizado As {ContenedorDeMaterial, New}, MallaPersonalizada As {BaseDeLaMallaAnimada(Of MaterialPersonalizado), New})
    Private fotogramaRaiz As AnimationRootFrame
    Private materialExtra As New List(Of ExtendedMaterial)()
    Private listaDeMaterial As New List(Of MaterialPersonalizado)()

    Public Sub New(ByVal dispositivo As Device, ByVal fichero As String, ByVal rutaDeLaTextura As String)
        ' Creamos un almacen que alojara del objeto X cargado, mallas y materiales
        Dim almacen As New AlojadorJerarquicoPersonalizado(Of MaterialPersonalizado, MallaPersonalizada)(dispositivo, Me, rutaDeLaTextura)
        ' Le indicamos la estructua jerarquica de la animacion de nuestro objeto X
        fotogramaRaiz = Mesh.LoadHierarchyFromFile(fichero, MeshFlags.Managed, dispositivo, almacen, Nothing)
        ' Personalizamos los fotogramas
        ConfiguraMatrizDeHuesos(DirectCast(fotogramaRaiz.FrameHierarchy, Fotograma))
    End Sub

    Friend Function MeteMaterial(ByVal dispositivo As Device, ByVal material As ExtendedMaterial, ByVal rutaDeLaTextura As String) As MaterialPersonalizado
        Dim i As Integer = 0
        For Each mate As ExtendedMaterial In materialExtra
            If mate.Equals(material) Then
                Return listaDeMaterial(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1))
            End If
        Next
        Dim nuevoMaterial As New MaterialPersonalizado()
        nuevoMaterial.inicializa(dispositivo, material, rutaDeLaTextura)
        listaDeMaterial.Add(nuevoMaterial)
        materialExtra.Add(material)
        Return nuevoMaterial
    End Function

    Private Sub ConfiguraMatrizDeHuesos(ByVal fotograma As Fotograma)
        ' Recursamos todas las veces que sean necesarias hasta tener convertidos todos los fotogramas
        If fotograma.MeshContainer IsNot Nothing Then ConfiguraMatrizDeHuesos(DirectCast(fotograma.MeshContainer, ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada)))
        If fotograma.FrameSibling IsNot Nothing Then ConfiguraMatrizDeHuesos(DirectCast(fotograma.FrameSibling, Fotograma))
        If fotograma.FrameFirstChild IsNot Nothing Then ConfiguraMatrizDeHuesos(DirectCast(fotograma.FrameFirstChild, Fotograma))
    End Sub

    Private Sub ConfiguraMatrizDeHuesos(ByVal contenedorPersonalizado As ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada))
        ' si el contenedor de mallas personalizado tiene informacion de la animacion
        If contenedorPersonalizado.SkinInformation IsNot Nothing Then
            Dim numhuesos_ As Integer = contenedorPersonalizado.SkinInformation.NumberBones
            ' tomamos todos los fotogramas del contenedor
            Dim MatrizDeFotogramas As Fotograma() = New Fotograma(numhuesos_ - 1) {}
            For i As Integer = 0 To numhuesos_ - 1
                ' Convertimos los fotogramas (Frame) al tipo de nuestra clase Fotograma
                Dim fotograma As Fotograma = DirectCast(Frame.Find(fotogramaRaiz.FrameHierarchy, contenedorPersonalizado.SkinInformation.GetBoneName(i)), Fotograma)
                If fotograma Is Nothing Then Throw New ArgumentException()
                MatrizDeFotogramas(i) = fotograma
            Next
            contenedorPersonalizado.PonFotogramas(MatrizDeFotogramas)
        End If
    End Sub

    Private Sub ActualizaMatrizDelFotograma(ByVal fotograma As Fotograma, ByVal matrixPadre As Matrix)
        ' Combinamos la matriz padre del fotograma actual y su propia matriz
        fotograma.MatrizTransformadaYCombinada = fotograma.TransformationMatrix * matrixPadre
        ' Si el fotograma actual, tiene hijos o no tiene hermanos, actualizamos de nuevo
        If fotograma.FrameSibling IsNot Nothing Then ActualizaMatrizDelFotograma(DirectCast(fotograma.FrameSibling, Fotograma), matrixPadre)
        If fotograma.FrameFirstChild IsNot Nothing Then ActualizaMatrizDelFotograma(DirectCast(fotograma.FrameFirstChild, Fotograma), fotograma.MatrizTransformadaYCombinada)
    End Sub

    Private Sub DibujaFotograma(ByVal dispositivo As Device, ByVal fotograma As Fotograma)
        Dim contenedorPersonalizado As ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada) = DirectCast(fotograma.MeshContainer, ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada))
        While contenedorPersonalizado IsNot Nothing
            DibujaContenedorDeMallas(dispositivo, contenedorPersonalizado)
            contenedorPersonalizado = DirectCast(contenedorPersonalizado.NextContainer, ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada))
        End While
        ' Si el fotograma actual, tiene hijos o tiene hermanos, volvemos a dibujar
        If fotograma.FrameSibling IsNot Nothing Then DibujaFotograma(dispositivo, DirectCast(fotograma.FrameSibling, Fotograma))
        If fotograma.FrameFirstChild IsNot Nothing Then DibujaFotograma(dispositivo, DirectCast(fotograma.FrameFirstChild, Fotograma))
    End Sub

    Private Sub DibujaContenedorDeMallas(ByVal dispositivo As Device, ByVal contenedorPersonalizado As ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada))
        If contenedorPersonalizado.MallaAnimada.tieneInformacionAnimada_ Then
            contenedorPersonalizado.MallaAnimada.Dibuja(dispositivo, contenedorPersonalizado.CogeFotogramas(), contenedorPersonalizado.materiales)
        End If
    End Sub

    Public Sub Anima(ByVal tiempo As Single, ByVal MatrixGlobal As Matrix)
        If fotogramaRaiz.AnimationController IsNot Nothing Then fotogramaRaiz.AnimationController.AdvanceTime(tiempo, Nothing)
        ActualizaMatrizDelFotograma(DirectCast(fotogramaRaiz.FrameHierarchy, Fotograma), MatrixGlobal)
    End Sub

    Public Sub Dibuja(ByVal dispositivo As Device)
        DibujaFotograma(dispositivo, DirectCast(Me.fotogramaRaiz.FrameHierarchy, Fotograma))
    End Sub

    Public Sub Dispose()
    End Sub
End Class

Public Class MallaAnimadaPersonalizada(Of MaterialPersonalizado As {ContenedorDeMaterial, New})
    Inherits BaseDeLaMallaAnimada(Of MaterialPersonalizado)
    Public Overrides Sub GeneraMallaAnimada(ByVal contenedorDeLaMalla As MeshContainer)
        ' Si hay informacion de animacion en el contenedor de la malla
        If contenedorDeLaMalla.SkinInformation IsNot Nothing Then
            tieneInformacionAnimada = True
            Dim numhuesos_ As Integer = contenedorDeLaMalla.SkinInformation.NumberBones
            matrices = New Matrix(numhuesos_ - 1) {}
            For i As Integer = 0 To numhuesos_ - 1
                matrices(i) = contenedorDeLaMalla.SkinInformation.GetBoneOffsetMatrix(i)
            Next

            ' Genera Adyacencia, trianguliza la malla
            Dim datosDeLaMalla As MeshData = contenedorDeLaMalla.MeshData
            adia = New Integer(miMalla.NumberFaces * 3 - 1) {}
            miMalla.GenerateAdjacency(0.001F, adia)
            miMalla = contenedorDeLaMalla.SkinInformation.ConvertToBlendedMesh(datosDeLaMalla.Mesh, MeshFlags.Managed Or MeshFlags.OptimizeVertexCache, adia, numeroDeInfluencias, huesos)
            numeroDeAtributos = huesos.Length
            contenedorDeLaMalla.MeshData = datosDeLaMalla
        End If
    End Sub

    Public Overrides Sub Dibuja(ByVal dispositivo As Device, ByVal frameMatrices As Fotograma(), ByVal materiales As MaterialPersonalizado())
        Dim atributoIdAnterior As Integer = -1

        ' Dibuja o renderiza el fotograma actual de nuestro objeto X
        For iatributo As Integer = 0 To numeroDeAtributos_ - 1
            Dim numBlend As Integer = 0

            For i As Integer = 0 To numeroDeInfluencias_ - 1
                If huesos(iatributo).BoneId(i) <> -1 Then numBlend = i
            Next

            If dispositivo.DeviceCaps.MaxVertexBlendMatrices >= numBlend + 1 Then
                Dim matrices As Matrix() = matrices_
                For i As Integer = 0 To numeroDeInfluencias_ - 1
                    Dim iMatrix As Integer = huesos(iatributo).BoneId(i)
                    If iMatrix <> -1 Then
                        Dim tempMatrix As Matrix = matrices(iMatrix) * frameMatrices(iMatrix).MatrizTransformadaYCombinada
                        dispositivo.Transform.SetWorldMatrixByIndex(i, tempMatrix)
                    End If
                Next

                dispositivo.RenderState.VertexBlend = DirectCast(numBlend, VertexBlend)

                If (atributoIdAnterior <> huesos(iatributo).AttributeId) OrElse (atributoIdAnterior = -1) Then
                    atributoIdAnterior = huesos(iatributo).AttributeId
                End If
                materiales(huesos(iatributo).AttributeId + 1).aplica(dispositivo)

                ' Dibujamos la Malla
                miMalla.DrawSubset(iatributo)
            End If
        Next
    End Sub

    Public Overrides Sub Dispose()
        miMalla.Dispose()
    End Sub
End Class

Public MustInherit Class BaseDeLaMallaAnimada(Of MaterialPersonalizado As {ContenedorDeMaterial, New})
    Inherits Malla(Of MaterialPersonalizado)
    Protected huesos As BoneCombination()
    Protected matrices As Matrix()
    Protected adia As Integer() ' Buffer que contiene información sobre los bordes, caras y caras adyacentes

    Protected numeroDeInfluencias As Integer
    Public ReadOnly Property numeroDeInfluencias_() As Integer
        Get
            Return numeroDeInfluencias
        End Get
    End Property
    Protected numeroDeAtributos As Integer
    Public ReadOnly Property numeroDeAtributos_() As Integer
        Get
            Return numeroDeAtributos
        End Get
    End Property
    Public ReadOnly Property matrices_() As Matrix()
        Get
            Return matrices
        End Get
    End Property
    Protected tieneInformacionAnimada As Boolean
    Public ReadOnly Property tieneInformacionAnimada_() As Boolean
        Get
            Return tieneInformacionAnimada
        End Get
    End Property

    Public Sub Inicializa(ByVal contenedor As MeshContainer)
        miMalla = contenedor.MeshData.Mesh
        GeneraMallaAnimada(contenedor)
        listaDeMaterial = New MaterialPersonalizado(0) {}
        listaDeMaterial(0) = New MaterialPersonalizado()
    End Sub

    Public MustOverride Sub GeneraMallaAnimada(ByVal malla As MeshContainer)
    Public MustOverride Sub Dibuja(ByVal dispositivo As Device, ByVal frameMatrices As Fotograma(), ByVal materiales As MaterialPersonalizado())
    Public MustOverride Sub Dispose()
End Class

' Personalizamos la clase AllocateHierarchy
Public Class AlojadorJerarquicoPersonalizado(Of MaterialPersonalizado As {ContenedorDeMaterial, New}, MallaPersonalizada As {BaseDeLaMallaAnimada(Of MaterialPersonalizado), New})
    Inherits AllocateHierarchy
    Private clasePadre As BaseDeLaAnimacion(Of MaterialPersonalizado, MallaPersonalizada)
    Private texRuta As String = ""
    Private miDispositivo As Device

    Public Sub New(ByVal dispositivo As Device, ByVal padre As BaseDeLaAnimacion(Of MaterialPersonalizado, MallaPersonalizada), ByVal rutaDeLaTextura As String)
        clasePadre = padre
        texRuta = rutaDeLaTextura
        miDispositivo = dispositivo
    End Sub

    Public Overrides Function CreateFrame(ByVal nombre As String) As Frame
        Dim fotograma As New Fotograma(nombre)
        Return fotograma
    End Function

    Public Overrides Function CreateMeshContainer(ByVal nombre As String, ByVal datosDeLaMalla As MeshData, ByVal materiales As ExtendedMaterial(), ByVal efectos As EffectInstance(), ByVal adyacencia As GraphicsStream, ByVal skinInfo As SkinInformation) As MeshContainer
        'Si no hay mallas o si no estan formateados los vertices no podemos crear un contenedor
        If datosDeLaMalla.Mesh Is Nothing Then Throw New ArgumentException()
        If datosDeLaMalla.Mesh.VertexFormat = VertexFormats.None Then Throw New ArgumentException()
        ' de lo contrario creamos un contenedor de mallas, de momento vacio
        Dim contenedorDeMallas As New ContenedorDeMallaPersonalizado(Of MaterialPersonalizado, MallaPersonalizada)()
        contenedorDeMallas.Name = nombre ' le damos nombre al contenedor

        Dim dispositivo As Device = datosDeLaMalla.Mesh.Device

        contenedorDeMallas.SetMaterials(materiales)
        contenedorDeMallas.SetAdjacency(adyacencia)
        ' crea una coleccion de materiales y se los manda al nuevo contenedor
        Dim mateList As MaterialPersonalizado() = New MaterialPersonalizado(materiales.Length) {}
        Dim i As Integer = 0
        For Each material As ExtendedMaterial In materiales
            mateList(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)) = clasePadre.MeteMaterial(miDispositivo, material, texRuta)
        Next
        contenedorDeMallas.materiales = mateList
        contenedorDeMallas.MeshData = datosDeLaMalla
        ' Si existe informacion de la animacion, se la pasamos al nuevo contenedor
        If skinInfo IsNot Nothing Then contenedorDeMallas.SkinInformation = skinInfo
        ' Para mas referencias ver la clase MallaAnimadaPersonalizada
        contenedorDeMallas.MallaAnimada = New MallaPersonalizada()
        contenedorDeMallas.MallaAnimada.Inicializa(contenedorDeMallas)
        Return contenedorDeMallas ' devuelve el nuevo contenedor de mallas
    End Function
End Class
' Personalizamos la clase MeshContainer
Public Class ContenedorDeMallaPersonalizado(Of MaterialPersonalizado As {ContenedorDeMaterial, New}, MallaPersonalizada As BaseDeLaMallaAnimada(Of MaterialPersonalizado))
    Inherits MeshContainer
    Private materiales_ As MaterialPersonalizado()
    Private miMalla As MallaPersonalizada
    Private fotogramas As Fotograma()

    Public Property MallaAnimada() As MallaPersonalizada
        Get
            Return miMalla
        End Get
        Set(ByVal value As MallaPersonalizada)
            miMalla = value
        End Set
    End Property

    Public Property materiales() As MaterialPersonalizado()
        Get
            Return materiales_
        End Get
        Set(ByVal valor As MaterialPersonalizado())
            materiales_ = valor
        End Set
    End Property
    Public Function CogeFotogramas() As Fotograma()
        Return fotogramas
    End Function
    Public Sub PonFotogramas(ByVal fotogramas_ As Fotograma())
        fotogramas = fotogramas_
    End Sub
End Class
' Personalizamos la clase Frame
Public Class Fotograma
    Inherits Frame
    Private combinado As Matrix = Matrix.Identity

    Public Sub New(ByVal nombre As String)
        ' Personalizamos nuestro fotograma con una matriz combinada
        Me.Name = nombre
        Me.TransformationMatrix = Matrix.Identity
        Me.combinado = Matrix.Identity
    End Sub

    Public Property MatrizTransformadaYCombinada() As Matrix
        Get
            Return combinado
        End Get
        Set(ByVal valor As Matrix)
            combinado = valor
        End Set
    End Property
End Class


Y por último decir que la clase no está completamente acabada, que es posible mejorarla, yo simplemente simplifique y adapté un proyecto en C sharp a Visual Basic, e intente dejarlo casi en el esqueleto para que fuera fácil su reutilización. Lo lógico es que si la finalidad es crear un juego o lo que sea, es que el interesado haga sus propias clases de gráficos , sonido, etc... lo compile todo en una DLL y la use en el juego.

Bueno una vez que ya tenemos nuestras clases creadas, la forma de usarla es bastante obvia.

Código:
dim malla As MallaAnimada(Of MaterialTexturizado)
...
...

malla = New MallaAnimada(Of MaterialTexturizado)(dispositivo, "ObjetoAnimado.x", "")


y luego para dibujarlo, podremos escoger varias opciones, podemos por ejemplo usar un timer e indicarle cada tantos intervalos pinte, podemos usar el evento paint, etc... Pero lo importante es que siga el procedimiento ya explicado en anteriores capítulos.

Código:
...
        dispositivo.Transform.Projection = Matrix.PerspectiveFovLH(CSng(Math.PI / 4), Me.Width / Me.Height, 1, 50)
        dispositivo.Transform.World = Matrix.RotationAxis(New Vector3(0, 1.0, 0.0), 0.0)
        dispositivo.Transform.View = Matrix.LookAtLH(New Vector3(0, 0, 5), New Vector3(0, 0, 0), New Vector3(0, 1, 0))

        dispositivo.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, Color.Blue.ToArgb(), 1, 0)

        dispositivo.BeginScene()

        malla.Anima(0.015F, Matrix.Translation(0, 0, 0))
        malla.Dibuja(dispositivo)

        dispositivo.EndScene()
        dispositivo.Present()
...
...


Bueno, pues hasta otra Ok .

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
Tesis
Administrador


Registrado: 04 Mar 2007
Mensajes: 3200
Ubicación: Valencia - España

Mensaje Publicado: Miércoles 28 Jul 2010 09:14

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Excelente aporte Ok Ok Ok Ok


Normas del foro
Aprende a postear correctamente usando las etiquetas
Volver arriba
Ver perfil del usuario Enviar mensaje privado
javi0unavailable



Registrado: 08 Feb 2012
Mensajes: 8

Mensaje Publicado: Miércoles 08 Feb 2012 19:35

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Disculpas por responder a un post antiguo pero realmente necesito ayuda.

Quiero hacer un pequeño juego, cutre, para el proyecto final de FP. Llevo varios días leyendo sobre DirectX,XNA... y tras decidirme hace un par de días por usar las librerías DirectX directamente no me surgen nada más que inconvenientes.

El último que me ha surgido y el que me impide empezar (por fin) a programar es que no puedo crear el Device.

Agrego las referencias
Cita:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D


y al intentar crear el device

Cita:

Public Class gameEngine
Dim _dispositivo As Direct3D.Device
End Class


El Visual Studio 2010 me dice: "el tipo Direct3D.Device no está definido"

He probado a ponerlo de varias formas de escribirlo, pero ese no es el problema. No puedo instanciar el Device.

Lo único que he visto al buscar y que me pueda resultar útil es que he encontrado en la MSDN el objeto Device en otro espacio de nombre:
Espacio de nombres: Microsoft.WindowsMobile.DirectX.Direct3D

He pensado en agregar ese espacio de nombres, pero me faltan las librerías que tengo que referenciar. También me surge la duda que en en la página de Microsoft sobre directx hace referencia a WindowsMobile para smartphones y pocket PC, la duda es si vale para programar juegos en PC.

Ya no se si no puedo usar las DirectX como tal y lo tengo que usar a través de XNA (que también lo intenté probar antes de decantarme por DirectX a pelo y tuve problemas por eso lo dejé), en fin, me gustaría seguir este tutorial de WhiteSkull que está muy bien (felicidades), pero....

A ver si alguno me podéis dar ese empujón que me falta para comenzar.

Gracias por leer.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
WhiteSkull
CoAdmin


Registrado: 20 Mar 2009
Mensajes: 3136
Ubicación: y*width+x

Mensaje Publicado: Miércoles 08 Feb 2012 23:39

Título del mensaje: Re: Tutorial de DirectX para VB .NET (DirectX8+)

Responder citando

Prueba quitando el DirectX

osea pon solamente
Código:
DIM dispositivo as Device


y ya está... prueba y me comentas... aunque no se cuando voy a responder la siguiente vez porque el viento me tiene la línea con cortes intermitentes...

Volver arriba
Ver perfil del usuario Enviar mensaje privado Visitar sitio web del autor
Responder al Tema Ir a página 123Siguiente
Mostrar mensajes anteriores:   
Ir a:  
Todas las horas están en GMT + 2 Horas

Temas relacionados

Tema Autor Foros Respuestas Publicado
El foro no contiene ningún mensaje nuevo

Tutorial Python Rápido para Principiantes

Errodringer Python 0 Viernes 14 Sep 2018 19:38 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Consulta sobre un tipo de PLUGIN para insertar ...

Federico Jose Temas generales 1 Sábado 08 Sep 2018 18:57 Ver último mensaje
El foro no contiene ningún mensaje nuevo

ayuda ayuda para este codigo que me sale error ...

DiegoBV C, C#, Visual C++ 0 Jueves 02 Ago 2018 23:52 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Buscamos Ingeniero de Software para Barcelona

AndresCG Bolsa de trabajo 0 Miércoles 18 Jul 2018 10:14 Ver último mensaje
El tema está bloqueado: no pueden editarse ni agregar mensajes.

Solicito programadores para mi proyecto

alexpin Bolsa de trabajo 0 Miércoles 23 May 2018 22:53 Ver último mensaje
Panel de Control
No puede crear mensajes, No puede responder temas, No puede editar sus mensajes, No puede borrar sus mensajes, No puede votar en encuestas,