lunes, 21 de abril de 2008

Kaspersky 7.0

DarKOoL [manuelpg@infomed.sld.cu]

Análisis de Kaspersky Anti-Virus 7.0

Si necesitas un Antivirus que detecte el máximo y proteja proactivamente tu equipo de virus, spyware y adware, entonces Kaspersky Anti-Virus 7.0 será ideal. Este antivirus es una mezcla perfecta entre el antivirus tradicional y la última tecnología en detección y protección frente a virus, asegurándote así una completa protección frente a programas maliciosos. Además la instalación del programa es realmente sencilla y su configuración puede modificarse fácilmente para adaptarse a tus necesidades. Sin duda alguna este producto fascinará tanto a los usuarios menos experimentados como a los usuarios de antivirus más avanzados.

Qué hace Kaspersky por ti

Kaspersky Anti-Virus 7.0 es totalmente compatible con Microsoft Windows y otros sistemas operativos, y también con otras soluciones de Firewall, etc. El antivirus proporcionará protección completa a tu sistema con las últimas tecnologías de detección y manejo de firmas de virus que te garantizará una protección máxima junto con protección frente a nuevos virus gracias los procesos que incluye. Además de la ya tradicional protección antivirus, una de sus más importantes funciones es que el programa escaneará la navegación web y los correos electrónicos asegurándote que éstas no afectarán al equipo. El antivirus monitoriza todos los programas que se ejecutan, y te avisa en tiempo real si detecta cualquier proceso inseguro o sospechoso. También se monitoriza el estado del registro del sistema, avisándote de cualquier intento de creación de claves del registro sospechosa. Kaspersky Anti-Virus 7.0 también te proporciona protección proactiva frente a macros peligrosas, bloqueando su entrada en el sistema.
Otras Funciones

Otra función muy importante de Kaspersky 7.0 es la restauración del sistema que te asegura que, en caso de cambios indeseados causados por algún programa malicioso, el antivirus restaurará (previa autorización) el sistema a su estado original. Así se asegura de que en ningún caso él usuario sufrirá debido a la actividad de código malicioso.

Kaspersky 7.0 usa pocos recursos del sistema, y su escaneo se ejecuta a gran velocidad. Sin duda alguna es el antivirus idóneo para de equipos portátiles, pues este antivirus te proporcionará un menor consumo de batería que cualquier otro.

Desventajas

Cualquier programa tiene alguna desventaja aunque los puntos positivos sean más y pesen más que los negativos. Así, algunos usuarios opinan que falla al no tener una función que filtre adecuadamente el contenido indeseado de Internet.

Resumen

Podemos decir claramente que Kaspersky Anti-Virus 7.0 es el mejor antivirus del mercado en lo referido a detección de virus, spyware y adware, especialmente para equipos portátiles debido a su bajo consumo de recursos. Sin embargo, como suite de seguridad Kaspersky Internet Security 7.0 debería complementarse con funciones de seguridad adicionales de otros fabricantes (control parental, acceso a red WiFi y otras) al no estar incluidas o no ser las mejores las incluidas en la suite.

Continuar leyendo

¿Quieres ser un Hacker? Parte 2

NightRaider [lexy.galban@fcf.camaguey.cu]

Siguiendo con nuestro curso de Hacking la presente entrega pretende dar a conocer los comandos básicos de Windows y de Linux, para que se familiaricen con ellos y que le servirán para resolver los problemas planteados en el resto de las entregas.

Comandos básicos {Windows}
Date Muestra o establece la fecha del sistema
Time Muestra o establece la hora del sistema
Ver Muestra la versión de MS-DOS que se está utilizando
Dir Muestra la lista de subdirectorios y ficheros de un directorio o carpeta
Cls Borra la pantalla

mkdir <directorio>
md <directorio>
Crea un directorio o carpeta. Por ejemplo: md utilidades

chdir <directorio>
cd <directorio>
Muestra el nombre o cambia el directorio actual . Por ejemplo: cd utilidades

Rmdir <directorio>
rd <directorio>
Borra un directorio o carpeta. Por ejemplo: rd utilidades

tree <ruta> Muestra de forma gráfica-texto la estructura de carpetas de una unidad o ruta.
Por ejemplo: tree c:\utilidades

Chkdsk Comprueba un disco y muestra un informe de estado

Mem Muestra la cantidad de memoria usada y libre en el sistema

rename <origen> <destino>
Ren <origen> <destino>
Cambia el nombre de uno o más ficheros.
Por ejemplo: ren nombreantiguo nombrenuevo

copy <origen> <destino> Copia uno o más ficheros en otra localización.
Por ejemplo: copy c:\util\fichero.txt c:\temporal

move <origen> <destino> Cambia el nombre a ficheros y directorios.
Por ejemplo: move c:\utilidades c:\herramientas

type <fichero> Muestra el contenido de un fichero de texto.
Por ejemplo: type c:\utilidades\mifichero.txt

More <fichero> Muestra la información pantalla a pantalla.
Por ejemplo: More c:\utilidades\mifichero.txt

delete <fichero>
del <fichero>
Elimina uno o más ficheros. Por ejemplo: del c:\utilidades\mifichero.txt

Herramientas de red {Windows}

ping <máquina> El comando ping permite enviar “sondas” ICMP (Internet Control Message Protocol) a otra computadora, con el objetivo de saber si ésta es alcanzable a través de la red. Además muestra un resumen estadístico acerca del porcentaje de sondas que no han tenido respuesta y del tiempo de respuesta. Se puede utilizar el nombre de la máquina o directamente su dirección IP en Internet.
Por ejemplo:
ping www.google.com
ping 193.145.85.2

Algunas opciones son:
-n <N> : envía N paquetes
-t : envía de manera indefinida los paquetes.
Para cancelar ésta y otras opciones: CTRL+C.
Para ver más opciones: ping /h

tracert <máquina> El comando tracert es la abreviatura de trace route, el cual nos permite saber la ruta que siguen los paquetes desde el origen, es decir, nuestra máquina, hasta la máquina destino. También se pueden visualizar los tiempos de cada salto. Como máximo,
se listarán 30 saltos. Es interesante observar que se obtienen los nombres de las máquinas por las cuales viajan los paquetes.
Por ejemplo:
tracert www.google.com
tracert 193.145.85.2

Algunas opciones:
-h <N> : para especificar N saltos como máximo.
-d : no muestra en nombre de las máquinas.
Para ver más opciones: tracert

ipconfig El comando ipconfig muestra información sobre las interfaces de red activas en el ordenador.
Por ejemplo:
ipconfig
Algunas opciones:
/all : muestra más detalles
/renew : activa las direcciones IP del adaptador
cuando se usa configuración automática con DHCP.
/release : desactiva las direcciones IP del adaptador
cuando se usa configuración automática con DHCP.
Para ver más opciones: ipconfig /?

route El comando route sirve para definir rutas estáticas, borrar rutas o simplemente ver el estado de las rutas.
Algunas opciones:
Print : muestra la lista de rutas.
Delete : borra una ruta.
Add : añade una ruta.
Por ejemplo:
route print
Para ver más opciones: route /?

netstat Muestra gran cantidad de información sobre el estado de la red y conexiones de red establecidas con máquinas remotas.
Algunas opciones:
-a Muestra todas las conexiones y puertos escucha.
-e Muestra estadísticas Ethernet.
Por ejemplo:
netstat
netstat –an

Para ver más opciones: netstat /?

Comandos básicos {Linux}

pwd Muestra el nombre del directorio actual.
hostname Muestra el nombre de la máquina local (en la que estamos trabajando)

finger <usuario> Muestra información sobre el usuario <usuario>
Por ejemplo: finger root
Ls Lista el contenido de directorios Por ejemplo: ls –la

cd <directorio> Cambia al directorio <directorio>.
Ejemplo 1: Si nuestro login es “milogin”, el comando $cd cambia al directorio /home/mylogin
Ejemplo 2: $cd - Cambia al último directorio visitado.
Ejemplo 3: $cd /tmp Cambia al directorio “tmp”

cp <origen> <destino>
Copia ficheros. Copia el fichero “origen” en “destino”. Por ejemplo: cp /etc/passwd /tmp

rm <fichero> Borra ficheros. Sólo el propietario del fichero (o root) puede borrarlo.
Por ejemplo: rm mifichero

mv <origen> <destino> Mueve o renombra ficheros y directorios
Por ejemplo: mv nombreantiguo nombrenuevo

mkdir <directorio> Crea un directorio con nombre “directorio”
Por ejemplo: mkdir midirectorio

rmdir <directorio> Borra el directorio “directorio” si se encuentra vacío
Por ejemplo: rmdir midirectorio

man <comando> Muestra las páginas del manual on-line Por ejemplo: man ls

Herramientas de red {Linux}

ping <máquina> El comando ping permite enviar “sondas” ICMP (Internet Control Message Protocol) a otra computadora, con el objetivo de saber si ésta es alcanzable a través de la red. Además muestra un resumen estadístico acerca del porcentaje de sondas que no han tenido respuesta y del tiempo de respuesta. Se puede utilizar el nombre de la máquina o directamente su dirección IP en Internet.
Por ejemplo:
ping www.google.com
ping 193.145.85.2

Para ver más opciones: man ping

Traceroute <máquina> El comando traceroute indica la ruta que siguen los paquetes desde el origen, es decir, nuestra máquina, hasta la máquina destino llamada <máquina>.
Por ejemplo: traceroute www.google.com
Para ver más opciones: man traceroute

Ifconfig El comando ifconfig muestra información sobre las interfaces activas (ethernet, ppp, etc.).
Por ejemplo:
ifconfig
Para ver más opciones: man ifconfig

route El comando route sirve para definir rutas estáticas, borrar rutas o simplemente ver el estado de las rutas.
Algunas opciones:
print: muestra la lista de rutas.
delete: borra una ruta.
add: añade una ruta.
Por ejemplo:
route
Para ver más opciones: man route

Netstat Muestra gran cantidad de información sobre el estado de la red y de las conexiones TCP/IP establecidas.
Por ejemplo:
netstat
netstat –an

Para ver más opciones: man netstat

Continuar leyendo

Caché en un procesador

Neo [erich14074@cha.jovenclub.cu]

Una memoria caché es una memoria en la que se almacenas una serie de datos para su rápido acceso. Existen muchas memorias caché (de disco, de sistema, incluso de datos, como es el caso de la caché de Google), pero aquí nos vamos a centrar en la caché de los procesadores.

Básicamente, la memoria caché de un procesador es un tipo de memoria volátil (del tipo RAM), pero de una gran velocidad.

En la actualidad esta memoria está integrada en el procesador, y su cometido es almacenar una serie de instrucciones y datos a los que el procesador accede continuamente, con la finalidad de que estos accesos sean instantáneos. Estas instrucciones y datos son aquellas a las que el procesador necesita estar accediendo de forma continua, por lo que para el rendimiento del procesador es imprescindible que este acceso sea lo más rápido y fluido posible.

Hay tres tipos diferentes de memoria caché para procesadores:

Caché de 1er nivel (L1):

Esta caché está integrada en el núcleo del procesador, trabajando a la misma velocidad que este. La cantidad de memoria caché L1 varía de un procesador a otro, estando normalmente entra los 64KB y los 256KB. Esta memoria suele a su vez estar dividida en dos partes dedicadas, una para instrucciones y otra para datos.

Caché de 2º nivel (L2):

Integrada también en el procesador, aunque no directamente en el núcleo de este, tiene las mismas ventajas que la caché L1, aunque es algo más lenta que esta. La caché L2 suele ser mayor que la caché L1, pudiendo llegar a superar los 2MB, hasta 8 se ven hoy día.
A diferencia de la caché L1, esta no está dividida, y su utilización está más encaminada a programas que al sistema.

Caché de 3er nivel (L3):

Es un tipo de memoria caché más lenta que la L2, muy poco utilizada en la actualidad.

En un principio esta caché estaba incorporada a la placa base, no al procesador, y su velocidad de acceso era bastante más lenta que una caché de nivel 2 o 1, ya que si bien sigue siendo una memoria de una gran rapidez (muy superior a la RAM, y mucho más en la época en la que se utilizaba), depende de la comunicación entre el procesador y la placa base.

Para hacernos una idea más precisa de esto, imaginemos en un extremo el procesador y en el otro la memoria RAM. Pues bien, entre ambos se encuentra la memoria caché, más rápida cuanto más cerca se encuentre del núcleo del procesador (L1).

Las memorias caché son extremadamente rápidas (su velocidad es unas 5 veces superior a la de una RAM de las más rápidas), con la ventaja añadida de no tener latencia, por lo que su acceso no tiene ninguna demora... pero es un tipo de memoria muy cara.
Esto, unido a su integración en el procesador (ya sea directamente en el núcleo o no) limita bastante el tamaño, por un lado por lo que encarece al procesador y por otro por el espacio disponible.

En cuanto a la utilización de la caché L2 en procesadores multinucleares, existen dos tipos diferentes de tecnologías a aplicar.

Por un lado está la habitualmente utilizada por Intel, que consiste en que el total de la caché L2 está accesible para ambos núcleos y por otro está la utilizada por AMD, en la que cada núcleo tiene su propia caché L2 dedicada solo para ese núcleo.

La caché L2 apareció por primera vez en los Intel Pentium Pro, siendo incorporada a continuación por los Intel Pentium II, aunque en ese caso no en el encapsulado del procesador, sino externamente (aunque dentro del procesador).

Continuar leyendo

BlueTooth

Yordan Pérez [truano@infomed.sld.cu]

En los tiempos que corren la tecnología avanza a pasos agigantados hacia las comunicaciones y conexiones inalámbricas, eliminar los viejos cables que conectan nuestros equipos electrónicos se ha convertido casi en una cruzada, amen por eso, ¿cuantas veces nos hemos quedado sin mouse porque el dichoso cablecito se nos parte? Y entonces el pequeño roedor comienza a caminar para donde le da la real gana, o sencillamente no hace click, todo eso es historia antigua cuando usamos un mouse inalámbrico, claro que entonces surgen otros problemas, como el gasto de baterías, pero yo particularmente he tenido mouse y teclado inalámbrico y por experiencia propia les digo que todo es ventaja.

¿Qué es BlueTooth?

Ante todo muchos se preguntan ¿porque BlueTooth? La traducción es “Diente Azul” y nadie le encuentra similitud a un diente azul con comunicaciones inalámbricas, bueno, el nombre Bluetooth viene de un rey vikingo llamado Harald Blåtand “Bluetooth” reconocido por hacer grandes progresos en la comunicación de su gente, bajo su reinado unió a Dinamarca y Noruega, así como también por haber logrado el comienzo de la cristianización entre la sociedad vikinga, satisfechos todos con saber por que “Bluetooth”, continuamos.

Bluetooth es una tecnología inalámbrica que nos permite comunicar nuestros dispositivos móviles, así como conectar muchos periféricos de nuestra pc sin necesidad de cables, dicha tecnología opera en la banda de radio frecuencia de los 2.4 Ghz y tiene un alcance optimo de 10m (opcional hasta los 100m), es capaz de atravesar paredes, maletines, etc.

Entre los usos más frecuentes está la conectividad entre teléfonos celulares, tanto entre ellos como para conectarlos a una PC, así como la posibilidad de usar manos libres sin necesidad de cables, también existen diferentes dispositivos para PC que usan esta tecnología, tales como mouse y teclados, módems, tarjetas de redes, PDA, etc.

¿Como surge el estándar?

Durante 1994, surgió la idea de investigar la posibilidad de crear un dispositivo de bajo costo que sirviera para comunicar diversos dispositivos, la idea era hacerlo basado en un estándar estricto para que su uso se popularizara y diversos fabricantes pudieran desarrollar dispositivos que lo utilizaran. En 1998, un grupo de industrias líderes en computadoras y telecomunicaciones, incluyendo Intel, IBM, Toshiba, Ericsson y Nokia, estuvieron desarrollando dicho dispositivo. Para asegurar, que esta tecnología esta implementada con un empalme perfecto en un diverso rango de dispositivos, esos líderes formaron un grupo de intereses especiales (Special Interests Group - SIG). El SIG fue rápidamente ganando miembros, como las compañías 3Com, Axis Comunication, Compaq, Dell, Lucent Technologies UK Limited, Motorola, Qualcomm y Xircom.

Arquitectura de Hardware

El hardware que compone el dispositivo Bluetooth esta compuesto por dos partes. Un dispositivo de radio, encargado de modular y transmitir la señal; y un controlador digital. El controlador digital esta compuesto por un CPU, por un procesador de señales digitales (DSP - Digital Signal Processor) llamado Link Controller (o controlador de Enlace) y de los interfaces con el dispositivo anfitrión.
El LC o Link Controller está encargado de hacer el procesamiento de la banda base y del manejo de los protocolos ARQ y FEC de capa física. Además, se encarga de las funciones de transferencia (tanto asíncrona como síncrona), codificación de Audio y encriptación de datos.
El CPU del dispositivo se encarga de atender las instrucciones relacionadas con Bluetooth del dispositivo anfitrión, para así simplificar su operación. Para ello, sobre el CPU corre un software denominado Link Manager que tiene la función de comunicarse con otros dispositivos por medio del protocolo LMP.

Entre las tareas realizadas por el LC y el Link Manager, destacan las siguientes:
- Envío y Recepción de Datos.
- Empaginamiento y Peticiones.
- Determinación de Conexiones.
- Autenticación.
- Negociación y determinación de tipos de enlace, por ejemplo SCO o ACL
- Determinación del tipo de cuerpo de cada paquete.
- Ubicación del dispositivo en modo sniff o hold.

Arquitectura de Software

Buscando ampliar la compatibilidad de los dispositivos Bluetooth, los dispositivos que se apegan al estándar utilizan como interfaz entre el dispositivo anfitrión (laptop, teléfono celular, etc) y el dispositivo Bluetooth como tal (chip Bluetooth) una interfaz denominada HCI (Host Controller Interface).

Los protocolos de alto nivel como el SDP (Protocolo utilizado para encontrar otros dispositivos Bluetooth dentro del rango de comunicación, encargado, también, de detectar la función de los dispositivos en rango), RFCOMM (Protocolo utilizado para emular conexiones de puerto serial) y TCS (Protocolo de control de telefonía) interactúan con el controlador de banda base a través del Protocolo L2CAP (Logical Link Control and Adaptation Protocol). El protocolo L2CAP se encarga de la segmentación y reensamblaje de los paquetes para poder enviar paquetes de mayor tamaño a través de la conexión Bluetooth.

Protocolo de Conexión

Las conexiones Bluetooth, son establecidas a través de la siguiente técnica:
Standby: Los dispositivos en un "piconet" que no están conectados, están en modo standby, ellos escuchan mensajes cada 1,28 segundos, sobre 32 saltos de frecuencias.

Page/Inquiry: Si un dispositivo desea hacer una conexión con otro dispositivo, éste le envía un mensaje de tipo page, si la dirección es conocida; o una petición a través de un mensaje de page, si éste no es conocido. La unidad "master" envía 16 page message idénticos, en 16 saltos de frecuencias, a la unidad "slave". Si no hay respuesta, el "master" retransmite en los otros 16 saltos de frecuencia. El método de Petición (inquiry) requiere una respuesta extra por parte de la unidad "slave", desde la dirección MAC, que no es conocida por la unidad "master".

Active: Ocurre la transmisión de datos.

Hold: Cuando el "master" o el "slave" desean, puede ser establecido un modo en el cual no son transmitidos datos. El objetivo de esto es conservar el poder.

Sniff: El modo sniff, es aplicable solo para las unidades "slaves", es para conserva el poder. Durante este modo, el "slave", no toma un rol activo en la "piconet", pero escucha a un reducido nivel.

Park: El modo park es un nivel más reducido , que el modo hold. Durante este, el "slave" es sincronizado a la "piconet", por eso no requiere un reactivación completa, pero no es parte del tráfico. En este estado, ellos no tienen direcciones MAC y solo escuchan para mantener su sincronización con el "master" y chequear los mensajes de broadcast.

Problemas y Desventajas

Como todo, la tecnología Bluetooth, también presenta algunos problemas que solucionar. Los microchips no son baratos aún, se espera que dentro de unos años disminuyan los costos, de lo contrario, el objetivo de esta tecnología no sería alcanzado. Por su parte, la velocidad de transmisión, aunque considerable, pronto quedará empequeñecida por la capacidad de los móviles de tercera generación. Y a pesar de que los prototipos de dispositivos Bluetooth se reproducen rápidamente, no sucede lo mismo con los programas informáticos que deben regular su funcionamiento.

Además, el espectro de radiofrecuencia en el que opera no está abierto al público en todos los países. En lugares como Francia o España el uso del espectro está restringido y se requiere la aprobación explícita del gobierno para poder operar en la banda ISM.

La interoperabilidad, pilar sobre el que se sustenta Bluetooth, es uno de los factores que se someterán a tensiones en el largo plazo. Con miles de compañías diseñando productos y aplicaciones Bluetooth, será difícil mantenerlas a todas bajo el mismo manto.

Aun así, las desventajas son mínimas cuando se comparan con los beneficios de disfrutar de un mundo sin cables y con las flexibilidades que ofrecería un mundo interconectado de manera inalámbrica y sin altos costos de conexión.

Conclusiones

Como toda nueva tecnología Bluetooth aun está en fases inciales, aun existen mucho camino por recorrer para que llegue a ser perfecta, pero mientras ya podemos ir disfrutando de las ventajas que nos ofrece, como siempre les deseo que mi articulo les sea esclarecedor y de mucha ayuda.

Continuar leyendo

WoW (Word of WarCraft)

Yordan Pérez [truano@infomed.sld.cu]

Introducción

¿Cuantas páginas podemos dedicar a quien se ha convertido en el mejor MMORPG de la historia? Les juro que esto es difícil, intentaré resumir todo lo que pueda, pero para llevarles un buen articulo creo que tendrá que ser en 2 partes, Y para aquellos que no saben que significa MMORPG (Massive Multiplayer Online Rol Play Game) son sus siglas en ingles, lo cual significa “Juego Masivo de Rol en Línea”, otra de las súper creaciones de nuestros amigos de Blizzard, en el mes de enero los servidores oficiales ya habían registrado mas de 10 millones de usuarios, de una cifra como esa podemos fácilmente deducir la gran aceptación que ha tenido entre los amantes de los juegos en línea, esta obra de arte es un todo incluido, el apartado grafico se merece un 9, la jugabilidad e interacciones con los objetos bien ganaría un 10, la amplitud del enorme mapa rompería con cualquier escala de puntuación, contiene además una historia rica en contenido y muy bien dividida, gran variedad de armas, armaduras, razas y objetos, muy bien distribuido el equilibrio entre las razas, en resumen, poco le falta para lograr la perfección.

Las Razas

El Universo de Word of WarCraft está habitado por varias razas de seres inteligentes. Estas razas hablan diferentes lenguas, tienen diferentes tierras natales y características raciales y pueden pertenecer a ciertas Clases. La mayoría de razas que conocemos vienen del mundo de Azeroth, algunas vienen de otros mundos como Draenor o el Twisting Nether(como la Legión Ardiente). Actualmente hay dos grandes facciones políticas en World of Warcraft, la Alianza y la Horda, y cada una comprende 5 razas que ofrecen un amplio abanico de clases.

Razas de La Alianza

Humanos: Son una raza versátil y adaptable, son los que mas reinos han llegado a manejar, aunque dentro del WoW solo se puede jugar con los humanos en el reino de Stormwind, son también los fundadores de La Alianza, pueden ser magos, guerreros, paladines, picaros, sacerdotes o brujos.

Enanos: Antiguos como el propio Kalimdor y sedientos de conocimientos, son los mejores Herreros que existen, de los tres reinos enanos existentes, solo podemos jugar con los del reino bajo la montaña, Ironforge, pueden ser de las siguientes clases cazador, mago, sacerdote, pícaro, paladín y guerrero.

Gnomos: Pequeños, audaces y peligrosamente inventivos. Los gnomos sienten pasión por la Ingeniería y son quienes dotaron a la Alianza de máquinas de guerra. Antiguos habitantes de Gnomeregan, actualmente viven alojados en Ironforge, las clases para estos pequeños son magos, picaros, brujos y guerreros.

Elfos Nocturnos: Una raza ancestral, enemiga y culpable a la vez de la llegada de la Legión Ardiente a Azeroth. Sienten una gran sintonía con el mundo natural, lo que sumado a sus hábitos nocturnos les da la capacidad de fundirse con las sombras. Su hogar es Darnassus, sus clases son druida, cazador, sacerdote, pícaro y guerrero.

Draeneis: Otra raza muy antigua. Hermanos de los corruptos Eredar, estos seres abrazaron la Luz Sagrada y huyeron de su mundo para finalmente quedar en Azeroth. Honorables y nobles tienen por fin eliminar la maldad de la Legión Ardiente. Habitan en Exodar, al sur de Darnassus. Afiliados con la Alianza debido a viejos rencores con los Orcos, clases que se les otorga son cazador, mago, paladín, sacerdote, chamán y guerrero.

Razas de La Horda

Orcos: Originarios de Draenor, los orcos sufrieron mucho tiempo la corrupción demoniaca. Ahora, bajo el liderazgo chamanístico de Thrall buscan reencontrar sus orígenes. Viven bajo el lema de Honor y Fuerza, su capital racial es Orgrimmar. Son los fundadores de La Horda, Clases cazador, pícaro, chamán, brujo y guerrero.

Tauren: Masivos y fuertemente espirituales, los Tauren mantienen un nexo inquebrantable con la Madre Tierra. Viven en ThunderBluff. Son la fuerza y guía espiritual de la Horda, pueden tener las siguientes clases druida, cazador, chamán y guerrero.

Trolls: Los trolls son de muchos colores, complexiones y creencias, pero los que son jugables en World of Warcraft son los trolls de la tribu Darkspear. Habitan en las Islas Eco y en Sen'Jin Village. Su agilidad y astucia los ha convertido en los exploradores por excelencia de la Horda, se les permite tener las clases de cazador, mago, sacerdote, pícaro, chamán y guerrero.

Undead: Los muertos vivientes pueden ser hasta de 3 afiliaciones pero aquellos con quienes es posible jugar son los autodenominados Forsaken. Afiliados a la Horda más por necesidad que por simpatía, proveen a su facción de combatientes mágicos y alquimistas destacados. Su capital es Undercity, y pueden vérseles con las siguientes clases mago, sacerdote, pícaro, brujo y guerrero.

Elfos de Sangre: Los blood elves también se unieron a la Horda por pura necesidad. Residen en la reconstruida Silvermoon. Excelentes Magos y Encantadores, los elfos buscan calmar su sed de magia antes que ella los acabe. Dotaron a la Horda de Paladines, sus clases pueden ser cazador, mago, paladín, sacerdote, pícaro y brujo.

Las Clases

Guerrero: Mi preferido, maestro de armas, el más ventajoso en la lucha cuerpo a cuerpo (normalmente las mas comunes) es muy resistente, no usa magia aunque puede aprender habilidades como furia, usan armaduras de tela, cuero, malla y después del lvl 40 pueden usar Placas, también son capaces de portar escudos.
Todas las razas pueden ser Guerreros menos los Elfos de Sangre.

Paladín: La primera línea de defensa de La Alianza, seguidores de La Luz, el azote de los Forzaken, luchan en todo momento contra las fuerzas demoniacas con armas como martillos y hechizos de guerra, estos santos guerreros son los comandantes de los ejércitos en la batalla, usan armaduras de tela, cuero, malla y placas en el lvl 40, también usan escudos.
Disponibles para humanos, enanos, draeneis y elfos de sangre.

Pícaro: Estos son los señores del disfraz y la ocultación, nunca se favorecen en un combate de frente, prefieren usar métodos como la esquiva y la ocultación y atacar cuando la ventaja está de su parte, casi siempre usando dagas o espadas cortas, casi siempre poniendo veneno en las mismas, son magníficos ladrones, para permitirse agiles movimientos usan solo armaduras de tela y cuero.
Está disponible solo para Gnomos, Humanos, Enanos, Elfos de la Noche, Orcos, No-Muertos, Trolls, Elfos de Sangre.

Cazador: Tienen el don de domesticar cualquier tipo de criatura y esta los acompaña a la lucha, son grandes rastreadores y dominan el tiro a distancia, usan solo armaduras de tela o cuero y solo después del lvl 40 usan malla.

Solo las siguientes razas pueden ser cazadores: Elfos de la Noche, Enanos, Draeneis, Orcos, Tauren, Trolls, Elfos de Sangre.

Mago: Dominadores del arte de la magia arcana, estos eternos estudiosos son un arma a tener en cuenta en la guerra, usan hechizos principalmente de área de efecto y varas con poderes para amplificar el daño causado, pasan demasiado tiempo estudiando, debido a esto no son capaces de llevar armaduras ya que no han ejercitado su físico para tal tarea, por esto solo usan tela y hechizos de protección.
Disponibles para: humanos, Gnomos, Draeneis, No muertos, Trolls y Elfos de Sangre.

Brujo: Han explorado con demasiada profundidad las raíces del poder demoníaco. Consumidos por un ansia de conocimiento oscuro, se han volcado en las magias caóticas del mundo. Además de una clase Crowd Control (usa hechizos que aterrorizan al enemigo, son capaces de paralizar elementales y demonios, o incluso controlarlos) También se caracteriza, por sus ataques de 30 metros. Imparables, llevan con sigo, una serie de "esbirros". Un esbirro es una invocación que hacen para mal, para protegerse. Son Diablillos, Abisarios, Súcubos... e incluso monturas, en las que se podrán montar para transportarse por el mundo de Warcraft más rápido.

Disponibles: Humanos, Gnomos, Orcos, No muertos y Elfos de sangre.

Chamán: Son lideres espirituales de sus tribus o clanes, tienen visiones del futuro comunicándose con los espíritus y guían a su pueblo a través de las oscuridades del tiempo. Un Chaman de alto lvl puede dominar tanto el combate cuerpo a cuerpo como la magia, así como también pueden ser curanderos, son muy versátiles, usan armaduras de tela, cuero y malla solo al lvl 40.

Disponibles: Orcos, Taurens, Trolls y Draeneis.

Druida: Son los guardianes del mundo y la naturaleza, tras la derrota de Archimonde los druidas han decidido seguir despiertos y ayudar a reconstruir las tierras desbastadas en la segunda guerra, al tener un lazo cercano y muy fuerte con la naturaleza los druidas pueden incluso hasta cambiar de forma, llegando a convertirse lo mismo en un lobo que en oso, adquiriendo poderes extras en la lucha, usan solo tela y cuero.
Disponible: Elfos Nocturnos y Taurens.

Sacerdote: Los Sacerdote conducen las diferentes creencias a lo largo de los dispares territorios de World of Warcraft. En Kalimdor, las Sacerdotisas Elfas Nocturnas adoran a la diosa de la luna Elune, mientras los Sacerdotes Enanos en Khaz Modan transmiten su mensaje sobre la Luz a todo el mundo. En las ruinas de Lordaeron, los Sacerdotes No-muertos de los Renegados, tienen su fe distorsionada y corrompida por sus torturadas existencias, extendiendo una oscura interpretación de la Luz Sagrada. Es el curador por excelencia, siendo el personaje principal en instancias más fuertes y que requieren más gente, solo usan tela por igual motivo que los magos.

Disponibles: Humanos, Enanos, Elfos nocturnos, Draeneis, No-muertos, Trolls, Elfos de Sangre.

Bueno como pueden ver este es un juego muy amplio que no los defraudará, en nuestro país al no tener la posibilidad de conectarnos a un servidor oficial ya sea por lo difícil que sea hace tener una conexión a internet sin proxys, o por la imposibilidad de muchos a efectuar los pagos de cuotas mensuales que se exigen para jugar este juego en línea en los servidores oficiales de Blizzard, así como también por que se necesita un ancho de banda del cual no todos disponemos, se juega instalando un servidor propio en la misma PC que se ejecuta el cliente, restándole muchísima emoción al juego ya que todos sabemos que en un juego online la emoción mas grande es la de poder compartir y competir contra personas iguales a nosotros mismos, pero aun así es un señor juegazo, el cual nunca me ha aburrido, tiene algunos requerimientos en cuanto a hardware, pero yo lo he corrido hasta en un Pentium 3, con 512 de memoria y una tarjeta de video Nvidia GeForce MX4000 de 64 mb, así que casi cualquiera podrá disfrutar de este juego, se los recomiendo.

Continuar leyendo

Dirección IP

Chacal [mariav.hedez@infomed.sld.cu]

Para esta edición pretendo hacer un pequeño recuento del protocolo IP, utilizado mundialmente para la identificación en la red de todas las computadoras del mundo.

Dirección IP

Una dirección IP es un número que identifica de manera lógica y jerárquica a una interfaz de un dispositivo (habitualmente una computadora) dentro de una red que utilice el protocolo IP (Internet Protocol), que corresponde al nivel de red o nivel 3 del modelo de referencia OSI. Dicho número no se ha de confundir con la dirección MAC que es un número hexadecimal fijo que es asignado a la tarjeta o dispositivo de red por el fabricante, mientras que la dirección IP se puede cambiar.

Es habitual que un usuario que se conecta desde su hogar a Internet utilice una dirección IP. Esta dirección puede cambiar al reconectar; y a esta forma de asignación de dirección IP se denomina una dirección IP dinámica (normalmente se abrevia como IP dinámica).

Los sitios de Internet que por su naturaleza necesitan estar permanentemente conectados, generalmente tienen una dirección IP fija (se aplica la misma reducción por IP fija o IP estática), es decir, no cambia con el tiempo. Los servidores de correo, DNS, FTP públicos, y servidores de páginas web necesariamente deben contar con una dirección IP fija o estática, ya que de esta forma se permite su localización en la red.

A través de Internet, los ordenadores se conectan entre sí mediante sus respectivas direcciones IP. Sin embargo, a los seres humanos nos es más cómodo utilizar otra notación más fácil de recordar y utilizar, como los nombres de dominio; la traducción entre unos y otros se resuelve mediante los servidores de nombres de dominio DNS.

Existe un protocolo para asignar direcciones IP dinámicas llamado DHCP (Dynamic Host Configuration Protocol).
Direcciones IPv4

En su versión 4, una dirección IP se representa mediante un número binario de 32 bits (IPv4). Las direcciones IP se pueden expresar como números de notación decimal: se dividen los 32 bits de la dirección en cuatro octetos. El valor decimal de cada octeto puede ser entre 0 y 255 (el número binario de 8 bits más alto es 11111111 y esos bits, de derecha a izquierda, tienen valores decimales de 1, 2, 4, 8, 16, 32, 64 y 128, lo que suma 255 en total).

En la expresión de direcciones IPv4 en decimal se separa cada octeto por un carácter ".". Cada uno de estos octetos puede estar comprendido entre 0 y 255, salvo algunas excepciones. Los ceros iniciales, si los hubiera, se pueden obviar.

Ejemplo de representación de dirección IPv4: 164.12.123.65
Hay tres clases de direcciones IP que una organización puede recibir de parte de la Internet Corporation for Assigned Names and Numbers (ICANN): clase A, clase B y clase C. En la actualidad, ICANN reserva las direcciones de clase A para los gobiernos de todo el mundo (aunque en el pasado se le hayan otorgado a empresas de gran envergadura como, por ejemplo, Hewlett Packard) y las direcciones de clase B para las medianas empresas. Se otorgan direcciones de clase C para todos los demás solicitantes. Cada clase de red permite una cantidad fija de equipos (hosts).

En una red de clase A, se asigna el primer octeto para identificar la red, reservando los tres últimos octetos (24 bits) para que sean asignados a los hosts, de modo que la cantidad máxima de hosts es 224 (menos dos: las direcciones reservadas de broadcast [tres últimos octetos a 255] y de red [tres últimos octetos a 0]), es decir, 16 777 214 hosts.

En una red de clase B, se asignan los dos primeros octetos para identificar la red, reservando los dos octetos finales (16 bits) para que sean asignados a los hosts, de modo que la cantidad máxima de hosts es 216 (menos dos), o 65 534 hosts.

En una red de clase C, se asignan los tres primeros octetos para identificar la red, reservando el octeto final (8 bits) para que sea asignado a los hosts, de modo que la cantidad máxima de hosts es 28 (menos dos), o 254 hosts. La dirección 0.0.0.0 es utilizada por las máquinas cuando están arrancando o no se les ha asignado dirección.

La dirección que tiene su parte de host a cero sirve para definir la red en la que se ubica. Se denomina dirección de red.

La dirección que tiene su parte de host a unos sirve para comunicar con todos los hosts de la red en la que se ubica. Se denomina dirección de broadcast.

Las direcciones 127.x.x.x se reservan para pruebas de retroalimentación. Se denomina dirección de bucle local o loopback.

Hay ciertas direcciones en cada clase de dirección IP que no están asignadas y que se denominan direcciones privadas. Las direcciones privadas pueden ser utilizadas por los hosts que usan traducción de dirección de red (NAT) para conectarse a una red pública o por los hosts que no se conectan a Internet. En una misma red no puede existir dos direcciones iguales, pero sí se pueden repetir en dos redes privadas que no tengan conexión entre sí o que se sea a través de NAT. Las direcciones privadas son:

Clase A: 10.0.0.0 a 10.255.255.255 (8 bits red, 24 bits hosts)
Clase B: 172.16.0.0 a 172.31.255.255 (16 bits red, 16 bits hosts)
Clase C: 192.168.0.0 a 192.168.255.255 (24 bits red, 8 bits hosts)

A partir de 1993, ante la previsible futura escasez de direcciones IPv4 debido al crecimiento exponencial de hosts en Internet, se empezó a introducir el sistema CIDR, que pretende en líneas generales establecer una distribución de direcciones más fina y granulada, calculando las direcciones necesarias y "desperdiciando" las mínimas posibles, para rodear el problema que las distribución por clases había estado gestando. Este sistema es, de hecho, el empleado actualmente para la delegación de direcciones.

Muchas aplicaciones requieren conectividad dentro de una sola red, y no necesitan conectividad externa. En las redes de gran tamaño a menudo se usa TCP/IP. Por ejemplo, los bancos pueden utilizar TCP/IP para conectar los cajeros automáticos que no se conectan a la red pública, de manera que las direcciones privadas son ideales para ellas. Las direcciones privadas también se pueden utilizar en una red en la que no hay suficientes direcciones públicas disponibles.

Las direcciones privadas se pueden utilizar junto con un servidor de traducción de direcciones de red (NAT) para suministrar conectividad a todos los hosts de una red que tiene relativamente pocas direcciones públicas disponibles. Según lo acordado, cualquier tráfico que posea una dirección destino dentro de uno de los intervalos de direcciones privadas no se enrutará a través de Internet.

IP dinámica

Una dirección IP dinámica es una IP asignada mediante un servidor DHCP (Dynamic Host Configuration Protocol) al usuario. La IP que se obtiene tiene una duración máxima determinada. El servidor DHCP provee parámetros de configuración específicos para cada cliente que desee participar en la red IP. Entre estos parámetros se encuentra la dirección IP del cliente.

DHCP apareció como protocolo estándar en octubre de 1993. El estándar RFC 2131 especifica la última definición de DHCP (marzo de 1997). DHCP sustituye al protocolo BOOTP, que es más antiguo. Debido a la compatibilidad retroactiva de DHCP, muy pocas redes continúan usando BOOTP puro.

Las IPs dinámicas son las que actualmente ofrecen la mayoría de operadores. Éstas suelen cambiar cada vez que el usuario reconecta por cualquier causa.

Ventajas

- Reduce los costos de operación a los proveedores de servicios internet (ISP).

Desventajas

- Obliga a depender de servicios que redirigen un host a una IP.
- Es ilocalizable; en unas horas pueden haber varios cambios de IP.

Asignación de direcciones IP

Dependiendo de la implementación concreta, el servidor DHCP tiene tres métodos para asignar las direcciones IP:
- manualmente, cuando el servidor tiene a su disposición una tabla que empareja direcciones MAC con direcciones IP, creada manualmente por el administrador de la red. Sólo clientes con una dirección MAC válida recibirán una dirección IP del servidor.
- automáticamente, donde el servidor DHCP asigna permanentemente una dirección IP libre, tomada de un rango prefijado por el administrador, a cualquier cliente que solicite una.
- dinámicamente, el único método que permite la reutilización de direcciones IP. El administrador de la red asigna un rango de direcciones IP para el DHCP y cada ordenador cliente de la LAN tiene su software de comunicación TCP/IP configurado para solicitar una dirección IP del servidor DHCP cuando su tarjeta de interfaz de red se inicie. El proceso es transparente para el usuario y tiene un periodo de validez limitado.

IP fija

Una dirección IP fija es una IP la cual es asignada por el usuario, o bien dada por el proveedor ISP en la primera conexión.

Las IPs fijas actualmente en el mercado de acceso a Internet tienen un coste adicional mensual. Estas IPs son asignadas por el usuario después de haber recibido la información del proveedor o bien asignadas por el proveedor en el momento de la primera conexión.

Esto permite al usuario montar servidores web, correo, FTP, etc. y dirigir un nombre de dominio a esta IP sin tener que mantener actualizado el servidor DNS cada vez que cambie la IP como ocurre con las IPs dinámicas.

Ventajas

- Permite tener servicios dirigidos directamente a la IP.

Desventajas

- Son más vulnerables al ataque, puesto que el usuario no puede conseguir otra IP.
- Es más caro para los ISPs puesto que esa IP puede no estar usándose las 24 horas del día.

Direcciones IPv6

La función de la dirección IPv6 es exactamente la misma a su predecesor IPv4, pero dentro del protocolo IPv6. Está compuesta por 8 segmentos de 2 bytes cada uno, que suman un total de 128 bits, el equivalente a unos 3.4x1038 hosts direccionables. La ventaja con respecto a la dirección IPv4 es obvia en cuanto a su capacidad de direccionamiento.

Su representación suele ser hexadecimal y para la separación de cada par de octetos se emplea el símbolo ":". Un bloque abarca desde 0000 hasta FFFF. Algunas reglas acerca de la representación de direcciones IPv6 son:
- Los ceros iniciales, como en IPv4, se pueden obviar.
Ejemplo: 2001:0123:0004:00ab:0cde:3403:0001:0063 -> 2001:123:4:ab:cde:3403:1:63
- Los bloques contiguos de ceros se pueden comprimir empleando "::". Esta operación sólo se puede hacer una vez.

Ejemplo: 2001:0:0:0:0:0:0:4 -> 2001::4.
Ejemplo no válido: 2001:0:0:0:2:0:0:1 -> 2001::2::1 (debería ser 2001::2:0:0:1 ó 2001:0:0:0:2::1).
Bueno espero que ahora comprendan mejor el funcionamiento y la explicación exacta de las direcciones IP.
BlackHat Un Proyecto Para Todos

Continuar leyendo

OpenGL: Introducción e inicialización

h0aX [hoax@fresnomail.com]

Nuevo año para BlackHat, nuevas entregas para sus seguidores. Este año me surge el capricho de presentarme más por la sección de Artículos (según el tiempo y el trabajo me lo permitan) y por su puesto, qué mejor manera de enriquecer nuestra querida sección de Códigos sino escribiendo motivadores artículos. Hace unos días encontraba me intercambiando con un amigo y miembro de la comunidad, ¿qué tipo de artículos podrían resultar interesantes para los lectores de BlackHat? y mientras pensaba yo en sniffers, IA y Prolog acomete mi amigo con una brillante idea: h0aX, escribe de OpenGL! Pues que así sea. Durante las próximas ediciones trataré en mayor o menor medida satisfacer la curiosidad de algunos que durante el tiempo que han permanecido tras las letras verdes y el fondo negro de nuestra revista, se han preguntado en alguna ocasión ¿qué es OpenGL?, ¿cómo puedo usarlo?

Sabido es por los seguidores de antaño que durante el pasado año he publicado algunos códigos del tema en cuestión, pues que sirvan estos de complemento para mis próximos artículos y les sacaremos mejor provecho. También quiero aclarar que mi mayor referencia para este trabajo consta fundamentalmente de dos documentos:
-El Libro Rojo de OpenGL (OpenGL RedBook)
-El Libro Azul de OpenGL (OpenGL BlueBook)
Así que si quedaran insatisfechos con la documentación que este trabajo representa ya saben a donde remitirse... y la verdad, espero que los realmente interesados queden insatisfechos :)

[(Como diría mi amigo DarkX: Zero is begin) ¿Qué es OpenGL?]

OpenGL (Open Graphics Library) no es más que una API que nos permitirá a nosotros, los programadores, sacar el mejor partido a nuestros dispositivos de gráficos y aceleradoras 3D, de modo que OpenGL es justo lo que estabas buscando si tu objetivo es la programación de gráficos avanzados en 2D/3D siendo amplia la gama de aplicaciones que bien pueden ir desde sistemas de simulaciones con alto valor científico hasta el más común de los juegos que hayas visto en cualquier consola. Esta API nos provee de una buena cantidad de comandos que nos permitirán realizar todas las tareas que puedas imaginar necesarias para el desarrollo de este tipo de aplicaciones, inicialización, definición de primitivas geométricas, definición de objetos complejos, aplicación de texturas, iluminación, transformación, etc. Bueno es aclarar que OpenGL (distinto a DirectX) solo nos facilitará el trabajo con gráficos, dejando a nuestro entero cuidado otras cuestiones como audio, red, o controles. Aún así esto no representa gran motivo de preocupación, y aunque resulta un poco anticipado solo diré que existen otras librerías similares como es el caso de OpenAL (Open Audio Library), así que por ahora solo tenlo en cuenta.

[Librerías acompañantes de OpenGL]

OpenGL como libraría independiente nos ofrece todas las funcionalidades necesarias para el trabajo con gráficos, no obstante surgen tareas realmente tediosas como es el caso de la proyección de matrices, posicionamiento de la cámara y otras para las cuales se han ideado librerías adicionales diseñadas expresamente para hacer más fácil nuestro trabajo.

GLU: Nos permite el trabajo no solo con primitivas geométricas, sino que nos ayuda a crear objetos un poco más complejos como cilindros, esferas, discos, y otros sin tener nosotros que preocuparnos si quiera de definir normales o coordenadas de texturas en caso que el objeto se defina texturizado o bajo la influencia de alguna luz en la escena. Nos facilita bastante también el trabajo con matrices. Esta librería la usaremos a menudo en nuestros proyectos. Glu siempre acompaña a las distribuciones de OpenGL.

GLUT: Independiente a la plataforma en que se está trabajando. Nos permite el trabajo de inicialización de ventanas, entradas del teclado y del ratón etc. Todo esto con independencia de si el código está siendo compilado en Windows, en Linux o en MacOS (¿Que no dije anteriormente que OpenGL se encuentra en múltiples plataformas? :o ) Además nos ofrece comandos para dibujar objetos más complejos. ¿Te acuerdas de la famosa cafetera que sale hasta en la sopa en todos los programas de diseño 3D? Quien ha visto el Teapot del 3DMax sabe a qué me refiero.

GLAUX: Muy parecida a Glut pero solo existe para Windows.

GLX: Librería para X-Windows en Linux, no diré mucho más de esta porque nunca la he usado.

OpenAL: La ya mencionada Open Audio Library. Nos permite el control del sonido, incluye soporte para sonidos en 3D, tan importante en aplicaciones de este tipo. Pues se vería bien mal que disparas contra tu objetivo con una Dragunov desde la cuarta planta de un edificio y escucharas el impacto del proyectil a tu lado, o que sintieras la deflagración de tus explosivos justo en frente cuando realmente han estallado a tu espalda.

OpenXX: Existen otras librerías similares a OpenAL que por ahora se encuentran fuera del alcance de este documento, es el caso de OpenNL (Network), OpenIN (Input), etc.

[Definiendo el entorno de trabajo]

Tal como les comentaba hace un momento, OpenGL es una librería multiplataforma, así que podrás encontrar distribuciones tanto en Windows, como en Linux o MacOS, incluso la última consola de la Nintendo, la admirable Nintendo Wii, utiliza OpenGL para generar sus gráficos según tengo entendido. Al momento de definir un entorno de trabajo he decidido tomar Windows XP como sistema operativo, C++ como lenguaje de programación y para ser más específico Borland C++ Builder 6 como compilador. Aunque estas son mis preferencias particulares, bien podrías utilizar otros compiladores o lenguajes. Para los programadores de Delphi les recomiendo Borland Delphi 6 en sustitución de Delphi 7 para estos menesteres.

[Prerrequisitos para comenzar a utilizar OpenGL]

Basta ya de tanta plática y vamos a los códigos. Primeramente, ¿qué necesitamos para comenzar a trabajar con OpenGL?

Para empezar estaría bien hacernos de una ventana donde dibujar nuestros objetos 3D, a menos que tengas en mente renderizar tus escenas en hologramas o algún otro dispositivo no convencional tendrás que conformarte con utilizar el DC de nuestras ventanas de Windows como lienzo portador de nuestro arte.

Comenzaremos en el menú File, New, Other... luego seleccionamos Console Wizard y marcamos las opciones tal como aparece en la imagen 2.



A partir de aquí asumo que posees conocimientos al menos básicos de cómo crear una ventana en Windows, que entiendes el bucle de tratamiento de mensajes, etc. De no ser así tendrás que estudiar un poco más antes de recibir esta documentación, luego pásate por el apéndice de este capítulo. Sustituye el código por este:

#include <windows.h>
#pragma hdrstop
#pragma argsused

HWND hWndMain; //almacena el handle de nuestra ventana
bool bFinished; //determina cuándo la aplicación ha sido terminada

/*Aquí escribiremos un poco de inicialización*/
void Start()
{
  bFinished = false;
}

/*Aquí liberaremos algunos recursos reservados*/
void Destroy()
{
  bFinished = true;
}

/*Una de las funciones más importantes, justo aquí dibujaremos*/
void Draw()
{
}

/*Controlaremos en esta función algunas cuestiones al momento de redefinir el tamaño de la ventana */
void Resize()
{
}

/*Bucle de control de mensajes de la ventana*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_SIZE:
    {
      Resize();
      return 0;
    }
    case WM_DESTROY:
    {
      Destroy();
      return 0;
    }
  }
  return DefWindowProcA(hwnd,uMsg,wParam,lParam);
}

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  MSG msg;
  WNDCLASS wndclass;
  char szClassName[] = "OpenGL";

  hInst = hInstance;

//Llenamos la estructura wndclass
  wndclass.style = CS_VREDRAW | CS_HREDRAW;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
  wndclass.hCursor = LoadCursorA(NULL, IDC_ARROW);
  wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = szClassName;

//registramos la clase
  RegisterClassA(&wndclass);

//creamos una ventana basados en esa clase
  hWndMain = CreateWindow(szClassName, szClassName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, hInstance, 0);
  ShowWindow(hWndMain, nCmdShow);
  Start();

//mientras la aplicación no esté finalizada
  while (!bFinished)
  {

//recegemos el mensaje de la cola y lo enviamos
//al bucle de tratamiento
    if ( PeekMessageA(&msg, 0,0,0, PM_REMOVE) )
    {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
    else
    {
//Dibujaremos solo cuando la ventana no esté
//procesando mensaje alguno
      Draw();
    }
  }

  return msg.wParam;
}

Presiona F9 para correr la aplicación, si todo sale como es debido tendrás una ventana en pantalla completamente funcional que podrás redimensionar, mover, etc.

[Inicialización]

El proceso de inicialización de OpenGL puede resultar realmente engorroso y tedioso, pero normalmente los códigos que mostraré a continuación serán siempre los mismo para todos tus programas 3D, de modo que sobra la necesidad de memorizarlos, solo entenderlos bastará, además, en esta o en la segunda entrega me encargaré de encapsular toda la inicialización en una librería para hacer el trabajo mucho más simple.

Comenzaremos primeramente por agregar los includes necesarios.

#include <windows.h> //necesario para crear la ventana
#include <types.hpp> //utilizaremos alguna que otra estructura definida aquí
#include <gl\gl.h> //la librería principal de OpenGL
#include <gl\glu.h> //ya debes conocer GLU

Continuamos con las variables globales, verás que han sido agregadas dc y rc, estás variables serán imprescindibles para el renderizado y representan el device context y render context respectivamente.

HWND hWndMain; //almacena el handle de nuestra ventana
bool bFinished; //determina cuándo la aplicación ha sido terminada
HDC dc; //contexto de dispositivo
HGLRC rc; //contexto de render de OpenGL

Inicializamos...

Primeramente obtenemos el Device Context de nuestra ventana y lo almacenamos en dc. Luego comenzaremos a definir el formato de pixel que queremos, para ello usamos el descriptor pfd con doble buffer, colores RGBA y 32 bits de colores. Buscamos un formato correspondiente a la descripción que hemos hecho y lo seleccionamos. Posteriormente creamos y activamos el Render Context. Es importante en este punto redimensionar la ventana, en este caso lo he hecho a 640x480. Por último definimos algunos detalles como el color de fondo, el modelo de sombreado, activación del buffer de profundidad, etc.

Me corresponde hacer una aclaración importante respecto a la función glClearColor y más específicamente a la manera en que OpenGL utiliza los colores. Tal como conoces, todos los colores pueden ser representados a partir de los tres primarios, rojo, verde y azul, igualmente en OpenGL cuando defines un color tienes que hacerlo de la misma manera. A la función glClearColor le hemos pasado 0.2 como primer parámetro, 0.2 como segundo, 0.5 como tercero y 1.0 como cuarto o lo que es lo mismo 0.2 unidades de rojo, 0.2 de verde, 0.5 de azul y el cuarto parámetro representa la transparencia (RGBA = Red, Green, Blue, Alpha) con lo que hemos obtenido un azul opaco para el fondo de nuestro lienzo.

/* Aquí escribiremos un poco de inicialización*/
void Start()
{
  bFinished = false;
  PIXELFORMATDESCRIPTOR pfd;
  int pf;

//obtiene el contexto de dispositivo de la ventana
  dc = GetDC(hWndMain);

//describimos el formato de pixeles que queremos
  pfd.nSize = sizeof(pfd);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | 0;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 32;

//vemos si está disponible y lo seleccionamos
  pf = ChoosePixelFormat(dc,&pfd);
  SetPixelFormat(dc,pf,&pfd);

//creamos el contexto de render y lo seleccionamos
  (void *)rc = wglCreateContext(dc);
  wglMakeCurrent(dc, rc);

//redimensionamos la ventana a 640x480
  SetWindowPos(hWndMain, NULL, 0, 0, 640, 480, 0);
  glClearColor(0.2,0.2,0.5,1.0);
//seleccionamos el color de fondo
  glShadeModel(GL_SMOOTH); //modelo de sombreado suavizado, normales por vértices
  glClearDepth(1.0); //define el valor con que se limpiará el buffer de profundidad
  glDepthFunc(GL_LESS); //valor usado en la comparación del buffer de profundidad
  glEnable(GL_DEPTH_TEST); //activamos buffer de profundidad
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); //seleccionamos la corrección de perspectiva más rápida
  glEnable(GL_TEXTURE_2D); //activamos el texturado
  glEnable(GL_COLOR_MATERIAL); //activamos el color para los materiales
}

La función Destroy() para la liberación de recursos es bien sencilla. Simplemente desactivamos el Render Context de OpenGL y lo eliminamos al igual que al Device Context.

/*Aquí liberaremos algunos recursos reservados*/
void Destroy()
{
  wglMakeCurrent(0,0);
//desactivamos el render context
  wglDeleteContext(rc); //eliminanos el render context
  ReleaseDC(hWndMain, dc); //liberamos el device context de la ventana
  bFinished = true;
}

Aunque aun no dibujaremos nada en la ventana nos será necesario ir preparando la función Draw() para su uso. Por cada frame que dibujamos en pantalla necesitamos primeramente, borrar el contenido del lienzo, es decir, el buffer de colores y el de profundidad, cargar la Matrix Identidad (aun no corresponde hablar de matrices, eso lo veremos en próximos capítulos), forzamos la ejecución de los comandos GL con glFlush hasta ese momento y por último intercambiamos entre los buffers frontal y tracero con SwapBuffers. Para comprender correctamente la necesidad de SwapBuffers haremos una pausa para una aclaración. Si recuerdan cuando definimos el tipo de pixeles a utilizar escogimos un descriptor con doble buffer y justamente entre estos dos buffer la función SwapBuffers trabaja. Cuando la computadora tiene que representar una escena en movimiento debe hacerlo de la manera más rápida posible para que nuestro juego/simulador no corra lento, consideren entonces que a cada frame debe borrarse lo que hay dibujado en la pantalla y pintarlo de nuevo. Esta tarea no presenta gran problema en escenas sin animación pero cuando está presente la misma aparece un efecto indeseado de pestañeo. La manera de corregirlo es mostrando un lienzo(buffer), mientras el otro está siendo borrado y redibujado(back buffer), luego se intercambian.

/* Una de las funciones más importantes, justo aquí dibujaremos*/
void Draw()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glFlush();
  SwapBuffers(dc);
}

Nos corresponde en este punto definir el comportamiento de la ventana cuando esta es redimensionada. Primeramente obtenemos el ancho y el alto, si el alto se encuentra en 0 le asignamos 1 para evitar una división por 0 en las próximas líneas. Usaremos la función glViewport para especificar el tamaño del lienzo, los primeros dos parámetros hacen referencia a la esquina superior izquierda (normalmente serán cero los dos) los dos últimos a la esquina inferior derecha que corresponden justamente con el ancho y alto de la ventana respectivamente. Otra función importante en el proceso de redimensión es gluPerspective que define justamente la perspectiva de la cámara. gluPerspective funciona tal como si estuviéramos escogiendo el lente que usará nuestra cámara y a través del cual será visto el mundo. El primer parámetro indica la amplitud del lente, 65º en este caso. Este valor resulta útil a la hora de realizar ciertos efectos de cámara como el zoom de una mira telescópica o el efecto "ojo de pescado" de la mini cámara de un misil teledirigido. El segundo parámetro indica el radio de visión, el tercero la distancia a partir de la cual comienzan a dibujarse los objetos y el último parámetro la distancia a partir de la cual ya no se dibujarán los objetos. Con estos cuatro parámetros hemos definido lo que se conoce como el frustrum de la cámara.

/* Controlaremos en esta función algunas cuestiones al momento de redefinir el tamaño de la ventana */
void Resize()
{
  TRect WinRect;
  int Width, Height;
  GetWindowRect(hWndMain, &WinRect);

  Width = WinRect.Right - WinRect.Left;
  Height = WinRect.Bottom - WinRect.Top;

  if (Height == 0)
  {
    Height += 1;
    SetWindowPos(hWndMain, NULL, WinRect.Left, WinRect.Top, Width,Height,0);
  }

  glViewport(0, 0, Width, Height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(65, (GLfloat)Width/(GLfloat)Height, 0.1f, 100.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

El resto de nuestro código por ahora aparece invariable pues no hemos hecho cambio alguno en el bucle de tratamiento de mensajes o en la función WinMain.

/* Bucle de control de mensajes de la ventana*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_SIZE:
    {
      Resize();
      return 0;
    }

    case WM_DESTROY:
    {
      Destroy();
      return 0;
    }
  }

  return DefWindowProcA(hwnd,uMsg,wParam,lParam);
}

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  MSG msg;
  WNDCLASS wndclass;
  char szClassName[] = "OpenGL";

  hInst = hInstance;

//Llenamos la estructura wndclass
  wndclass.style = CS_VREDRAW | CS_HREDRAW;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
  wndclass.hCursor = LoadCursorA(NULL, IDC_ARROW);
  wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = szClassName;

//registramos la clase
  RegisterClassA(&wndclass);

//creamos una ventana basados en esa clase
  hWndMain = CreateWindow(szClassName, szClassName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, hInstance, 0);

  ShowWindow(hWndMain, nCmdShow);

  Start();

//mientras la aplicación no esté finalizada
  while (!bFinished)
  {

//recegemos el mensaje de la cola y lo enviamos
//al bucle de tratamiento
    if ( PeekMessageA(&msg, 0,0,0, PM_REMOVE) )
    {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
    else
    {

//Dibujaremos solo cuando la ventana no esté
//procesando mensaje alguno
      Draw();
    }
  }

  return msg.wParam;
}

Corriendo la aplicación que acabamos de escribir debemos ver una ventana como esta. Por ahora solo tenemos un lienzo en blanco pero ya habremos superado el proceso de inicialización de OpenGL.

[Encapsulando la inicialización]

Resultaría sin duda alguna tediosa y poco alentadora la necesidad de escribir todo este volumen de código para solamente preparar la ventana donde dibujaremos por cada vez que iniciamos un proyecto en OpenGL. Con motivo de hacernos la vida más fácil y debido a que la inicialización comúnmente será la misma, convendría construirnos una librería que encapsulara la tarea de iniciar OpenGL y de este modo obtendremos un código mucho más funcional y limpio.

[La clase CGL]

//---------------------------------------------CGL.H---------------------------------------------
#include <glaux.h>
#include <types.hpp>
#include <windows.h>

class CGL
{
  private:
  HDC dc;
//Device Context
  HGLRC rc; //Render Context
  public:
  CGL();
  ~CGL();
  void InitOpenGL(HWND hWnd);
//Inicia OpenGL
  void Resize(HWND hWnd); //Control de redimensión de ventana
  void StopOpenGL(HWND hWnd); //Termina OpenGL
  void StartSceneDraw(); //Comienza el dibujado, todo lo que se dibuje debe encontrarse tras esta función
  void StopSceneDraw(); //Termina el dibujado
};

//---------------CGL.CPP-----------------
/********************************
**
** Nombre: CGL.cpp
**
** Autor: h0aX hoax@fresnomail.com
**
** Fecha: 30/03/2008
**
** Descripción: Tareas básicas de inicialización de OpenGL.
** Tutorial OpenGL para BlackHat. 0 Inicialización.
**
**
*********************************/
#include "CGL.h"

CGL::CGL()
{
}

CGL::~CGL()
{
}

void CGL::InitOpenGL(HWND hWnd)
{
  PIXELFORMATDESCRIPTOR pfd;
  int pf;

  dc = GetDC(hWnd);

  pfd.nSize=sizeof(pfd);
  pfd.nVersion=1;
  pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | 0;
  pfd.iPixelType=PFD_TYPE_RGBA;
  pfd.cColorBits=32;

  pf = ChoosePixelFormat(dc,&pfd);
  SetPixelFormat(dc,pf,&pfd);

  (void *)rc = wglCreateContext(dc);
  wglMakeCurrent(dc, rc);

  SetWindowPos(hWnd, NULL, 0, 0, 640, 480, 0);

  glClearColor(0.2,0.2,0.5,1.0);
  glShadeModel(GL_SMOOTH);
  glClearDepth(1.0);
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_COLOR_MATERIAL);
}

void CGL::Resize(HWND hWnd)
{
  TRect WinRect;
  int Width, Height;
  GetWindowRect(hWnd, &WinRect);

  Width = WinRect.Right - WinRect.Left;
  Height = WinRect.Bottom - WinRect.Top;

  if (Height == 0)
  {
    Height+=1;
    SetWindowPos(hWnd, NULL, WinRect.Left, WinRect.Top, Width,Height,0);
  }

  glViewport(0, 0, Width, Height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective( 65, (GLfloat)Width/(GLfloat)Height, 0.1f, 5000.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

}

void CGL::StopOpenGL(HWND hWnd)
{
  wglMakeCurrent(0,0);
  wglDeleteContext(rc);
  ReleaseDC(hWnd, dc);
}

void CGL::StartSceneDraw()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
}

void CGL::StopSceneDraw()
{
  glFlush();
  SwapBuffers(dc);
}

[Implementación de la clase CGL]

Para concluir solo nos resta conocer la manera de implementar la clase CGL.

#include <windows.h>
#include <CGL.h>

#pragma hdrstop
#pragma argsused

//variables globales
HWND hWndMain;
bool bFinished;
CGL *gl;

//prototipos
void Start();
void Destroy();
void Draw();
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Start()
{
  bFinished = false;
  gl = new CGL();
  gl->InitOpenGL(hWndMain);
//inicializamos en la función Start
}

void Destroy()
{
  gl->StopOpenGL(hWndMain);
//Liberación de recursos
  delete gl;
  bFinished = true;
}

void Draw()
{
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_SIZE:
    {
      gl->Resize(hWndMain);
//Redimensión
      return 0;
    }

    case WM_DESTROY:
    {
      Destroy();
      return 0;
    }
  }

  return DefWindowProcA(hwnd,uMsg,wParam,lParam);
}

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  MSG msg;
  WNDCLASS wndclass;
  char szClassName[] = "Tutorial OpenGL 0 de h0aX - Inicialización";

  wndclass.style = CS_VREDRAW | CS_HREDRAW;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
  wndclass.hCursor = LoadCursorA(NULL, IDC_ARROW);
  wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = szClassName;

  RegisterClassA(&wndclass);

  hWndMain = CreateWindow(szClassName, szClassName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 10, 10, NULL, NULL, hInstance, 0);

  ShowWindow(hWndMain, nCmdShow);

  Start();

  while (!bFinished)
  {
    if (PeekMessageA(&msg, 0,0,0, PM_REMOVE))
    {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
    }
    else
    {
      gl->StartSceneDraw();
//comienza el dibujado
      Draw(); //función de dibujado
      gl->StopSceneDraw(); //termina el dibujado
    }
  }

  return msg.wParam;
}

En la carpeta Tools de esta edición se incluye un ejemplo para mostrar lo aprendido hasta el momento de OpenGL.

[Apéndice para este capítulo]

Al concluir este primer capítulo imagino que habrán aprendido muchos algunas cosas nuevas sobre OpenGL, otros habrán aprendido incluso temas más básicas como la forma manual de hacernos de una ventana en Windows, pues seguramente estaban acostumbrados a desarrollar esta tarea de forma visual con el VCL de Borland. A modo de apéndice quisiera agregar algunas notas para mostrarles la manera de inicializar OpenGL sin necesidad de encargarnos nosotros de la creación de la ventana.

Normalmente cuando abrimos C++ Builder 6 inmediatamente el IDE nos muestra un nuevo proyecto creado, listo para ser usado por nosotros. Este proyecto incluye como elemento básico una ventana prefabricada por el VCL (Visual Component Library) en la cual podremos agregar controles todo de forma visual y sencilla. En este caso, y para facilitar el trabajo en OpenGL a las personas que solo saben utilizar el VCL, haremos uso de esta ventana para realizar con ella todas las tareas que vimos en temáticas anteriores.

Primeramente, en la unit correspondiente al Form1 agregaremos el header de nuestra librería CGL en el include.

#include <vcl.h>
#include <CGL.h>

Seguidamente declaramos una variable global correspondiente a nuestro objeto gl.

TForm1 *Form1;
CGL *gl;

Activamos el evento OnCreate del formulario y escrbimos la inicialización. OnCreate corresponde a la función Start() vista en los ejemplos anteriores.

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  gl = new CGL();
  gl->InitOpenGL(Handle);
}

En el evento OnDestroy definimos la liberación de recursos, OnDestroy equivale a la función Destroy() antes vista.

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  gl->StopOpenGL(Handle);
  delete gl;
}

Ya debes imaginar el trabajo correspondiente al evento OnResize

void __fastcall TForm1::FormResize(TObject *Sender)
{
  gl->Resize(Handle);
}

Si tienes buena memoria recordarás que en los ejemplos anteriores escribimos el bucle de tratamiento de mensajes de tal manera que la función Draw() para dibujar solo era invocada mientras la ventana no tuviera mensajes por procesar. Si intentáramos hacerlo de otra forma la aplicación no nos mostrará los resultados deseados. El medio de hacer que nuestra aplicación ejecute determinado código cuando no tenga mensajes pendientes para procesar es la siguiente.

En la paleta Aditional de componentes busca uno llamado ApplicationEvets e insertalo al formulario.

Luego presiona dobleclick sobre el evento OnIdle de este componente y en su interior escribe el código para el dibujado.

void __fastcall TForm1::ApplicationEvents1Idle(TObject *Sender, bool &Done)
{
  gl->StartSceneDraw();
  gl->StopSceneDraw();
  Done = false;
}

De haber seguido todos los pasos indicados obtendrás los mismos resultados que en los primeros ejemplos sin el VCL. Algunos curiosos se estarán preguntando por qué me abstengo a usar el VCL en mis ejemplos. Pues comienza por comparar los tamaños entre el ejecutable compilado con el VCL y el que no, mientras uno se lleva 448 Kb el otro ocupa solo 53Kb.

Escribir tu mismo el código de la ventana significa que tendrás un poco más de control sobre la misma, es muy probable que si continuas estudiando OpenGL en el futuro prefieras escribir tú todo el código en lugar de dejarle la tarea al VCL de Borland. También conviene decir que de esta manera podrás escribir tus programas OpenGL en cualquier compilador de C/C++ logrando deshacerte de cierta dependencia del compilador.

Hasta aquí este primer capítulo introductorio a la programación de gráficos avanzados en OpenGL. Por el momento nuestro lienzo permanece mudo y la función Draw() casi vacía. En la próxima entrega veremos más y hablaremos de creación de primitivas geométricas.

Quisiera que las personas interesadas en este y en los siguientes artículos que conformarán el tutorial me expresen su interés a hoax@fresnomail.com de modo que pudiera saber a cuantos y a quienes están siendo dirigidos mis esfuerzos, además de poder personalizar un poco el contenido con lo que ustedes consideren más interesante. De las personas que escriban dependen las próximas entregas, pues no tiene sentido escribir un tutorial de 10 capitulos con 20 páginas cada uno que solo vaya dirigido a 3 o 4 personas.

Continuar leyendo