poniedziałek, 31 października 2011

GPU RGB2HSV

Maly programik, konwertujacy obrazek .TGA z przestrzeni kolorow RGB do HSV z pomoca GPU. Jest to wstep do wiekszego projektu - sledzenia twarzy przez kamere. Najpierw taka twarz trzeba znalezc. :) Mozna to osiagnac po przejsciu na przestrzen HSV i znalezieniu pikseli mieszczaczych sie w odpowiednich wartosciach:

H= <0, 0.1> u <0.9, 1>
S= <0.2, 0.7>
V= <0.4, 1>

W tym celu chce uzyc karty graficznej. Jestem na etapie konwersji rgb2hsv:
-> wczytaj obrazek i zamien na teksture,
-> w oknie o rozmiarach obrazka wyswietl prostokat w rzucie ortogonalnym z uzyciem wyspecjalizowanego shadera, z nalozona tekstura,
-> zapisz okno do pliku.
Okazuje sie, ze taki sposob dzialania jest bledny, bo wystarczy ze obrazek bedzie wiekszy niz dostepny ekran. :) Da sie to obejsc, ale na razie jest ok. ;)

Prosty shader konwersji wyglada nastepujaco:

rgb2hsv.glsl.vp:
#version 130

in vec4 vVertex;
in vec2 vTexCoords;

// Transformation Matrix
uniform mat4 mvpMatrix;

smooth out vec2 vVaryingTexCoords;

void main(void) 
{ 
    vVaryingTexCoords = vTexCoords;
    gl_Position = mvpMatrix * vVertex;
}
    

rgb2hsv.glsl.fp
#version 130

uniform sampler2D colorMap;

smooth in vec2 vVaryingTexCoords;
out vec4 vFragColor;

void main()
{
//image RGB value
 vec4 t= texture2D( colorMap, vVaryingTexCoords.st );
//max, min and diff 
 float fmax= max(max(t.x,t.y),t.z);
 float fmin= min(min(t.x,t.y),t.z);
 float diff= fmax-fmin;

//set up vFragColor with max, vFragColor represent HSV
 vFragColor.xyzw= vec4(fmax); //x->H y->S z->V

//if max is not 0, set S value
 if (fmax != 0)
  vFragColor.y= diff/fmax;

//if max and min are same, H is 0
 if (fmax == fmin)
  vFragColor.x= 0;
 else { //otherwise
  if ( fmax == t.x ) { //if R is dominant
   float tmp= 0;
   if (t.y < t.z)
    tmp= 6;
   vFragColor.x= (t.y-t.z)/diff + tmp;
  } 
  else if ( fmax == t.y ) //if G is dominant
   vFragColor.x= (t.z-t.x)/diff + 2;
  else if ( fmax == t.z ) //if B is dominant
   vFragColor.x= (t.x-t.y)/diff + 4;
   
  vFragColor.x= vFragColor.x/6;
 }
}
Jak widac, vertex shader ma tylko przepuscic geometrie i wspolrzedne tekstury do fragment shadera, w ktorym odbywa sie wlasciwa konwersja. Po szczegoly konwersji odsylam do wikipedii lub ksiazki "Techniki Biometryczne, Czesc 1, Metody Rzopoznawania Twarzy" G.Kukharev, A.Kuzminski. Poniższy screenshot pokazuje, od lewej - obraz oryginalny, obraz w HSV po przepuszczeniu przez moj program i obraz kontrolny w HSV po przepuszczeniu przez MATLABowska funkcjce rgb2hsv:

Dla Leny w calej jej krasie i w rozdzielczosci 1084x2318 widac duza roznice w szybkosci dzialania pomiedzy MATLABem a napisanym programem, i o to chodzilo. :) Lena moze nie jest najszczesliwszym obrazkiem do testow, bo wiekszosc obrazka miesci sie w przedzialach HSV, ale to nic. :)




środa, 31 sierpnia 2011

Tower Defense Game

05.09 o 9.00 Musze oddac swoja gre, na razie prezentuje sie tak:
Co zostalo zrobione? Zarzadzanie teksturami, modelami, shaderami. Staralem sie stosowac Model-View-Controller, dlatego jest tez zarzadzanie modelami i widokami. Zrobilem proste animacje, np. obracania wiezyczki. Dodalem efekt bloom, poprawilem go troche w porownaniu do poprzedniej wersji (ktory byla testowana tylko z obrazkiem 2d ;)). Poza tym wydaje mi sie :), ze napisalem to zgodnie ze specyfikacja OpenGL 3.2 Core Profile.

A z wylaczonym bloomem, gra wyglada tak:
BTW, staralem sie jak najwiecej informacji trzymac poza kodem. To znaczy, np. czy bloom jest wlaczony czy nie decyduje o tym plik konfiguracyjny. O tym jak wyglada model (np. jego kolor) tez decyduja pliki zewnetrzne. Niby nic, a jakie fajne gdy sie testuje rozne rozwiazania. :)

Krotki film, jakze krotkiego intra. (:


Czy to wystarczy na zaliczenie? Powinno, biorac pod uwage fakt... o, i w tym momencie ugryze sie w jezyk. :)

piątek, 12 sierpnia 2011

Wavefront OBJ Model File Loader

Napisalem loader plikow .obj do swojej gry. Na szybko, niezdarnie ale dziala. :) Najpierw zczytuje dane z pliku .obj do klasy Geometry. Potem tworze obiekt GLTriangleBatch na podstawie tych danych. Miejsce na ulepszenia to przede wszystkim pozbycie sie redundancji danych i przyspieszenie dzialania, dzieki pominieciu klasy Geometry, Vertex, Normal, TextureCoordinate i ew. Face. Ale to moze kiedy, teraz "there is no time for this". :)




Link do projektu eclipse z kodem zrodlowym.