|
|
|
Az UTF-8-ról tudom, hogy változó szélességű, de pl. az UTF-16 már fix. Nemrég pedig ezt olvastam, ahol beszél erről egy picit.
Igazából eleve használhatnék 2 byte-os "karaktereket", igazából egy minimális memóriapazarlás csak a hátránya. No meg ugye a blogon emlegetett byte ordering is, de ha saját magamnak kezelem, akkor úgysincs belőle gond.
Egyébként itt van a videó az általad linkelt pdf-hez.
szerk.:
Most olvasom csak, hogy az UTF-16 is változó hosszúságú. Még jó, hogy az egyetemen hülyeséget tanítanak.
Ezt a hozzászólást Instalok módosította (2016.03.12 21:16 GMT+1 óra, 769 nap)
|
|
|
Ezt olvasd el mindenképp. Pl mert az UTF eleve nem fix szélességu, amit sokan nem tudnak.
Egyébként meg a font renderelés más téma, ott be szokták gyujteni a lokalizációs fájlokból a szimbólumokat és valamilyen formában kirenderelni egy textúrába.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
|
|
|
UTF8
win-en ebből MultiByteToWideChar() és ki tudod rajzolni.
|
|
|
Csináltam egy alap localization systemet, ami egyelőre semmi extra, csak egy kulcs alapján megkapok egy stringet, amelyet a jelenleg betöltött localization file határoz meg.
A problémám csak annyi, hogy ez jól működik minden olyan nyelvre, amelynek a karakterkészlete belefér 1 byte-ba, mert a betöltött szövegeket std::string-ként tárolom, amely viszont nem lesz jó például a japán nyelvre (kivéve a romanji, katakana, hiragana írásokat), hiszen a kanji sok ezer szimbólumból áll.
A gond például ott kezdődik, hogy kell egy másik karakterábrázolás (2 byte már úgy gondolom elég lenne, 2^16=65536 különböző karakter), valamilyen Unicode dologgal. Érdemes csinálni egy saját "stringet", amely ezeket is tudja tárolni? Ott van a varchar, de arról azt olvastam, h compiler függő, hogy végül mekkora lesz a mérete.
Továbbá felmerül a gond az ingame text rendereléssel, ahol szintén valahogy társítani kell az adott textúrakoordinátákhoz a megfelelő szimbólumokat, de ez már másik topic lesz.
|
|
|
Sziasztok!
World of Warcraft: Warlords of Draenor szerverhez csinálásához keresek embereket. Jelenleg 5en vagyunk(a wow részlegen), a munkálatokat már elkezdtük, átlag életkor 21+ A csapat teljesen komolyan gondolja amit csinál, amúgy egy "Multigaming" vagyunk, és jó pár játékhoz csinálunk szervereket (Minecraft, GTA5, WoW, ArmA 3 stb...) Saját szervergépekkel, és hozzáértő emberekkel. akit érdekel a dolog az keressen bátran, Aki úgy gondolja hogy van elég ideje és sokat tud foglalkozni a dologgal, annak egy csekély havi szintü fizetést fel tudok ajánlani, nem valami nagy összeg(20-35k ft) de a semminél jobb. Természetesen a szerver beindulása után részesedést jár a bevételből
Amilyen tudású emberekre szükség van:
C++
C#
Visual Studio ismerete
MySQL és Scriptelés
TrinityCore ismerete nem hátrány, de nem is kötelező
Ha érdekel keress meg privát üzenetbe, Skypeon (raptor212) emailen:xsm023@gmail.com vagy TS3 szerverünkön: aviorgaming.com (Brendon néven találtok meg)
Ezt a hozzászólást Sliden módosította (2016.03.03 15:41 GMT+1 óra, 778 nap)
|
|
|
Igen, tudom, hogy mi a diamond megoldása, viszont inkább annak az elkerülése érdekelt.
Nem igazán értem viszont a feltevésedet. Viszont (ha jól értem), nem szeretem a túlzottan vegyes osztályokat, inkább maradjon csak meg külön-külön. Ha nincs külön vertex- és index buffer, akkor nagyon jó, mert ugyan azt az osztályt lehet példányosítani, és kész. Ráadásul ez az egész így csak annyit mond meg, hogy van egy olyan osztály, ami úgy viselkedik, mint egy vertex buffer. Hogy ez konkrétan hogy van implementálva, az aztán tökre nem érdekes a magas szinten. Ennyi nekem elég is.
|
|
|
Megint rossz megközelítés. Ne absztrahálj low level dolgokat, mert újabb apikban nincs is vertexbuffer (csak buffer). De említhetném a GL 4-es shader storage buffert is. Vastag réteget csinálj és azt specializáld (GLMesh, DXMesh, stb.).
diamond problemre meg olvasd el az öröklődésről szóló cikkemet (virtuális öröklés a megoldás).
|
|
|
Milyen patternnel lehetne szépen megoldani az alábbit?
Van egy BufferObject osztály, ami a vertex- és index bufferek közös tulajdonságait, műveleteit tartalmazza. Ebből öröklődik maga a VertexBuffer és IndexBuffer osztály, ami kiegészíti a saját funkcionalitásával.
Ebből a kettőből öröklődik az API-specifikus osztály (pl. OGLVertexBuffer). itt jön a problémám: az OpenGL szintjén a két osztály kb. csak egy enumban tér el, azaz jó lenne, ha közös ősük lenne. Ekkor viszont el is jutottam a "diamond inheritance" problémáig.
Egyetlen megoldásként egyelőre azt találtam ki, hogy van egy OGLBufferObject osztály is, ami az OpenGL szinten közös dolgokat tartalmazza, továbbá ugyan úgy megvan az OGLVertexBuffer és OGLIndexBuffer osztály is, ami implementálja a pure virtual függvényt, ami csak meghívja a megfelelő enummal az OGLBufferObject egy függvényét. Na szóval valami ilyesmi (természetesen ez csak vázlat, de a lényeg benne van)
Kód: class BufferObject
{
// .... közös dolgok
// implementálandó függvény
virtual void Upload(offset, size) = 0;
};
class VertexBuffer : public BufferObject
{
// ... kiegészítések
};
class IndexBuffer : public BufferObject
{
// ... kiegészítések
};
class OGLBufferObject
{
public:
uint32 GetId() const
{
return id;
}
protected:
void OGLUpload(target, maxsize, offset, size, data)
{
if (!id)
{
// ... create buffer (<-- target)
}
else
{
// ... bind buffer (<-- target)
}
// ... fill data (<-- target)
}
private:
uint32 id;
};
class OGLVertexBuffer : public VertexBuffer, public OGLBufferObject
{
void Upload(offset, size) override
{
OGLUpload(GL_ARRAY_BUFFER, GetMaxSize(), offset, size, GetData());
}
};
class OGLIndexBuffer : public VertexBuffer, public OGLBufferObject
{
void Upload(offset, size) override
{
OGLUpload(GL_ELEMENT_ARRAY_BUFFER, GetMaxSize(), offset, size, GetData());
}
};
Van-e esetleg erre valami okosabb megoldás, vagy "jóezígy"?
szerk.:
Ja igen, a Vertex- és IndexBuffer osztályoknak a BufferObject osztályból kell öröklődniük, mert használják annak bizonyos függvényét/függvényeit.
|
|
|
Szóval, ha az ember dynamic libet akar használni, akkor implementáljon saját containereket? Esetleg változott ez a dll-export dolog a 11-es szabvánnyal?
|
|
|
Nem viszem túlzásba, nagyon sok csúnya dolgot láttam abban a kódban. Például nagyon sok globális változójuk van, nem használt, csúnyán rendszerezett kód, hatalmas (néha több ezer soros) függvények, stb. Viszont miután megfejtek egy adott részt, vannak benne jó ötletek, azokat adaptálom, és a saját számíze szerint megvalósítom, ha megtetszett.
|
|
|
Azért ne vidd túlzásba ezt az UE4 majmolást...a globális változók nem thread safe-ek, később nagy szopás lehet belőle.
|
|
|
Na megint jövök a furcsaságaimmal.  Böngészve az UE4 forráskódját, megtetszett ez a moduláris felépítés, viszont van néhány dolog, amit statikusan szeretnék linkelni. És hogy LoadModule() esetén ne keresse a dll-t, így valahogy be kell a managernek regisztrálni, hogy ez a modul bizony egy statikusan linkelt modul.
Erre volt benne egy jó ötlet, készítettek a regisztráló osztályt, ami a konstruktorában meghívja a manager megfelelő függvényét. Röviden valami ilyesmi:
Kód: template <class M>
class Register
{
Register() { Manager::Get().RegisterStatic(&Register<M>::InitializeModule);
M* InitializeModule() { return new M(); }
};
Az adott modul implementációjakor pedig egy makró segítségével készítenek ebből egy static objektumot, ami elvileg beregisztrálná. Ez ugye az adott modul egy cpp file-jába kerül.
Kód: static Register<MyModule> registerForMyModule;
Na most a problémám itt következik. Lebuildeltem static libként, hozzálinkeltem a másikhoz, viszont ez a változó nem inicializálódik.
Gondolom valahol (valószínűleg linkeléskor) eldobta, mert nem hivatkozik rá senki. Az UE4 kódjában (Runtime/Core/Public/Modules/ModuleManager.h) van is a makróban egy erre hivatkozó rész:
Kód: // [...]
/** Implement an empty function so that if this module is built as a statically linked lib, */ \
/** static initialization for this lib can be forced by referencing this symbol */ \
void EmptyLinkFunctionForStaticInitialization##ModuleName(){} \
// [...]
Viszont azt nem találom meg, hogy erre ki hivatkozik.
Különösebb build-toolok és automatikus kódgenerálás kifejlesztése nélkül van-e lehetőség valahogy inicializálni azt a változót?
szerk.:
Ok, mágikus módon megjavult, egyetlen linker beállítással a futtatható programon:
Kód: Use Library Dependency Inputs -> true
Viszont észnél kell lenni, meg kell majd nézni (egyszer), hogy g++al milyen eredmény születik.
szerk. 2:
Ja értem! Azért javult meg, mert ezzel az opcióval nem magát a libet, hanem az objecteket linkeli a programhoz?
szerk. 3:
Igen, megtaláltam, itt egy bejegyzés erről.
Ezt a hozzászólást Instalok módosította (2015.12.16 20:24 GMT+1 óra, 856 nap)
|
|
|
Lentebbi példához kapcsolódóan:
Véleményem szerint ennek mennie kellene:
Kód: static_assert(std::is_function<decltype(T::GetType)>::value, "Not a COMPONENT_GROUP");
Viszont abban az esetben is írja a hibaüzenetet, ha a T-nek van GetType függvénye. Azonban, ha kicsit megcsavarom a dolgot, és a címével próbálkozok, akkor megjavul:
Kód: static_assert(std::is_function<typename std::remove_pointer<decltype(&T::GetType)>::type>::value, "Not a COMPONENT_GROUP");
Ezt a hozzászólást Instalok módosította (2015.11.25 12:13 GMT+1 óra, 877 nap)
|
|
|
Viszont az rtti-t perf miatt kikapcsolni oltari hulyeseg. A 90-es evekbol visszamaradt rossz szokas. nem ezen fog mulni a 60 fps, leszamitva azt az esetet, ha mocsokszar compilert hasznalsz.
|
|
|
Egyébként egy ilyen értéket jelenleg is használok megkülönböztetésre, de eddig eszembe nem jutott volna az, hogy virtuális függvényt használjak.
Jelenleg egyébként egy elég hacky megoldást használok. Van egy define-om, ami definiál egy egyszerű static függvényt, ami visszatér egy 32 bites integerrel, magával a függvény címével.
Kód: #define COMPONENT_GROUP()\
public:\
inline static Component::Type GetType() { return reinterpret_cast<Component::Type>(&GetType); }
Ahol a Component::Type egy uint32 define (hogy később akár uint64-re is lecserélhető legyen).
Illetve magát a component hozzáadását egy template függvénnyel csinálom, így könnyen el is tudom tárolni az adott példányhoz tartozó típust is, innentől kezdve pedig működhet a virtual függvényes dolog.
Az enummal meg valóban csak annyi a baj, hogy előre tudni kell, hogy milyen gyerekek lesznek pontosan.
Köszi a hozzászólásokat.
|
|
|
Ez lehet hogy egyszerűbb, de nem jól alkalmazható több lépcsős öröklés esetén, illetve a parentnek előre kell tudnia minden gyerekosztályról. Az én változatomban elvileg bármikor utólag is bővíthető, anélkül, hogy hozzá kellene nyúlni a meglévőkhöz.
Persze, ha csak az egyszerűség számít, akkor az enum is elég, ráadásul nincs benne virtuális függvény, ami spórolhat egy vtable-t.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
|
|
|
Egyszerűbb ha:
Kód: class ParentClass
{
public:
enum Types { ChildType1, ChildType2 };
inline Types GetType () const { return mytype; }
protected:
ParentClass (Types type) { mytype = type; }
private:
Types mytype;
};
Az idtech4 ezt egyetlen makróval oldja meg ami minden osztály elején ott van (és nincs beleégetve az enum).
|
|
|
Szerintem is felesleges egyetlen egy típusvizsgálatért bekapcsolni az egész RTTI-t. A legtöbb esetben úgyis kb arra leszel kíváncsi, hogy egy Parent pointer az A vagy a B gyerekre mutat e. Mivel közös az ős, egy virtuális függvényhívással meg tudod oldani. Kicsit macera (bár csinálhatsz rá egy makrót), de elég gyors és biztonságos. Ennél több elég ritkán kell.
Kód: class Parent {
static const UID TypeID = 1;
virtual bool IsType(UID type) const { return TypeID == id; }
}
class ChildA : public Parent {
static const UID TypeID = 2;
virtual bool IsType(UID type) const override
{ return TypeID == id || Parent::IsType(type); }
}
class ChildB : public Parent {
static const UID TypeID = 3;
virtual bool IsType(UID type) const override
{ return TypeID == id || Parent::IsType(type); }
}
....
Parent* valami = ...;
if (valami->IsType(ChildA::TypeID))
{
...
}
Értelemszerűen az UID típust értelmezheted aminek csak szeretnéd, akár stringnek is, bár az lassúcska. Mi például string hashekkel dolgozunk, ami kód írásakor offline számítható, és commenben odaírod, hogy mi az eredetije, vagy csinálsz egy konstanst valahol ugyanazzal a névvel, amiből a hash számolódott. Van ugyan egy kicsi esély az ütközésre, de az kb nulla.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
|
|
|
Jo, igaz (runtime-t akartam irni, csak hulye vagyok), a lenyeg, hogy nem tamogatott. Nem vagyok benne biztos, hogy a java miatt, de az android dokumentacio explicit emliti, hogy felejtsd el.
|
|
|
Ez nem a compiler hibája hanem a java-é...úgy tölti be a dll-eket, hogy nem publikálja az rtti-t, innen jön ez a hiba. A compilerrel semmi baj nincs.
|
|
|
az android nem tamogatott platform a c++ szamara szvsz. rendes szamitogepeken van rendes compiler.
|
|
|
Én "saját" rtti-t használok.
alias aalberik
|
|
|
Én kerülném a dynamic_cast-ot is, meg az rtti-t is. Androidon jött elő az a probléma, hogy dll-eken keresztül nem működik a dynamic_cast és ez kurvanagy szopás, mert most írthatom ki az engineből.
Javasonlám inkább az idtech4 megoldását.
|
|
|
Egyébként ismételten rákeresve az RTTI és dynamic_cast dolgokra, itt például azt írják, hogy nem annyira vészes. Mondjuk azzal meg egyetértek, hogy ha túl sok helyen kell dynamic_cast-ot használni, akkor az egy rosszul tervezett program.
|
|
|
Hiába az as, a feltétel scope-ján kívül kell egy változót deklarálni mindenképpen. Egyébként az OOP patternek zömének alapja a polimorfizmus, anélkül kár is C++ t használni, elég a C.
|
|
|
C#-ban is használhatod rögtön az "as"-t, null-t ad vissza, ha nem konvertálható. Hát, akkor lehet, hogy dynamic_cast lesz a vége.
|
|
|
Igazából, ha C#-ban az is-t használod, akkor utána az as-al kell konvertálni, vagyis az már helyből két dinamikus művelet, míg C++ nál már a feltételben is megkaphatod az eredményt egyből:
Kód: if (auto b = dynamic_cast<Behavior *>(c))
b->...
|
|
|
az rtti kikapcsolasa hulyeseg. a dynamic cast meg jo
|
|
|
A dynamic_cast mennyire ördögtől való? Általában a RTTI-t kikapcsolom (gondolom ez performance boost is), de dynamic_cast-hoz viszont (nyilvánvalóan) szükséges. Egyetlen helyen akarnám csak használni, de ott is csak arra, hogy megállapítsam, hogy egy adott objektum az egy adott osztály gyereke-e. Komponens-alapú dologhoz kellene.
Kód: class Component { };
class Behavior : public Component { };
class MyBehavior : public Behavior { };
void Add(Component* c)
{
// C#-ban ennyivel el lehet intézni, itt használnám a dynamic_cast-ot.
if (c is Behavior) { ... }
}
Add(new MyBehavior());
|
|
|
Használd a fantáziád:
Kód: template <bool value>
class where
{
private:
where ();
};
template <>
class where<true> {};
template <class T>
class MyClass : where<is_base_of<Base, T>::value>
{
};
|
|
|
Hát, ezzel nagyjából ott vagyok, ahol eddig, minden esetre tanulságos ez a megoldás, lehet, hogy eszembe sem jutott volna.  Pedig így megnézve logikus...
|
|
|
Ezt a hozzászólást Asylum módosította (2015.11.12 09:53 GMT+1 óra, 890 nap)
|
|
|
static_assert-en kívül van-e lehetőség template típusellenőrzésre? Azt szeretném megnézni, hogy az adott típus az gyereke-e egy másiknak. Természetesen csak és kizárólag compile-time. Hasonlóan, mint C#-ban a where feltétel generic esetén. Egyelőre csak ennyi van a függvény elején:
Kód: static_assert(std::is_base_of<ComponentBase, T>::value, "Not a component!");
Olvastam valamit a Concept-ről, de az VS 2013 alatt (még?) nem működik, és nem szeretnék váltani, főleg nem emiatt.
|
|
|
Oké, ez jogos.
|
|
|
Már hogy a fakkba ne lehetne
Kód: // alma.cpp
class Alma
{
public:
inline void Foo() {}
};
|
|
|
Oké, hogy az egy hint, viszont ha nem a headerben van, akkor NEM LEHET inline. Néztem jó pár cikket ezzel kapcsolatban, és megállapították, hogy egyszerű getter/setter függvények esetén NAGYON sokat dob az inline.
C++ban meg nincs olyan, hogy property - vagy értsem ezalatt a getter/setter függvényeket?
|
|
|
Idézet Instalok :
Ha nem a headerbe teszem a definíciót, akkor nem lehet inline. Szóval a kérdés még mindig áll. Inline esetén egyébként semmi nem kerül a dll-be, a fordító panaszkodik is, ha inline függvényt akarsz exportálni. Property?
Nincs olyan, hogy inline, ez csak egy kívánság, ami vagy teljesül, vagy nem. Cserébe viszont állandóan újra fog fordulni minden, amit érintenek ezek a fgv-ek. getter/setter = property.
Optimalizálni ott kell, ahol a program dolgozik, nem pedig mindent. Általában a program 10%-a fut az idő 90%-ban, itt kellene optimalizálni, nem feltétlen inline-ozással, ami mint írtam tetszőleges.
|
|
|
Ha nem a headerbe teszem a definíciót, akkor nem lehet inline.  Szóval a kérdés még mindig áll. Inline esetén egyébként semmi nem kerül a dll-be, a fordító panaszkodik is, ha inline függvényt akarsz exportálni. Property?
|
|
|
Ha a headerbe teszed a kidolgozást is, akkor mi fordul a dll-be? cpp-ke rakd szerintem a property-ket is.
|
|
|
Ha egy dll-ként használható modult csinál valaki, akkor tervezés szempontjából melyik a szebb?
- az egyszerű get/set függvények inline függvények, azaz a headerben vannak definiálva
- még az akár 1 soros gettereknek is csak a deklarációja van a headerben, a definíció mindig a cpp fileban található (természetesen ez alól kivételek a template függvények, amelyek kötelezően a headerben találhatóak)
|
|
|
Hello, Lead játékfejlesztőt keresek egy nemzetközileg elismert magyar játékfejlesztő céghez. Jó a fizu, jó a csapat. Szívességből írtam ide ki, hátha valakit érdekel. Ha igen, írj nekem az akos.szabadi@hotmail.com címre.
|
|
|
A program bonyolultságát nem az dönti el, hogy konzolos, vagy ablakos. Kompatibilitási okai vannak a konzolnak régi DOS-os programok miatt. Még ma is vannak olyan fejlesztői eszközök, amik DOS-os kimenetet állítanak elő a programnak pl.: Progress és a mai napig írnak ebben ügyviteli rendszereket kórházaknak stb. Játékfejlesztésnél igazából editornál használunk ablakos nyomógombos felületet, játéknál egy üres render ablak kell csak, amire OpenGL, vagy DirectX-el rajzolunk, a konzolos részt mondjuk logolásra lehet használni.
|
|
|
Hát igen, az Assembly már eléggé hardverközeli nyelv, s valóban, arra mindenesetre jó volt a róla szóló könyv bújása, hogy megtudjam, mik azok a regiszterek, mitől 8, 16, 32 ... bites egy program vagy operációs rendszer (ekkora regisztereket bír kezelni, ha jól értelmeztem).
De a C++-ra visszatérve: a konzolos részét használva is lehet legalább olyan jó progikat készíteni, mint az ablakossal? Egyáltalán: miért van elkülönítve a két rész? Elvileg azért pakolja alapból teli a szerkesztőablakot ablakkezelő kódokkal az induláskor, hogy könnyítse a programozó dolgát - engem inkább elriaszt.
Asylum, jók a cikkeid (ezek alapján is fogok majd nekiállni a tanulásnak) és aranyos a hörcsögöd is.
|
|
|
|
A C/C++ (mert azért ez eggyütt használandó sok esetben) elég mély téma, igazán jól művelni sok év kérdése. Assembly-vel C++ állásinterjún szoktak szivatni, igazából nem is maga a nyelv, hanem a hardver ismeret a lényeg, hol mennyi elemi utasítást lehet megspórolni, a memória melyik részére teszi az adatot éppen a program, vagy melyik memóriába, "itt mit csinálhat a compiler" és hasonló kérdésekre tudsz válaszolni és aszerint programozni, vagy mások elszúrt programjait helyrehozni.
|
|
|
Idézet Nomad :
én egy kis bengabali vok de én tavaly előtt tanultam meg a c++-t internetes tutorialokból szerintem nem volt nehéz megtanulni úgyhogy szerintem nyugodtan kezdhet azzal az ember csak egy kis idő kell mire az ember elkezdhet opengl meg ilyen komolyabb dolgokkal foglalkozni...
Irigyellek, jóeszű gyerek lehetsz. Én pár hónapja beszereztem egy rakás programozási szakkönyvet, de még mindig ott tartok, hogy sehol.  Igaz, nem is nagyon volt még időm gyakorolni, de talán most nyáron...
A C++-t hajtanám én is, mert úgy látom, ez a fórumtéma pörög itt a JF.hu-n, nem a sima C-s vagy C#-os, úgyhogy ebből azt szűrtem le, hogy ez a legalkalmasabb a játékfejlesztésre is.
Idézet
(az utóbbi 2 hónapban megtanultam az assembly-t)
Pedig az kemény dió lehet. És van egyáltalán valami létjogosultása az Assemblynek a mostani korszerű és korszerűsített programozási nyelvek között? Vagy azt is fejlesztették?
Annakidején megvettem Agárdy Gábor: Gyakorlati Assembly c. könyvének első kötetét; az eleje még érthető volt számomra kb. a szövegek kiíratásáig, de utána már mintha veszített volna a szájbarágósságából és nem sokat értettem belőle...
|
|
|
Mivel ugyan az Mint a terep2 Remake-ek mely, CTruck3D vagy is ennek a játéknak
Simon_hasur fejlesztett ládásul köze van a c/c++, openGL Grafikával.
https://youtu.be/B74QvPGyBYM
|
|
|
Bocsi, ezt benéztem. Nem fogtam fel, hogy eleve azt írta, hogy "beépített típusokat".
|
|
|
Erre gondoltam igen. Ha nem muszáj akkor ne adjunk puskát a programozó kezébe.
|
|
|
Legújabb project:
electronics
Legutóbb frissített project:
electronics
Friss kép a galériából:
|