_fpeti_ 2017.10.30. 20:54

DirectSound

Gondoltam csinálok egy pici framework-öt, ami minden installálás nélkül fut kb. bárhol. Hangnak DirectSound-ot gondoltam, elég régi cucc, de még megy, nem kell neki semmi extra dll-t installálni. Annyi gond volt vele, hogy nem  találtam más tutorialt, mint a Rastertek-eset. Ebben, ha betöltöttünk egy wav-ot, így kell létrehozni, hozzá a buffert,amit a DS le tud játszani:

result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL);
if(FAILED(result))
 return false; 
 
result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&*secondaryBuffer);
if(FAILED(result))
return false;

Szóval kell egy temp buffer valamér, utána kell megcsinálni a 'secondaryBuffer'-t, ami lejátszható.
Nekem a QueryInterface() E_INVALIDARG-ot ad vissza. Poénból megpróbáltam a tempBuffer-t
lock-olni, betölteni abba a hangot.. és le lehet játszani. Úgyhogy a bohóckodás nem kell a QueryInterface()-el.

 

Szólj hozzá!

_fpeti_ 2017.08.03. 22:17

C++ fordító mágia

Van ez a cseppnyi kód:

#include <iostream>
using namespace std;

class f
{
public:
   f() { v = 0; }
   f(int a) :v(a) {};
   const f& operator=(int a) { v = a; return *this; }
   const f& operator+=(const f& m) { v += m.v; return *this; }
   int getv() const { return v;};
private:
   int v;
};

void main()
{
   f test;
   test = 1;
   test += 5; // this works without f::operator+=(int) !
   cout << "so test is = " << test.getv() << endl; // prints '6'
}

Nekem érdekesnek tűnik, hogy a fordítónak nem okoz gondot, hogy hozzáadja az '5'-t anélkül, hogy lenne hozzá megfelelő operátor-túlterhelés. Debug-ban végigmenve kiderül, mit is csinál a vs2013c++ fordítója:
csinál egy temporális 'f' példányt, majd meghívja neki az op=(int) fv-jét, így értéke 5 lesz, majd ezt hozzáadja a 'test' példányhoz az op+=(const f&) segítségével.
Azaz rájött, hogy a meglévő függvényekkel meg tudja oldani a feladatot. Szerintem durva, hogy ilyenre rájön.

Szólj hozzá!

_fpeti_ 2016.06.05. 01:40

MS Visual c++ 2010 és a -1.#IND, ami csak release-ben jön elő

Néha előfordul a fenn említett rendszerrel, hogy release-ben full optim mellett mondjuk 3 float összeadása eredményeképpen +-1.#IND lesz a végeredmény. Nálam 3d vektor dotproduktja produkálta, a netet nézve úgy néz ki másnak is volt hasonló kalandja (x*x+y*y = #ind). Ha kikapcsolom az optimalizációt, elmúlik, de lassabb a program (180fps helyett 70).
Mit lehet tenni? Le kell cserélni, mert egy régi szar. 2013-on már jól megy.

Szólj hozzá!

_fpeti_ 2014.11.30. 23:58

Átállás Havok (hk2014_1_0_r1) régebbiről (vs2010EE alatt)

Ha van egy ilyen hiba:

hkGeometryUtilities.lib(hkMemoryMeshTexture.obj) : error LNK2019: unresolved external symbol "public: static class hkImage * __cdecl hkImageDecoderUtil::loadFromFile(char const *)" (?loadFromFile@hkImageDecoderUtil@@SAPAVhkImage@@PBD@Z) referenced in function "public: virtual class hkImage * __thiscall hkMemoryMeshTexture::Sampler::getImage(int)const " (?getImage@Sampler@hkMemoryMeshTexture@@UBEPAVhkImage@@H@Z)

Akkor ez a lib hiányzik neki:

hkImageUtilities.lib.

Szólj hozzá!

_fpeti_ 2014.03.01. 02:24

directx11 shader hiba

Mivel töltöm időmet: ez a kódrész azt eredményezi, hogy a konstans bufferre azt azt adja ki a dx runtime debugging, hogy 16 byteot adok meg (vec3 + pad), de 48 byte kéne neki.

Texture2D Texture[3];
SamplerState texSampler;

cbuffer whatnot
{
float3 viewposition;
};

#include "deferredfunc.c"
#include "cotangetframe.c"

Ha az #include-ok a file elejére kerülnek, elég neki a 16 byte, vagyis rendesen működik. Nem tudtam megtalálni, miért 48 byte kell neki, semmilyen más betöltött shadernek/cbuffernek nem kell ekkora buffer.

Szóval include-ok legfelülre mennek, vagy nem lehet tudni, mi lesz.

 

 

 

Szólj hozzá!

_fpeti_ 2014.01.25. 00:56

XAudio2 hiba

Véletlenszerűen kihagyott hangokat a játékom, gondoltam bekapcsolom a xaudio2 debugger funkcióját, ezzel:

HRESULT r = XAudio2Create(&xaDevice,XAUDIO2_DEBUG_ENGINE); 

Ez annyit csinált, hogyha meghívtam egy ilyet:

IXAudio2SourceVoice::Stop(XAUDIO2_PLAY_TAILS); // csak ezzel a parammal csinálja!!

Akkor széjjelfagyott a progi a Stop() fv.-ben. Ha nincs debuggolás, minden ok.
A hibáról egyébként kiderült, hogy lejátszás közben töröltem hangokat, IXAudio2VoiceCallback::OnBufferEnd() lefutása után kell törölni, én mást néztem, így már megy szépen, a debuggolást meg el is felejtem, mert csak bajt okoz, ráadásul nem is nagyon sok mindent lehet vele kideríteni. Kb annyit, hogy le volt-e terhelve az XA engine..sokat ér.

Címkék:XAudio2 Szólj hozzá!

_fpeti_ 2013.02.25. 00:47

Rossz blendelési súlyszám

Volt egy érdekes hiba, ami elvitt pár órát. A modelnézegetőt bütyköltem, de egy sarok körüli összes háromszögön a textúrázás rossz volt (a villa jobb ágának tövében kell keresni)
blend3.PNG

El nem tudtam képzelni, mi lehet a baja, mindenhol jó volt, csak ott nem 6 darab háromszögön az ominózus vertek körül, pedig minden háromszögnek külön vertexlistája volt. Minden adatot megnéztem, visszafejtettem a vertexbuffer adatokat, minden stimmelt, próbáltam még FVF fixed módon is előidézni a hibát, de nem sikerült. Az a nagy háromszög a csíkos textúrával annak az eredménye, hogy 2 vertex súllyal rajzoltam ki, és ettől a textúra elromlott..
Aztán kiderült, hogy ha nincsennek a vertex struktúrában a blendindex/weight adatok (2 súly +index per vertex) akkor nincs baj. De akkor miért nem rossz több helyen is a dolog? Végül átnéztem az eredeti modelt, amit kiexportáltam, és kiderült, hogy 3 súly is van néhol, de csak kettőt ír ki a konverter a végső file-ba. Ez nem magyarázza meg, miért a textúrázás romlott el, miért nem az animáció, és miért csak 1 helyen, ahol 3 súly kellett volna, de máshol is volt ilyen vertex. Kijavítva a konvertáló-bugot 3 súllyal már működik. Vertex méret, vertex adatok elhelyezkedése, vertex-deklaráció minden jó volt 2 súllyal is - ezt a progi automatikusan építi fel a model adataiból- de ha hiányzott a harmadik súly, széthúzta a textúrát. Vagy a tu vagy tv koordináta 1 volt az egész háromszögön, PIX-el is megnéztem, ott jó textcoordokat mutatott minden sarokban a vs_output-nál. Annál mélyebbre meg nem lehet menni vs/ps debugolásban. Rejtélyes, de ha megfelelő minden, akkor nem jön elő, lehet csak a régi vga-m szórakozik.

Címkék:hw-skinning textureproblem Szólj hozzá!

_fpeti_ 2013.02.25. 00:38

Modelformátum, hát már megint itt vagy.

Volt nekem egy problémám a content pipeline-omban. Már ha azt a pár poligonhalmazt kontentnek lehet nevezni, amiket összebarmoltam Blenderben tesztelés gyanánt. Nekiveselkedtem pár éve és összekínlódtam egy 50kb-os python-scriptet, ami szépen működött, a Blender 2.4x-es verzóiban. 2.5-tel jött a nagy pofáraesés, az eredeti szkript minden sora minimum egy helyen dobott egy hibát, így dobhattam el az egészet. Mivel nem rajongok a pythonért, gondoltam az egyetlen ésszerű dolog, ha meglévő formátumot használok, ami tényleg jó ötlet, hisz egy népszerűbb formátumba minden 3d-s szoftver tud menteni, de milyen jó lesz.
Ránéztem hát az Autodesk által fémjelzett FBX formátumra, amihez még SDK-t is adnak, ami betölti a file-t, én meg csak kiírom saját formátumomba, minden van benne, ami valaha csak kellhet. Elég jól is ment a gyér dokumentáció ellenére is, csak az animációnál akadtam fönn azon, hogy a Blender (2.6.5) fbx exportere minden frame-et kiexportál, nem csak a keyframe-eket.
Ez annyit jelent, hogy ha van 2 keyframe-em, mondjuk 1-es és 100-as képen a időskálán, akkor 100 transzformációt ír ki minden csontnak. Ezt én erős túlzásnak tartom, és kiderült, nem is teljesen ennek kéne lennie, azaz az exporter nincs a helyzet magaslatán. De azt is olvastam, hogy ez az fbx formátumot amúgy is sokszor mocap adatok átvitelére használják, ahol kb minden képkockán változhatnak a transzformációk, azaz megszokott, hogy minden pillanatra van külön adat. Most mit lehet tenni, másodpercenként 25 képpel számolva egy 10 mp anim 250 keyframe, mondjuk 10 csontra 2500 mátrix lesz az engine-ben, kicsit sok, megjegyzem az fbx szögekben tárolja a forgatásokat.

Nekem ez egy kicsit sántított, így vettem egy nagy levegőt, és ’együltömben’ írtam egy másik szkriptet az újabb Blenderhez, ami nem 50 hanem 5kb lett. Simán kidumpolok mindent egy köztes text-fileba, semmi extra kód, csak face-data, skinning, és animáció.
Írtam egy szimpla c++ konzolos progit, ami ezt a köztes filet beolvassa és előállítja a végleges adatokat az engine-nek, és azt már emészthető formában file-ba írja. Ezzel azt értem el, hogy ahelyett, hogy minimalizáltam a Blender-függő kód mennyiségét, így sokkal könnyebb frissíteni, ha valami változik. A konverter progi meg nagyjából marad mindig ugyanaz, hacsak nem kerül be valami extra, de cpp-ben nem nagy ügy.
A köztes file kiterjesztése mra lett (m-raw rövidítve). A kész modelfile .m típusú, hasonló a régihez, de pár dolgot hozzáadtam. Pl a régi csak 1 textúrát tudott kezelni, ami nem volt túl jó ötlet így visszagondolva.
Így van most egy Blender -> szkrtipt(python) -> .mra(texfile) -> mraimporter(c++) -> .m(textfile)  útvonalam.
Ezeken kívül van egy modelnézegető progi (mviewer.exe) és egy C-s dll, ami ’m’ fileokat olvas be, megkönnyítve bármilyen programban a használatukat.

Címkék:model3D Blender Szólj hozzá!

_fpeti_ 2012.05.21. 23:19

Repülő npc-k és a Havok

 

Jól elszórakoztam ezzel is, az Intel-es Havok fórumon is tiszteletemet tettem, ahol mondották, hogy hát 100 féle képen meg lehet oldani egy hkpCharacterRigidBody reptetését. 0-ra állítom a gravitciót és wiiiii, már száll is amerre akarom!
Ez igaz, de ha hozzáér bármihez a talpán, akkor odatapad, mert beindul a gyalogló-algoritmus, csúszósíkok számolása, stb. Ráadásul  a hkpCharacterContext::update mindig nullázza az y-t a mozgási irányban, így hiába adunk meg a hkpCharacterInput::m_forward-ban függőleges mozgási irányt, az csak vízszintes síkon hat. Így aztán én inkább kitaláltam magamtól, ahogy szoktam. :)
A megoldás:
ne vegye észre a kontroller, hogy áll valamin, amit ezzel lehet elérni:
hkpCharacterInput::m_surfaceInfo.m_supportedState = hkpSurfaceInfo::UNSUPPORTED;

A kontroller mozgatása ezután már működik, nem a hkpCharacterInput-on keresztül persze, hanem közvetlenül a rigidbody sebességét kell állítani, vagy a gravitációt +- irányba beállítani.

Elsőre furának tűnt egyébként, hogy nincs standard repülő-npc megoldás egy drága 'industry-standard api'- ban, de ez talán nem is olyan meglepő, ha a mai 3d-s játékokat nézzük. Ritkák manapság a repülő szörnyek, maximum helikopterek, azokat meg meg lehet oldani egyszerűbben is. Azok nem szoktak falakról visszapattanni, csúszkálni :3.
 

Szólj hozzá!

_fpeti_ 2012.05.19. 23:20

Non-blocking UDP server

Ezt kell a server kódba bind() elé tenni, és akkor a recv() és társai nem állnak le várni az infót. Ezt nem könnyen találtam meg a neten, hátha így könnyebb lesz másnak. :3
u_long on = 1;
ioctlsocket(Socket, FIONBIO,&on);

 

Címkék:server udp Szólj hozzá!

_fpeti_ 2012.04.29. 04:41

Öntapadó kézigránát.

 Él-e még valaki, aki ismeri a Shadow warrior nevű mókás szoftvert? Játék '97-ből, 3DRealms alkotása, akik a Duke Nukem-et is elkövették. Kb. ugyanaz a motor, nagyon elborult játék volt ez is. Volt benne egy 'sticky grenade' nevű tüskés gömb, amit el lehetett dobni, ha ellenfélre esett, akkor ráragadt és kis rohangálás után felrobbant. Ha falhoz csapódott a gránát, akkor egy mozgás érzékelős akna lett belőle, ha közel ment valami, akkor robbant fel. Lehet inkább a Halo-féle plazmagránáthoz kéne manapság hasonlítani.
Gondoltam nem árthat, ha én is megcsinálom :3.
Így három üzemmódja lett a kis piros gránátnak:
Sima időzített, ez most 4mp után robban, de lehet kézben kibiztosítva tartani, így lehet vele trükközni, hogy a levegőben robbanjon. Mondjuk túl sokáig nem érdemes szorongatni.
A ragadós változat mindenre rátapad, de az időzítő tovább fut, és ennek lejártával 'detonál'.
A harmadik mód az 'impact' nevet kapta, ez azonnal robban, ha hozzáér valamihez.
Rövidke demonstráció:
VIGYÁZAT: hangot is vettem föl, ami elég hangos.


Aki figyelt, annak feltűnhetett, hogy két hasonló robot van a képen. A távolabbit TALÁLTAM a kódban, egy régebbi verzió, de működik, csak nem csinált semmit azon kívül, hogy rázta a lábát, vagy ha észrevett, akkor próbált odajönni. Megfejeltem annyival, hogy ha közel ér, akkor mi mást is csinálna...  felrobban. Kezdem magam 'Michael Bay'-nek érezni :).

Címkék:grenade Szólj hozzá!

_fpeti_ 2012.02.13. 02:38

Új effekt

 Alphablendinggel nagyon sok olyan dolgot meg lehet csinálni, ami elég jól néz ki, de nem bonyolult megcsinálni. Csináltam is egy 'animált' (forog 'áze) jelenséget, de nem tudom mi a neve. 'Teleportálási effektnek' hívom. Minecraft-ból jött az ötlet (lehet néha mással is kéne játszani). Ott az 'End' dimenzióban a sárkány legyőzésekor láthatjuk. Csináltam egy kis modelt Blenderben, pár tucat 3szög, és mindegyiknek van egy csúcspontja középen. Semmi más nem kell, a színeket és a alfa mértékét a pixelshader elintézi. Eleve 'hw instancolósra' írtam, így sokat ki lehet belőle rajzolni egyszerre.

 

Címkék:alphablending Szólj hozzá!

_fpeti_ 2012.02.09. 03:16

Videókártyán számolt magasságtérkép árnyék.

 Van nekem egy magasságtérkép szerkesztő progim, nem egy nagy szám, van pár funkciója, többek között árnyékot is tud számolni, majd elmenti png-be. Eredetileg az árnyékot cpu-n számoltam, elég sok háromszög-sugár ütközés volt benne, és kb 10 percig tartott, mire egy 512x512 heightmap-en kiszámolt egy 2048x2048-as árnyéktérképet. Ráadásul nem is volt túl szép, még blur-ozni is kellett. Gondoltam, kipróbálom mi lenne ha gpu-n tolnánk a sugarakat, csináltam már afféle godray alapú árnyékokat 2d-s játékmotorban, ide pont jó lenne.

Elég egyszerű a dolog, kell hozzá 2 rendertarget textúra, az egyikbe készül a magasságtérkép, a másikba a shadowmap.
Az első mérete elég ha akkora, ahány cellából a térkép áll. Ebbe bele kell renderelni a hieghtmap-et úgy, hogy a legmagasabb pontja legyen 1, a legmélyebb pontja pedig 0. Ez nagyon könnyű, még projekciós mátrix sem kell hozzá. Csak -1 +1, és 1 -1 közé kell konvertálni a heightmap vecktorok xz komponensét, (vertex shaderben) majd a PS-nek átadva az y koordinátát azt elosztja a magasságtérkép legnagyobb magasságával, ezzel 0-1 közé konvertálja azt. (ha a lehet a vektor.y negatív, akkor még attól relatívvá kell tenni)

 

Kb ennyi a shader kód:

 

float2            origo; // hülye név csak a cellaszám felét adja meg

float2            zproj; // ’.x’ a minimum y, .y a himap magassága abszolút

 

void vs_himap(

            // input data

            float4 pos              :POSITION,

            float3 n                :NORMAL,

            float4 color0           :COLOR0,

            float4 color1           :COLOR1,

 

            // output

            out float4 opos              :POSITION,

            out float opixelheight  :TEXCOORD0)

{

      opos.xy = (pos.xz/origo);// world coord to x: -1 -> +1 y: +1 -> -1

      opos.zw = float2(0,1);

      opixelheight = pos.y;   // ps needz it

}

 

 

// simple diffuse with one color

void ps_himap(          float pixelheight :TEXCOORD0,

                        out   float4 oColor           :COLOR)

{

      oColor = (pixelheight-zproj.x) / zproj.y;

}

 

Most ebből számoltassam már ki a árnyékot, mégpedig úgy, hogy minden pixel koordinátájából a nap fele megnézünk egy csomó pixelt, és ha magasabb, mint a sugár y értéke ott, akkor árnyékol, csökkentsük a végső árnyékpixel-intenzitást. Ez gyakorlatilag egy csomó ’texture-fetch’ (pixel szín kiolvasás textúrából), ami talán a leglassabb, amit a gpu-n lehet. Egyébként ezt a módszert használják a pálmafa-levélen átszűrődő fénycsíkok rajzolására is a Crysis-ben például.

Kód:

float3            Invlightdir;

float2            HalfPixel;

 

texture Thimap;         // heightmap

 

// Himap

sampler Shimap = sampler_state

{

Texture     = <Thimap>;

MinFilter   = POINT;

MagFilter   = POINT;

MipFilter   = POINT;

AddressU    = CLAMP;

AddressV    = CLAMP;

};
void vs_shadowmap(

            float4 pos              :POSITION,

 

            // output

            out float4 opos         :POSITION,

            out float2 texcoord     :TEXCOORD0)

{

      opos = pos;

      // -1 -> +1 +1->-1 map to 0-1,0-1

      texcoord.x = pos.x*0.5 + 0.5;

      texcoord.y = (-pos.y)*0.5 + 0.5;

 

      texcoord+=HalfPixel;

}

 

 

void ps_shadowmap(           float2 texcoord         :TEXCOORD0,

                             out   float4 oColor           :COLOR)

{

      const int ITER = 256;

      float3 texadd = Invlightdir;

      float basehi = tex2D(Shimap,texcoord).r;

      float3 tc = float3(texcoord.x,basehi,texcoord.y);

 

      float finalcolor = 1;

      for(int i=0;i<ITER;i++)

      {

            tc+=texadd;

            float h = tex2D(Shimap,tc.xz).r;

            if(h>tc.y) finalcolor -= 0.01; // soft shadow lesz

      }

      oColor = finalcolor;

      oColor.a = 1; // csak hogy lássuk

}

A vertex shader nem nagy vaszidszdasz, egy target méretű négyzetet rajzolunk, aminek a koordinátái már -1 +1 közé esnek, csak a textúra koordinátákat kell ebből kiszámolni – át is lehetne adni a VS-nek, de mindegy.

A lényeg a pixelshaderben van (ps_shadowmap). A texadd az a növekmény, amit minden iterációban hozzáadunk a pixelpozícióhoz (tc). Kicsit bonyinak tűnhet, de nem az. A tc.xz a textúrakoordináta, a tc.y pedig a magassága a pixelnek a hieghtmap textúra alapján. Így a texadd.xz a texcoord növekmény, a texadd.y pedig a sugár emelkedésének növekménye pixelenként. Igazából itt van a cica elásva. Ez az Invlightdir –ból jön, amit be kell állítani a hieghtmapnek megfelelően. Az x és z komponens az egy pixelre jutó textúrakoordináta növekmény, mondjuk 512x512 heightmap textúra esetén 1.f / 512. Az y pedig az egy pixelre jutó sugáremelkedés. Ezt úgy kapjuk meg, hogy a heigthmap maximum magasságával osztjuk a normált raydir y komponensét. Inkább beszéljen a kód:

 

VECTOR smallm = Lightdir; // normalized!

smallm.y /= heightmapysize;

float pixelnum = float(HieghtMap.GetTexSizeX());// heightmap textúra mérete (x==y nálam)

smallm.x /= pixelnum;   // osszuk le pixelméretre

smallm.z /= pixelnum;

 

S ezt a ’smallm’-et lehet beállítani az effect ’ float3 Invlightdir’ paraméterébe. S kész is. A kérdés csak az, megérte-e a hardvert használni? A szoftveres 10 percig fut – ez 2 EZREDMÁSODPERCIG! Szóval sokkal gyorsabb, és sokkal gyorsabban meg is lehet írni.

Pár apróság, hogy ne menjen el másnak erre egy este:
- Képernyőnél nagyobb rendertarget-et csak megfelelő méretű z bufferrel lehet használni dx9 alatt, ehhez a SetDepthStencilSurface() a kulcs.

 

- rendertarget formátuma: a hieghtmaphez én a kedvenc D3DFMT_R32F-t használom, ez pontos és talán elég elterjedt. A shadowmap-hez próbáltam egy 8 bites formátumot, a D3DFMT_L8-at, amit a kártyám támogat is a dxcapsviewer szerint, de érdekes módon x irányban széthúzta a kb 4 szeresére a textúrát, 32bit helyett 8 bitbe próbáltam renderelni, talán azért, de ez nem indok arra, hogy ne működjön. Mindegy, inkább D3DFMT_A8R8G8B8 lett, ami 4-szer annyit foglal, de úgyse kell sokáig, csak amíg kimentjük fileba. 

Végül egy kép, hogy mégis, a kék a magasságtérkép, a fehér a shadowmap.

esetleg egy részletesebb, 64 iterációval és nagyobb fényerőcsökkentéssel:
 

 

Szólj hozzá!

_fpeti_ 2012.01.30. 00:52

Installer nyűgök: InnoSetup és DXSETUP nagy harca

Gondoltam nyitok a világ felé, és csinálok egy menő installer-es demót, mit csak le kell tölteni elindítani, várni míg végez, és élvezni a végtelen szórakozást. Manapság mindenki kényelemhez szokott, ha nem megy minden flottul, akkor legörbül a száj, és rajongókat veszít az ember. Ezért fontos a könnyed installáció – mondja a reklám.

Innnosetup-ot nagyon könnyű használni, szkript alapon működik, alap projektet is létre lehet hozni, be kell írni a könyvár nevét, ahol van a kész játék amit majd kitömörít a user célgépén abba a mappába (Program Files-ban valahol ált.), amibe kell. Kb. ennyi a minimum. Ez egy sor. Ez tartott órákig nekem? – nem. Hanem az, hogy a DirectX-es Visual C++ al készült cumóknak kell egy VC redist (vcredist_x86.exe) és egy DirectX-es install is. A vcredist_x86.exe-vel nincs gond, fenn van a neten, hogy kell paraméterezni, hogy silent módban – usert nem idegesítve – szépen fölinstallálja magát (nem Önt! :D). A DX-es rész kicsit bonyolultabb, ott minimum 5 file kell ahhoz, hogy egyáltalán elinduljon az install – miért is ne- plusz még a csomagok is, ezeket a dxsdk/redist mappájában találhatjuk meg. Nálam ez 11 file. Ezt szimplán úgy oldottam meg, hogy a kiadandó programban létrehoztam egy redist mappát, abba ment minden file, és miután ezeket az installer kibontotta a célgép mappájába, elindítottam a {app}/redist/ vcredist_x86.exe és a {app}\redist\DXSETUP.exe-t. Itt baj lett a dxsetup-nál, mivel azt írta ki, hogy nem találja a framedyn.dll-t. Kemény gugli-fu után olyan történt, ami még velem soha: kiderült, hogy ez nem az én hibám –ami rémisztően hatott. Kiderült, hogy a hivatalos MS álláspont szerint ez ’elszaródott Windows XP’ oprendszereken fordulhat elő, ahol megsérült, vagy törlődött ez a dll. Erre mit is mondhatnék. Meg lehet oldani, környezeti Path változóhoz a system32/wbem-et is hozzávenni, vagy csak szimplán bemásolni a dll-t a system32-be. Aztán én erre kérjek meg mindenkit, akinek előfordul?
Szerencsére kiderült, hogy e nélkül is lefut az install, valamint Vista és Win7 rendszereken nem fordul elő. Így talán nem érint majd túl sok embert, engem annyiban, hogy órákig kerestem a hibát a szkriptemben.

Az idő második része egy egyszemélyes dll-hárború vívásával telt el. Szerencsére valaki a konyhaasztalon hagyta éjszakára a mit sem sejtő win7-tel felvértezett ártatlan notebook-ját, így azon tudtam tesztelni, hogy ’meddig fagysz még’. Először hiányolt egy X3DAudio1_7.dll-t, amit nagy nehezen megtaláltam egy 2010 februári cab-ben.. Azzal azt  csinálta a progim, hogy elindult, fekete képernyő, utána kilépett. Megnéztem a log.txt-jét, kiderült, hogy elindult szépen csak az xaudio device nem jött létre, valamint egyetlen dx-es effect-file se tudott lefordítani. De nem írta ki, hogy hiányozna valami. Azért csak kerestem egy friss D3DCompiler_43_x86.cab-ot meg Xaudio, és XACT-ot is, ha már ott vagyok, sokat nem foglalnak az installerben. Ezekkel már ment szépen a cucc. Nagyjából 30-40 fps-en egy kétmagos asus gépen integrált intel cukiságos vga-val – 800x600-ban. Többre számítottam, ennyi a régi gépen is (gefGS7300)-on. Érdekes módon sokkal simábban ment a 2 magos gépen, úgy látszik van különbség ugyanolyan fps mellett itt. A lényeg, hogy megy.

Ide is másolom a InnoScript azon részeit, ami vonatkozik:

[Files]
Source: "C:\3d\release\*"; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs


[Run]
Filename: {app}\redist\vcredist_x86.exe;Parameters: "/q:a /c:""VCREDI~3.EXE /q:a /c:""""msiexec /i vcredist.msi /qn"""" """; WorkingDir: {tmp}; StatusMsg: Installing CRT...
Filename: {app}\redist\DXSETUP.exe; Flags: waituntilterminated;StatusMsg: Installing DirectX dlls...
 

Címkék:innosetup dxsetup Szólj hozzá!

_fpeti_ 2012.01.08. 02:07

Triplanar texturing és nagyobb decalek

Triplanar texturing: Textúrakoordináta számolása a csúcspont (vertex vektor) alapján, és több textúra 'összeblendelése' normál iránya szerint (normal.xyz adhat 3 faktort). Ez van a nagy kövön. :)
Meg nagy koromnyomok is. Gondolkoztam, milyen egyszerű lenne deferred shaderrel projektálni a textúrát a sziklára, de inkább belevágom a decal aabb-jébe a mesh összes háromszögét, és textúrakoordinátákat számolok nekik. Nagyon gyorsan nő a háromszögszám, hipoly-mesheken nem kifizetődő a dolog. Mesh vágáskor nagyon sok redundáns vektor keletkezik (minden elvágott élen lesz egy pár.) Ezeket ki lehet keresni, de félek elég soká tartana párszáz vektoron végigmenni párszázszor, hogy megtaláljuk az ismétlődőket. Mondjuk a nem számolt (meshből kapott) csúcspontokat könnyű összehasonlítani, bitre egyeznek (én float xyz helyett (int*)-ra kényszerítem és úgy hasonlítom.. elég vicces, de gyorsabb 2 integer közötti egyenlőség, mint a fabs(x0-x1)<delta cuccos.) Ha túl sok vektor/háromszög keletkezne, egyszerűen nem hozok létre új decalt. Nem annyira fontos, hogy mindenen legyen. Egyelőre ráadásul csak sztatikus objektumokon lehet ilyen, nincs per-frame decal transzformáció. Lehet így is marad. Mondjuk jó lenne ragdoll-okra is nagyobb decal-eket applikálni, ha nagyot sérül. Ekkor már csontozni is kéne a decalt, amihez nem lesz kedvem előreláthatólag soha. :3

bigdecals_triplanartex.PNG

Címkék:decal Szólj hozzá!

_fpeti_ 2011.12.08. 23:19

Level of detail avagy LOD

Régi trükk: ha valami messze van, ne rajzoljuk ki a nagy felbontású modelt, hanem használjunk kevesebb háromszöget, messziről úgyse látszik. Nem bonyolult, nálam annyiban merült ki, hogy Blender-ből több modelt is lehet egy .m fájlba exportálni, az első model a hi-poly-mesh, animációkkal, textúrákkal.  A második megy egy low-poly változat, ami csak vertex-colort használ. Vannak játékok, amik sok LOD szinttel dolgoznak, (nem vagyok biztos benne, de mintha a Serious Sam 30+ LOD-ot használt volna  - az első játék, nem a legújabb). Manapság nagyon oda kell figyelni arra is, hogy hányszor rajzolunk egy frame-ben, ha minden modelnek lenne 30 verziója, az nagyon belassulna (dx9 alatt 300-500 drawcall kéne - pesze ez nem ökölszabály, de a dx9 virágzásakor ezt beszélték ;) )
Mivel a második LOD-os modelben nagyon kevés háromszög van, (<100) ezért semmiképpen nem érdemes külön-külön rajzolni őket. Én két módszert is választottam:
1. A nagyon kevés háromszögeket használó objektumokat szoftveresen forgatom térbe, és egy drawcall-al kimegy a cucc.
2. Ha nagyobb a poligonszám, akkor jöhet az a hardware-instancing, amivel csomó ugyanolyan objektumot lehet egyszerre képernyőre küldeni.

Végül, ha nagyon-nagyon távol van az az ojjekt, akkor kár fecsérelni modelrajzolásra az időt, és elég egy kis képként kirajzolni - ezt billboarding-nak is hívják.

Itt egy kép az első próbálkozásról, a három lod szint van: hipoli,lowpoli,billboard. Jól elkülönülnek, ami nem jó, de ennyire futotta a programmer art-ból mára.

Szólj hozzá!

_fpeti_ 2011.11.21. 01:51

Játékötlet (nem nagyon eredeti, de Minecraft ><; )

Mostanában nagyon gondolkodom egy MC klón félén, örömprogramozás céljából. Sokkal több kockával, (min 8x) nagyon szimpla egy szín (+tulajdonság) per kocka adat szerkezettel - lehetne 1 byte per 'voxel'. Alapból 256*256*256 kockákból állna a scene egy darabja, ez 16MB adat lenne egyszerre. (MC-ben 16*16*128-as oszlop.) Ha a cache-miss nem szól nagyon bele. Ebből lenne persze egyszerre több is benn a memóriában. A láthatóság nagyon egyszerű módon működne, ami az eredeti Minecraft-ben is nagyon szimpla - egyszerűen minden kockát kirajzol, aminek van olyan oldala, ami mellett levegő van. Ez zseniálisan egyszerű húzás, és nem is annyira pazarló, mint előre gondolná az ember. Én megfejelném egyfajta raytrace-szel, csak nem minden képpontnak lenne egy sugár, minek egy ilyen szabályos kockákból álló világban, hanem voxelről-voxelre ugrálna a ray, pont mint a 2d-s szakaszrajzoló algókban. Ez nem lenne teljesen pontos, az is fontos, hol helyezkedik el a kamera egy voxelen belül, ami hibákat eredményez(het). Erre még visszatérek, ha egyszer eljutnák oda. Itt akár még előjöhetne egy dinamikus, nap irányából jövő árnyékolás is, nem mindig fölülről jönne a fény, mint MC-ben.
De lehetne valamiféle durva z-buffer jellegű dologgal is próbálkozni, szigorúan fixpontos alapon.
Végső soron maradna a per pixel ray, de azt kétlem, hogy valós időben képes lenne sok mindenre. De majd kipróbálom.

Persze ott vannak a gpu-s módszerek is, pl ez a 256*256*256 beleférne egy 3 dimenziós textúrába is, és lehetne szórakozni Cuda/DirectCompute dolgokkal is, ezzel még pláne nem foglalkoztam, érdemes kipróbálni akinek van dx10 karija minimum.


Fák jól néznének ki átlátszó zöld lombbal - jó lenne valamilyen módon egyesíteni az átlátszó kockáit egy lombnak egy egységes geometriává, és úgy rajzolni, MC-ben elég darabosan néznek ki pl a jégkockák egymás mögött. Összefüggő erdőlombozatnál ez elég durva számolás lenne mondjuk.

Arra is gondoltam, hogy miért is rajzoljak sima kockákat, ha közel vannak a kamerához, lehetne használni egy kis extra geometriát, hogy ne legyenek annyira élesek a szélek. Nagyon egyszerűen meg lehetne nézni, hogy egy kockának melyik oldalain van szomszédja és aszerint rajzolni egy nagyobb felbontású kis 'mesh-escskét', hogy jobban passzoljon mondjuk egy leejtő oldalába. Tulajdonképpen a látható éleket kellene kicsit lekerekíteni, pl ha egy szomszédja sincs, akkor egy ortopéd gömböt rajzolnék ki. Elég sok kombó van, hisz 26 kocka szomszédja lehet, forgatásokkal lehetne csökkenteni a mesh-ek számát, ami szvsz nem annyira menő (még forgatni is kelljen?). Vagy a fontos szomszédok számát is lehetne csökkenteni, mondjuk csak az oldalaihoz érőket figyelembe venni - így csak 6 elemből kell kikombinálni. Nyilván ezt ki lehet számolni előre, és csak akkor kell módosítani, ha változik körülötte valami.
Ez az egyik iszonyatos előnye a kockavilágnak, hogy ahhoz képest, hogy teljesen dinamikusan lehet változtatni mindenen, nagyon sok mindent előre is ki lehet számolni, majd ha változik valami - ami általában kockák elhelyezése vagy eltűnése a világban - akkor kell újraszámolni a változástól függő dolgokat. Ilyen szintű rugalmasságot nem lehet elérni semmilyen más módszerrel.

Apropó kockák lerakása, a játékmenetet  - már ha lesz valaha, amit kétlek így az első kódsor megléte előtt - én nem annyira a kreatív vonalon mozognék, egyébként is kis kockákkal bíbelődni milyen már, inkább felfedezős-akciós-lyukrobbantós mezsgyén képzelem a dolgot (mint mindig). XD

Ez persze nem jelenti azt, hogy nem lehet találni semmit, pl. szép átlátszó drágaköveket (azérse gyémántot :) )  amiért itt-ott lehetne táposabb cuccokat venni, vagy csak megdobálni vele az ellent.. semmi 'crafting', meg bonyolítás, az ilyesmi gyönyörűen meg van írva az MC-ben, minek másolni. Tul. a kockákból felépített álló világon kívül nem sok mindenben kéne, hogy hasonlítson MC-re, de mindenkinek ugyanaz a játék fog eszébe jutni róla.

btw ellenfelek: mi lenne, ha azok is kis kockákból állnának és 'behatás' esetén törölgetnénk őket, ezzel elég látványos - és mély - nyomokat lehetne hagyni mindenkiben.

Címkék:Minecraft 2 komment

_fpeti_ 2011.10.08. 00:34

Egy régi-új npc

Első npc-met 3d-ben 'sonofapeach'-nek azaz 'barackfia'-nak neveztem el :). Elég hülyén nézett ki. Most 'elővettem a képességeimet', és Blenderben egy gömbből és egy pöfeteg gombáról készült fényképem segedelmével megalkottam a kettes verziót. Döntse el mindenki, mire hasonlít Elég gusztustalan, de szörnyes fps-ben talán nem olyan nagy gond az.

Amúgy a doom beli cacodemon ihlette, csak nem olyan lett.
(Csak tudnám hogy kell szebben beilleszteni képet)
ps: Ez még mindig placeholder, nem kell megijedni.


 

 

 

 

Címkék:sonofapeach Szólj hozzá!

_fpeti_ 2011.09.22. 02:04

Képek

Blogolás gyakorlása céljából :)
Íme egy lyuk amiből felfelé fény jön (magmalight a neve).

 

Emissive texture:

 

 Water refraction: Avatott szeműek észrevehetik, hogy nem csak a víz alatti részeket torzítja, de nem sok kedvem van csak emiatt mégy egyszer renderelni. Nekem tetszik (ami nem sok jót szokott jelenteni.)

 

Szólj hozzá!

_fpeti_ 2011.07.30. 03:01

Ázekh!

DrawPrimitive()-el nem működik a HW instancing dx9-el! Majd 2 órám ment el mire kiderült, DrawIndexedPrimitive()-el egyből megy!

Jó tudni (nem annyira, de jó :) )

Címkék:drawprimitive Szólj hozzá!

_fpeti_ 2011.03.16. 23:07

Grafikai ráncfelvarrás (nomnoming yo' framerate)

’Deferred is preferred’ tartja a népi bölcsesség.
Ez egy speckó renderelési módszer, a fényeket és árnyékokat utólag adja a látható képhez. Sok problémát meg lehet vele oldani, de sokkal lassabb, főleg egy régebbi dx9-es videókártyán. A régi módszer (forward rendering) 60-100 fps körül ment, ez az új 30 alá is mehet, attól függően, mennyi nagy fényforrás látható éppen. Mondjuk a 7300gs (64 bit) karim nem a legújabb, igazából a geforce 7-es szériájának teteje és azon felülire módosulhat ezzel a becélzott végfelhasználói csoport. Megtartottam a régi, egyszerűesített rajzolást is, csak ott egy fény van csak egyelőre, a nap, azon még dolgozni kéne, hogy így nézzen ki, de az a jövő zenéje. Annyit gyorsítottam a dolgon, hogy a napot egyből a g-buffer generáláskor kiszámolom egy negyedik bufferbe - első a szín, második a normálisok és csillivill-faktor, harmadik a z buffer. Ezzel spórolok egy full-screen-es directional-light rajzolást, ami talán megéri. Fényeket is hozzá lehet kötni tárgyakhoz, így jöhettek létre a himbálózó fények, amik nagyon fontosak, mert anélkül semmik vagyunk. (mondom én, aki 2 órát Minecraft-ol napi szinten :D)

Amúgy van diffúz point és spotlight, valamint textúrás-projekciós spotlight is, mert nem lehet játék rácsos textúrás HIMBÁLÓZÓ spotlight-ok nélkül. A vicces az, hogy a valóságban egy berácsozott lámpa fényében sosem lehet látni a rácsozatot, de ez nem valóság.
Csináltam vizet is, ritka hitvány egy valami lett, el is döntöttem, hogy lehet nem is foto realisztikus megjelenítés lesz. Mondjuk még egy fénytörés/visszaverődés félét csinálok rá (stalker doksi alapján: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html)

Csak még megjegyzem, hogy már a hang része is nagyjából készen van a játéknak, a szokásos wav fileok a 3d-s hangoknak, és .ogg a streamelt muzsikának. Én annyival még megfejeltem a dolgot, hogy a vorbisdll nem a hdd-ről nyomja a zenét, hanem betöltöttem az egész ogg filet ram-ba (3 megát kibírunk), és onnan megy. Hosszabb dialógusokat is lehetne .ogg-ban tárolni, csak nem nagyon akarok dialógusokat, hanem önfeledt szórakozást inkább, a többieknek meg ott a Kossuth Rádió. J

Apropó dialógusok, a ’szkriptrendszert’ is elkezdtem. A törzse már megvan, a legegyszerűbb módot választottam, amit windows-on lehet: minden pályának van egy dll-je, amiben van egy csomó függvény, amit az engine hívogathat, ha valami speciális történik. Pl a pályaszerkesztőben el lehet helyezni 3d-s dobozokat, aminek lehet egy neve. Ha a játékos belép ebbe a dobozba, a pályához betöltött dll-ből meghívja az azonos nevű függvényt. Az a függvény meg tehet, amit akar, leginkább döntéshozó- játéklogikai kódokat tartalmaz. A dll induláskor kap egy nagy struktúrát, amiben az összes olyan függvény pointere megvan, amin keresztül az engine-t elérheti. Első függvény volt, hogy lejátszhat egy hangot, ha a játékos bemegy a dobozba. Miért nem használok lua/python/as cumókat? Nem a sebesség miatt, hanem mert nincs rá szükség. Nincsenek illúzióim a játékkal kapcsolatban, nem lesz külön ember a szkriptelésre, én fogom azt is csinálni.

Itt a szokásos zagyva videó (hangja nincs.)

 

 

 

Címkék:grafika deferred Szólj hozzá!

_fpeti_ 2011.01.27. 01:34

Kelj fel!

 

Ez szerintem vicces. :p

 

Szólj hozzá!

_fpeti_ 2011.01.25. 01:35

Szörnyek alaplángon

Igen, már amennyire egy zöld kocka félelmetes lehet. :) npc-kel foglalkozom manapság, nagyon új, és közepesen érdekes téma. A zöld valamik helyére egy lebegő rémet kellene képzelni, ami szabálytalan lufiszerű mozgással ide-oda libbenve lövöldöz, most még egyelőre egy szimpla részecskét. Elég sokat szívtam a kvaterniós orientációval, nehéz volt pl. megcsinálni, hogy ne fejjel lefele legyen állandóan, hanem forduljon a hasára,ha csak tud. Eddig az van, hogy alapból nézelődik, ha észreveszi az alap-ellenséget (meg lehet adni a látószöget neki), akkor irányba fordul és elkezdi eregetni a golyóit, XD és közeledni. Ha elég közel van, körözni kezd az ellenfele körül, és próbál vízszintes irányba kerülni a célpontjához képest.
Npc-knél az első dolog, ami nálam kötelező, hogy ne csak a játékost támadják, hanem egymást is. Ilyet a doom2-ben láttam először, azóta nagyon tetszik. Egyszerű megoldani, és látványos tömegjeleneteket lehet ezzel elérni. Itt is úgy van, hogy egy npc eltalál egy másikat, akkor az automatikusan visszatámad. Ez addig folyik, míg egyik el nem patkol – pontosabban még tovább is, addig, amíg a halott npc ragdoll-ja is be nem szerez annyi sérülést, hogy lefut a desintegrate() függvénye, ami kitörli a játékból (ide kell majd egy gib-rendszer). Ekkor a győztes npc visszaáll alaphelyzetbe, azaz újra a játékosnak esik. Szerintem nagyon mókás összeveszejteni egy csomó szörnyet, hadd csépeljék agyon egymást.
 

 Elkezdtem a golyónyom megjelenítőn is ügyködni, még elég hiányos. Kétféle van:
egyszerű testekre csak szimpla textúrázott négyszögeket rajzol, mozgó test esetén mozgatja a testtel együtt.
A második decal-féle pedig terrain-ra van, amik robbanásból kifolyólag kerülhetnek a talajra, általában egy kráter aljára.
Mindkettőnél a haladás egyik gátja az, hogy vágni kellene a decaleket, ne lógjanak le a testről. Például ha egy doboz legszélét találjuk el, akkor a golyónyom 4zetből le kell vágni a kiálló részt. Ez nagyon változatos poligonokat eredményezhet, ráadásul, ha a decal alatti terület nem sík, minden egyes 3szögre rá kellene vetíteni a megfelelő részt. Igazából elég sok módját el tudnám képzelni a decal-ek képzésének és rajzolásának, pl vágások helyett deferred shadinggel el lehetne játszani, hogy a fényekhez hasonlóan screen-space-ben a z bufferrel oldanánk meg az egészet. (ha az nem gond, hogy egy dobozról lelógó részlet láthatóvá válik, ha közel kerül egy másik tárgyhoz – jah, ’decal bleeding’)
A terrainra egy trükköt találtam ki, hogy ne kelljen mindig vagdosni:
csak egy méretű decal lehet, az pedig csak a terrainháló csúcspontjaira, vagy éleire eshet. Így 9 esettel meg lehet oldani az összes kombinációt. Ha nem pont csúcsra vagy élre esik a  középpontja, kicsit odébb kell húzni, és már jó is. ;)

 A harmadik jóság, hogy nekiálltam az aljnövényzetnek, mert az is kell (ahhoz volt kedvem – indie dev for de win!!) Úgy csináltam meg, hogy minden talaj textúrához tartozhat egyféle fű textúra, mivel 4 textúra lehet egy talajon, így 4 fűféle kell, amit egy textúrába tettem, így az összes füvet ki lehet rajzolni egyszerre. A fű mesh modelje két négyzet merőlegesen, és ezt rajzolom ki hw instancing-gal. Nem túl nagy területet füvesítek be egyszerre, de így is 400-600 füvet kell alapból kirajzolni, ami nekem soknak tűnik, főleg ahhoz képest, ahogy kinéz. Mondjuk olyan sok fps-t nem vesz le. Még csak félig van kész, a távoli fűvek eltűnését alpha-dissolve módszerrel fogom finomítani, a frustum culling se tökély. Amúgy a generálása per terrain-háromszög történik, és raktározza addig, amíg az a 3szög látszik, vagy elég távolra nem kerül. Fontos, hogyha megváltozik a terrain (pl bombázás – esetleg creepers, Minecraft rulez amúgy ,) ), akkor a rajta lévő füvek pozíciója is idomuljon, ne lebegjenek a föld fölött.

 

Szólj hozzá!

_fpeti_ 2010.11.05. 05:12

Dekorációk a játékban.

Mostanában egy lenge növényzettel és egyéb fizikával nem rendelkező objektumokkal foglalkoztam. A Havok alapjáraton 16K rigidbody-t enged egyszerre a szimulációba, ami a 16 biten tárolt értékek miatt van. Át lehet kapcsolni 32 bitre is, ami már 4giga objektum, de semmi értelme ennyivel kezdeni, és felére lassul az axissweep-teszt dupla memóriaigénye miatt. Egyébként sem ildomos minden fűt-bokrot fizikailag leképezni, csak akadályozna a mozgásban. Ez a (CDecor) osztály tehát nem tud mást, mint tartalmaz egy mesh-t, amit kirajzolhatunk, más játékra gyakorolt hatása nincsen. Fura is volt ezt csinálni, mert az elmúlt kb 1 évben csak a legfontosabb elemekkel, a játékmotor nyers mechanikájának összebarkácsolásával foglalkoztam (egy lépés előre, kettő oldalra formában). Mondjuk a framerate-re igen szép hatással tud lenni – hw instancing már nem késhet soká.
A jópofa ezekben a nagyrészt statikus dekorációkban az, hogy bevezettem egy ’parenting’  (szülő-gyerek) rendszert a játékbeli objektumok között, amivel össze lehet őket kapcsolni, amennyit a ’szülő’ elmozdul, annyit mozog a ’gyerek’ is. Ez egyébként is bevett dolog játékmotorokban. A videó elején látható, hogy a pálmát megütve a rácsatlakozott ’fagyöngyök’ együtt mozognak a levéllel, vagy az ellőtt fa kidőlő részével együtt mozog a lombja. A csatlakozásokat a pályaszerkesztőben kell kijelölni, majd töltéskor a játék megkeresi (összetett fizikai objektumok estén) a legközelebbi rigidbody-t (itt a pálma-model esetén a megfelelő levelet). Eltárolja a relatív transzformációt, majd bejegyzi a szülőnek, hogy van gyereke. Ezután ha a szülő elmozdul, értesíti a gyereket, aki frissíti a mátrixát. A kapcsolati rendszer fix tömbökkel történik, minden objektumnak max 8 gyereke lehet (egyéb ízületekkel együtt). Ha a szülő törhető, mint az kettérobbantott/lőtt fák, akkor törésnél meg kell keresni azt a darabot, amelyikhez a legközelebb van, és arra újra rá kell csatlakoztatni. Vagy törölni, ha nem maradt semmi. (esetleg széjjelfagy – ez is opció volt egy darabig ;))

 

Címkék:dekoráció Szólj hozzá!

_fpeti_ 2010.10.15. 05:55

Kevés haladás, kis videó.

Hát igen, a Fraps 30 másodprecet enged 'ingyér' egyszerre. A lényeg, hogy nagyjából látszik, hogy működőképes az animáció, és a halálozás utáni ragoll is működik.

Próbáltam több fegyót is használni, az nagy fehér cső egy rakétavető, csak nem volt a tárban egy raksi sem, elfelejtettem felvenni lőszert hozzá. :) De volt pisztoly, egy vérbénán kinéző puskaféle, valamint személyes kedvencem, a kézigránát, amit az utolsó utáni másodpercben vetettem be.

 

Szólj hozzá!