Photosynth


Desde hace algún tiempo me he puesto a seguirle los pasos a Photosynth, este tipo de proyectos se me hacen super interesantes y desde luego muy complicados...

Imaginen las posibilidades de crear albumes fotográficos así, que podemos subir fotos nuestro facebook (por mencionar alguno), que el server cataloge nuestas fotos y las agregue a un albúm temático donde podamos visualizarlas de una manera nueva, como por ejemplo este tipo de paseo 3D.

Les dejo un synth que hice sobre el lugar donde trabajo. (nesecitan instalarse el plugin para verlo, haganlo se los recomiendo :D)




En la página de Photosynth pueden encontrar lugares más famosos que me oficina, por ejemplo el vaticano :P

Influencias videogamicas


En estos días me metido en el misterioso mundo del Game Design, el arte de hacer un juego divertido, de planear y saber que es lo que quieres hacer para que la gente se quede traumada, así que uno de mis ejercicios es comenzar por definir mis influencias, cuales son los juegos que más me han impactado y por que, bueno si me quedara en una isla decierta llena de mujeres seguramente aparte de cerveza me gustaría tener estos títulos:


Syphon Filter
Ofrece una camara exelente en tercera persona, la posibilidad de apuntar con el arma, gran variedad de niveles y armas, la historia es buena, tienes que explorar practicamente todo el nivel y encontrar puntos ocultos.

Tony Hawk's 2
El replay value es maravilloso, hay un buen de trucos por aprender, la curva de aprendizaje esta muy bien manejada, el modo multiplayer es genial, tienes muchisimas "gaps" por descubrir.

Starcraft
El modo multiplayer es perfecto, el que puedas crear tus escenarios, tengo mas de 6 años jugandolo y no me enfado, TOWER DEFENSE!! la tecnología manejada en aquella época y el juego que lograró hacer...

Final Fantasy 9
Tiene una historia envolvente metida en un mundo de fantasia, hay mucho mucho mucho que explorar, las gráficas son geniales, el modo de juego por turnos es divertido e intuitivo.

Silent Hill
Acción, terror, una historia que no sabes ni que rollo, el ambiente con poca iluminación, mucha bruma y colores pobres le da un aspecto único.

Resident Evil 2
Acción, armas, historia, puzzles.

Wip3out
Este juego es el resultado de mezclar la velocidad con la acción, me gusta el ambiente futurista, como manejan las gráficas y la música.

Crash Bandicoot 2
Tiene uno de los mejores controles que he visto en videojuego, a pesar de ser de plataforma se puede complicar mucho, hay muchas gemas secretas que sacan de onda.

Cristalys
Este pequeño RPG fue divertidismo durante mi infancia, a pesar de que para aquel entonces era un /n00b tenia una jugabilidad donde cualquier persona se podia sumergir, otro aspecto fue el sistema de batallas en tiempo real, algo que me gusta de los RPG.

Quake 3
Corre, dispara, asesina, se asesinado, revive, repite... este juego es brutalmente adicitvo, su gameplay es muy sencillo y esta soportado por muchos mods.

Counter Strike
La gran diferencia entre quake3 y counter strike es que aquí la estrategia y el trabajo en equipo son importantes.

Golden Eye
Otro de dispraros tipo quake, solo que aquí tienes que utilizar un poco más el cerebro y cumplir ciertos objetivos, los tipo de juego en multiplayer son bastante buenos.

Rainbow Six
Muchisima más estrategia y realismo que counter strike, la historia es genial, la forma en que planeas las misinoes y haces cambios entre tu equipo, el modo multiplayer :D

Warcraft
Básicamente el mero mole son los mods, llamemosle DOTA y Tower Defense :P

Sonic Adventure 2
En este juego de plataforma la velocidad es un elemento fundamental, algunas veces no tengo idea de como corro, simplemente no puedo dejar de hacerlo, buen replay value, mini juegos, modo multiplayer, el chaos garden...



bueno, aparte un twister, un billar y una baraja para acompañar esa cervezita y esas mujeres no caeria nada mal.......

Muere el Hijo del Papá


Al igual que la muerte del bien querido Valentin Elizalde nuestro amigo hijo del presi de la CANACA ha muerto y con el miles de ilisiones en nuestros niños mexicanos :(

http://www.dk1250.com/local/2650.html


Ahora quien servirá de mal ejemplo para esos chamacos ebrios entrados e la pubertad, sinceramente yo esperaba tener otro par de videos del él.

Otro hecho inedito en el país es el accidente ocacionado por un elefante en plena autopista, no mms!! puros pinches accidentes :(

http://www.cronica.com.mx/nota.php?id_nota=386781


Don canacas no muere, vive en nuestro corazones.

No pongo el link del video porque a menos de que hayan vivido en una alcantarilla los últimos meses ya lo deben de haber visto.

La próxima vez que piensen manejar borrachos recuerden que pueden ser amarrados como puercos y perder 50,000 pesos en el acto.

Problem with my pong game


Hey!! can you help me to fix this code, I get some flicker :S




LOL!!, I hate the "hello, world" introduce code, so when I like to lear a new lenguaje I always try to make a pong (I think you get noticed on my previous post :P), this time I just obsfuscate a c++ pong...

And here is a link to one of my favorite one's:

http://www.aerojockey.com/software/ioccc/index.html

VHDL Pong


En algunas ocasiones cuando uno no tiene nada que hacer se le ocurre cada cosa, como por ejemplo construir tu propia consola de videojuegos.

Tiempo: 1 hora

Costo: $30 – $150 US Dlls

Dificultad: Fácil






El primer paso es crear un pequeño juego en VHDL, así podemos entender (o aparentar que entendemos) las entradas de usuario, la lógica del juego y enviar los datos a un monitor VGA.

Básicamente el pipeline de lo que haremos será el siguiente:





En un post anterior explique como es la lógica del pong, y es la misma que implemento en VHDL.

Aquí lo más complejo es poder utilizar el puerto VGA, para esto necesitamos preocuparnos por los 5 pines, uno para cada componente de color en formato RGB, una para saber la posición vertical y horizontal en la que estamos trabajando.

Si ya hasta trabajado con Pixel Shaders la teoría te resultara familiar, prácticamente cada ciclo vamos a recorrer un pixel en la pantalla comenzando por la parte superior izquierda, en este punto especifico podemos modificar el color, si es un pixel shader!!!

Entonces para lograr esto debemos de sincronizarnos con el monitor, para esto vamos a lanzar nuestros primeros 640 colores para la primera línea con los pines para la sincronía horizontal y vertical con valor de 1, entonces vamos a avisarle al señor don monitor que baje una línea simplemente mandando un valor de 0 al pin de sincronización horizontal, y así nos la llevamos con cada línea hasta que tengamos que hacer lo propio con las 480 líneas verticales, entonces le aplicamos la misma al pin vertical y habremos concluido de dibujar nuestra pantalla así que comenzamos de nuevo. (Y es obvio que debemos de hacer lo mismo ya que el monitor no guarda ningún dato)

Una vez dicho esto creo que podemos pasar al código. :)





Al final el resultado debe de ser el del siguiente screenshot.



Basic4GL Pong


En este post vamos a ver como programar el clasico de clasicos, y por ser la primera vez con Basic4GL solo vamos utilizar las funciones print.

Primero dibujaremos nuestra pelota y la tabla con la que vamos a jugar:

TextMode(TEXT_BUFFERED)

while true
cls

locate 39,10
print "0"

locate 10,40
print "HHHHHHHH"

DrawText()
wend

A diferencia del tutorial anterior aquí agregamos las lineas locate, estas lineas le siguen dos números, el primero cambiara la posición inicial del texto en la posición X, y el segundo en la posición Y, experimenta un poco con esto a ver que pasa (lo números máximos son 39 para X, 24 para Y).

Si ejecutamos nuestro programa (F5), veremos en la pantalla nuestra tabla y una pelota aún sin movimiento.

Ahora vamos a controlar nuestra tabla, para esto utilizaremos las teclas de flecha derecha e izquierda:

TextMode(TEXT_BUFFERED)

dim playerX
while true
cls

locate 39,10
print "0"

locate playerX,40
print "HHHHHHHH"

if ScanKeyDown(VK_LEFT) and playerX > 0 then
playerX = playerX - 1
endif

if ScanKeyDown(VK_RIGHT) and playerX <>
playerX = playerX + 1
endif

DrawText()
wend

El pimer cambio es un dim playerX, dim es una palabra reservada de Basic para declarar que vamos a crear una variable y playerX es el nombre de nuestra variable.

Después vienen dos estructuras if que controlan nuestra tabla, en ambas comprobamos si el jugador esta presionando una tecla (VK_LEFT para la tecla izquierda, y VK_RIGHT para la derecha), si es así entontences vemos si aún no nos salimos de la pantalla, esto es: si la posición inicial en X es mayor a 0 aún estamos dentro, y si es menor a 31 (los 39 caractéres menos los 8 que mide nuestra tablita) sucede lo mismo así que podemos despazarnos sobre el eje X sin ningún problema.

Si ejecutamos, ahora podemos mover nuestra tabla.

TextMode(TEXT_BUFFERED)

dim playerX, ballX, ballY, movX, movY

movX = 1
movY = 1

while true
cls

ballX = ballX + movX
ballY = ballY + movY

if ballX <> 38 then
movX = movX * -1
endif

if ballY <> 24 then
movY = movY * -1
endif

locate ballX,ballY
print "0"

locate playerX,24
print "HHHHHHHH"

if ScanKeyDown(VK_LEFT) and playerX > 0 then
playerX = playerX - 1
endif

if ScanKeyDown(VK_RIGHT) and playerX <>
playerX = playerX + 1
endif

DrawText()
wend

Ahora agregamos más variables y otro par de sentencias if.

Las variables ballX y ballY controlan la posición de nuestra pelota en los ejes de coordenadas, movX y movY controlan la dirección de la misma de la siguiente manera:

Si la bola se esta moviendo positivamente movX y movY valdran 1, de lo contrario se valor será de -1, por lo que si lo sumamos cada vez a la posición de la pelota esta se movera en dicha dirección.

Despúes dentro de los if's vamos a comprobar si nuestra pelota aún permanece dentro de la venta de manera similar a lo que hcimos con la tabla pero además agregaremos el eje Y.

Si lo ejectuamos podremos ver la bola rebotando por toda la ventana.


TextMode(TEXT_BUFFERED)

dim playerX, ballX, ballY, movX, movY

movX = 1
movY = 1

while true
cls

ballX = ballX + movX
ballY = ballY + movY

if ballX <> 38 then
movX = movX * -1
endif

if ballY <> 24 then
movY = movY * -1
endif

if ballY > 23 then
if ballX > playerX and ballX < (playerX + 8) then
movY = movY * -1
else
cls
locate 15,10
print "Game Over"
DrawText()
end
endif
endif

locate ballX,ballY
print "0"

locate playerX,24
print "HHHHHHHH"

if ScanKeyDown(VK_LEFT) and playerX > 0 then
playerX = playerX - 1
endif

if ScanKeyDown(VK_RIGHT) and playerX <>
playerX = playerX + 1
endif

Sleep(75)
DrawText()
wend

En esta última parte solo vamos a eliminar el rebote de la pelota con la parte baja de la ventana, y lo vamos a cambiar por un game over, o en el caso de que le peguemos con la tabla programaremos la acción correspondiente.

En el primer if solo eliminamos la última comprobación, y en el segundo sólo vamos a entrar cuando la pelota este al nivel de la tabla, a partir de ahi solo tenemos 2 opciones, le dimos o no le dimos: si la posición x de la pelota se encuentra entre la pocisión inicial y la final (playerX + 8) de la tabla, significa que le dimos, sino simplemente borramos la pantalla y dibujamos un letrero de game over.

El utimo Sleep(75) indica que vamos a esperar 75 milésimas de segundo cada que lleguemos a él, esto causara que el programa se vuelva más lento y la pelota no este desquiciada.

estupendo

Finalmente le ponemos algunos extras, intenten agregarle m[as cosas, por ejemplo acá ya tiene el puntaje implementado:

TextMode(TEXT_BUFFERED)

dim playerX, ballX, ballY, movX, movY
dim score as integer

movX = 1
movY = 1

reset_game:

ballY = 0
ballX = 10 + (Rnd() % 20)

playerX = 16

while true
cls

ballX = ballX + movX
ballY = ballY + movY

if ballX <> 38 then
movX = movX * -1
endif

if ballY <> 24 then
movY = movY * -1
endif

if ballY > 23 then
if ballX > playerX and ballX < (playerX + 8) then
movY = movY * -1
score = score + 1
else
while true
cls

locate 15,10
print "Game Over"

locate 13,12
print "Try again(y/n)"

if KeyDown("Y") then
goto reset_game
end if

if KeyDown("N") then
end
end if

DrawText()
wend
endif
endif

locate 0,0
print "Score: " + score

locate ballX,ballY
print "0"

locate playerX,24
print "HHHHHHHH"

if ScanKeyDown(VK_LEFT) and playerX > 0 then
playerX = playerX - 1
endif

if ScanKeyDown(VK_RIGHT) and playerX <>
playerX = playerX + 1
endif

WaitTimer(100)
DrawText()
wend

OneNote Sudoku Addin


As many of you know the las months I've wrote a Sudoku Addin for the Office One Note, this was a part of my Student2Business assingment.

Finally the last week I get it working so you can take a look from CodePlex -codeplex.com/onom-

Also the John Guin blog (The Project Mannager) has a cool installation guide. -John Blog-


Download

Windows Live Agents


Muchos me han pedido que les explique como hacer un agente para el messenger, en realidad este proceso puede ir desde lo sencillo hasta algo muy complejo, obvio depende de que quieran hacer, por el momento simplemente haremos uno que detecté cuando estas ausente y si recibes un mensaje que le devuelva al remitente una respuesta.

Para esto vamos a crear un proyecto de biblioteca de clases.

Despúes agregamos como referencia el assembly MessengetClient.dll (que se encuentra dentro de la carpeta Windows Live/Messenger de archivos de programa.

Con esto vamos a poder utilizar en namespace Microsoft.Messenger el cual es necesario para crear una interfase en nuestra clase llamada IMessengerAddIn.

Para implementar dicha interfase debemo agregar el método Initialize(), aquí vamos a crear una instancia del cliente del cliente del messenger


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Messenger;

namespace WindowsLiveMessengerAgent
{
public class MessengerAddIn
: IMessengerAddIn
{
private MessengerClient _client;
private void IncomingTextMessage(object sender,
IncomingTextMessageEventArgs e)
{
if (_client.LocalUser.Status == UserStatus.Away)
_client.SendTextMessage(
"Lo siento, en este momento me encuentro ausente" +
"\nDeja tu mensaje y me comunico más tarde\n\n" +
_client.LocalUser.FriendlyName, e.UserFrom);

}
#region IMessengerAddIn Members

public void Initialize(MessengerClient messenger)
{
_client = messenger;

_client.AddInProperties.FriendlyName =
"WindowsLiveMessengerAgent";
_client.AddInProperties.Description =
"Este agente responde cuando no estas en linea.";

_client.IncomingTextMessage +=
new EventHandler<IncomingTextMessageEventArgs>
(this.IncomingTextMessage);
}

#endregion
}
}



Nota: antes de compilar hay que asegurarnos (de hecho no esta por default) de que nuestro assembly se llame igual que nuestro bot + . + nombre de la clase principal, ejemplo:

WindowsLiveMessengerAgent.MessengerAddIn

Una vez compilada nuestra biblioteca debemos cargarla en el messenger (Ojo: versión 8.5):

Abrimos messenger -> Opciones -> Accesorios -> Agregar a messenger -> Buscamos nuestro assembly;



Y lo activamos desde el menú principal..



:D y listo.


Las opciones con los agentes son muy divertidas y/o interesantes, por ejemplo unos compañeros y yo hicimos uno que procesaba los mensajes que recibia y mandaba una respuesta, hay uno que es de la Encarta el cául te ayuda a hacer búsquedas, o por ejemplo uno (para mí muy útil por cierto) que manda feeds de RSS.

Es cuestión de echarlo coco...

CUDA


Hace algunos dias me tope con una tecnología de nVidia llamada CUDA. uhmmm ¿Para que sirve? básicamente para utilizar el procesamiento many-core de los GPU's.

Además los GPU's modernos nos permiten desarrollar programas utilizando vector programming, así como utilizar algunas "opciones extra" a la hora de trabajar con floats...

Bien, a esto le vamos a agregar que podemos desarrollar nuestros programas en lenjuague C, e incluso integrarlo en varios IDE's.

Hace un rato me puse a integrarlo en VC++ 2005 (Guía ) y todo funciona perfectamente (ea ojo, solo vamos a utilizar el editor, para compilar necesitamos utilizar el compilador de CUDA)

Veamos un pequeño ejemplo pasado en C++


#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>

#define M_PI 3.14159265358979323846f

int _tmain(int argc, _TCHAR* argv[])
{
DWORD start = GetTickCount();
const int N = 200000;
float a[200000] = {0};

for (int i=0; i<N; i++)
a[i] = (float)i;


for (int i=0; i<N; i++)
a[i] =
sqrtf(sqrtf(cosf(a[i] / 1024 * (M_PI / 180.0f))) * sinf(1.0f)) *
sqrtf(sqrtf(cosf(a[i] / 1024 * (M_PI / 180.0f))) * sinf(1.0f)) *
sqrtf(sqrtf(cosf(a[i] / 1024 * (M_PI / 180.0f))) * sinf(1.0f));


DWORD end = GetTickCount();
printf("Processing time: %d %d (ms) \n" , end - start);

system("PAUSE");
return 0;
}


Sencillo, simplemente creamos un array y le aplicamos operaciones a lo bruto (a lo bruto).

Ahora nuestro ejemplo portado a CUDA sería algo así:


#include <tchar.h>
#include <stdio.h>
#include <cuda.h>
#include <cutil.h>

#define M_PI 3.14159265358979323846

__global__ void kernel(float *a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx<N) a[idx] =
sqrtf(sqrtf(cosf(a[idx] / 1024 * (M_PI / 180.0f))) * sinf(1.0f)) *
sqrtf(sqrtf(cosf(a[idx] / 1024 * (M_PI / 180.0f))) * sinf(1.0f)) *
sqrtf(sqrtf(cosf(a[idx] / 1024 * (M_PI / 180.0f))) * sinf(1.0f));
}


int main(void)
{
unsigned int timer = 0;
CUT_SAFE_CALL(cutCreateTimer(&timer));
CUT_SAFE_CALL(cutStartTimer(timer));

float *a_h, *a_d;
const int N = 200000;

size_t size = N * sizeof(float);
a_h = (float *)malloc(size);


cudaMalloc((void **) &a_d, size);

for (int i=0; i < N; i++)
a_h[i] = (float)i;

cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);


int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);


kernel <<< n_blocks, block_size >>> (a_d, N);


cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
CUT_SAFE_CALL(cutStopTimer(timer));


printf("Processing time: %f (ms) \n", cutGetTimerValue(timer));
CUT_SAFE_CALL(cutDeleteTimer(timer));

free(a_h);
cudaFree(a_d);
system("PAUSE");
}


Solo que esta pieza corre dos veces más rápido!! (AMD Athlon X2 vs GeForce 8800 GTX) y eso que aún estamos contando el tiempo de creación de datos que en realidad solo pasaría una vez en el programa.

¿En que es diferente el código?
El código en CUDA, tiene una función extra, esta función es nuestro kernel, en otras palabras la función que cargaremos al GPU; esto es elemental puesto que a todos los datos los vamos a procesar igual (como en los shaders), ademas todos los datos debemos de crearlos en el host, osea en la PC (ouch!! solo imaginen que la tarjeta de video esta aparte) y en el dispositivo (la tarjeta de video que suponemos esta aparte) y al hacer esto debemos de preocuparnos por su sincronización.

Este ejemplo es estupidamente sencillo, pero ahora imaginemos que podemos procesar partículas (jejeje voy a hacer eso esta semana), fluidos, física, u otro tipo de cosas donde el procesamiento es elemental, sobre todo cuando vamos a aplicar una misma función a una gran cantidad de datos (SIMD - Simple Input Multiple Data).

F# + XNA


Cuando leí que al correr sobre .NET F# podía utilizar cualquier libreria dije "ya lo veremos", y vaya hasta el momento me ha funcionado bastante bien y para muestra me puse investigar acerca de cómo demonios meterle XNA... y es MUY SENCILLO :D


#light

#I @"C:\Program Files\XNA\v2.0\References\Windows\x86"

#r "Microsoft.Xna.Framework.dll"
#r "Microsoft.Xna.Framework.Game.dll"

open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Graphics
open System

type XNAGame = class
inherit Game as base

val mutable graphics : GraphicsDeviceManager

new() as this =
{
graphics = null
}
then
this.graphics <- new GraphicsDeviceManager(this)

override this.Draw(gameTime) =
let gd = this.graphics.GraphicsDevice
gd.Clear(Color.CornflowerBlue)
end

let Main() =
let game = new XNAGame()
game.Run()

[<STAThread>]
do Main()




:D ;) :) xD

Lo único de deben hacer es establecer el directorio donde tienen alojado el XNA, en este caso la versión 2.0 pero también lo probé con la 1.0 (oh si, mi version de F# es 1.9.3.14) porque tal parece que los assembly no estan en el GlobalAssemblyCache, otra opción es configurar el envoriment path (bucar en google) para poder acceder hasta él desde la linea de comandos.

Para compilarlo utilizé el siguiente batch:


@if "%_echo%"=="" echo off
setlocal

..\..\..\bin\fsc.exe xna.fs
if ERRORLEVEL 1 goto Exit

:Exit
pause
xna.exe
endlocal

exit /b %ERRORLEVEL%



Osea un compila y ejecuta.

Ya veré más delante que más le meto...

XNA HLSL Shaders


El día de ayer (bueno la madrugada de hoy) hicé un pequeño screencast acerca de shaders en XNA, les dejo el video y el link para descargar el código.





Tambièn les dejo la imagen de la escena lograda con este tutorial. :D




Bloom Cubemap



HLSL Shaders: Ejemplo en XNA


Hay una parte muy cool de cuando programar gráficos se trata, esa parte es el utilizar el GPU (Graphics Processing Unit) ósea la mismí­sima tarjeta de video para hacer cálculos y almacenamiento de memoria.

La Content Pipeline

Actualmente existen lenguajes de alto nivel (Cg de nVidia, HLSL de Microsoft y GLSL para OpenGL) que básicamente funcionan de la siguiente manera:


Content Pipeline


Primero obviamente lo que necesitamos es crear un shader, este lo podemos hacer desde Visual Studio, o utilizando un programa de autorí­a de shaders como el Render Monkey de ATI o FX Composser de nVidia, este archivo lo vamos a cargar en nuestra aplicación y la API gráfica se encargará de que la tarjeta de video lo compile en tiempo real, esto se hace para crear una optimización para cada tipo de hardware.
Una vez hecho esto nosotros generamos un conjunto de vértices (estos pueden ser por ejemplo un modelo 3D) activamos el shader desde nuestra aplicación y cuando el GPU realice los cálculos para la proyección tomará en cuenta los parámetros y métodos del shader; después nuestra los drivers convertirán esa salida generada (aún 3D) a coordenadas de pantalla, este proceso se le conoce como rasterización, con nuestros objetos proyectados en la pantalla podemos modificarlos una vez más, esta vez pí­xel a pí­xel. :D
Ejemplo

Supongamos que tenemos el siguiente código en un archivo .fx, podemos crear estos archivos dando click derecho en nuestro explorador de soluciones y en agregar nuevo Effect:





Código en Effect1.fx:



//Estas variables representan las matrices de posición de nuestro objeto
//la matriz de nuestra camara, y nuestra proyección
float4x4 World;
float4x4 View;
float4x4 Projection;


//Esta estructura indica que es lo que va a tomar el shader
//En este caso solo tomara la posición del vértice, podemos agregar
//las coordenadas de textura, normales, colores, etc.
struct VertexShaderInput
{
float4 Position : POSITION0;
};

//Esto es muy parecido a la estructura de entrada, pero aquí­ especificamos
//que queremos que devuelva nuestro método
struct VertexShaderOutput
{
float4 Position : POSITION0;
};

//Esta función es nuestro vertex shader
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;

//Sólo aplicaremos una sencilla transormación
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);

return output;
}

//Esta función es nuestro pixel shader
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//Aquí­ especificamos que queremos que para todo ­xel
//que se dibuje lo pinte de color rojo :)
//podemos por ejemplo regresar el valor de una textura respecto
//a la coordenada actual
return float4( 1, 0, 0, 1);
}

//Aqui especificamos nuestras técnicas
//un archivo fx puede tener varias técnicas
technique Technique1
{
//Para cada pasada especificamos que funciones vamos a llamar
//y ademas debemos de decirle bajo que perfil se compilarán
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}



Para utilizarlo vamos a modificar nuestra clase Game1.cs:

Primero, vamos a declarar dos objetos en nuestra clase, uno para el modelo que utilizaremos y otro para nuestro efecto:





Model _model;
Effect _effect;

Después vamos a modificar nuestra función LoadContent() para poder cargar nuestros archivos:



        protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

_model = Content.Load<Model>("model");
_effect = Content.Load<Effect>("Effect1");

///Esto va a quitarle el efecto actual al modelo y establecera el que
///le estamos asignando
foreach (ModelMesh mesh in _model.Meshes)
foreach (ModelMeshPart part in mesh.MeshParts)
part.Effect = _effect;

// TODO: use this.Content to load your game content here
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

float aspectRatio = graphics.GraphicsDevice.Viewport.Width /
graphics.GraphicsDevice.Viewport.Height;


//Definimos la tecnica
_effect.CurrentTechnique = _effect.Techniques["Technique1"];

_effect.Parameters["World"].SetValue
(Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up));
_effect.Parameters["View"].SetValue
(Matrix.CreateLookAt(new Vector3(0.0f, 5.0f, -10.0f), Vector3.Zero, Vector3.Up));
_effect.Parameters["Projection"].SetValue
(Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
aspectRatio, 1.0f, 10000.0f));

//Actualizamos el shader
_effect.CommitChanges();

foreach (ModelMesh mesh in _model.Meshes)
foreach (Effect effect in mesh.Effects)
mesh.Draw();


base.Draw(gameTime);
}


Por último vamos a dibujar nuestro modelo con el shader correspondiente y el resultado debe de ser el modelo dibujado completamente en rojo, y esta es la imagen de nuestro primer shader:





¿No es interesante? Bueno, es nuestro "hola, mundo!" de los shaders, así­ que de aquí­ podremos partir a cosas más interesantes como iluminación, a continuación les voy a presentar una imagen de un render un poco más complejo:



Este render contiene 3 shaders, uno para los reflejos del agua, otro para el brillo de la nave, y otro que le da un efecto de zoom radial. :)


Conclusiones

Los shaders se utilizan para prácticamente todo el procesamiento de gráficos, algunas aplicaciones lo manejan automáticamente pero si quieres tener el control completo y agregar efectos a tus aplicaciones gráficas la mejor manera es meterle mano.

Los shaders no solo se utilizan en videojuegos o aplicaciones 3D, también se utilizan en edición de imágenes o ví­deo, en un futuro tutorial hablaré de como crear shaders de post producción (como los que se utilizan para las pelí­culas).

About Me

Mi foto
carlos
Guadalajara, Jalisco, Mexico
Ver mi perfil completo

Twitter