|
|
A uniform változók értékét mindig be kell állítani, ha közben más shaderprogramot használtam, vagy az marad, ha egyszer már beállítottam?
A uniform location lekérése mennyire költséges? Érdemes egyszer lekérni, és megjegyezni, vagy mehet minden hívásnál?
|
|
|
Mármint az ibo bindelés hiánya volt a hiba? Ha igen, az úgy elég kemény, mert általában furábban szokott ilyenkor kinézni a modell.
|
|
|
Ez olyan facepalm-OS, nem?
alias aalberik
|
|
|
Egyébként illene. Olyannyira, hogy az volt a hiba
Azért nézegettem egy darabig az assimp-os részeket, meg az assimp flag-ekkel is játszadoztam, nem gondoltam volna, hogy itt lesz a gond.
Amúgy ott volt az, csak véletlenül kommentbe került egy jelenleg még használaton kívüli kódrészlettel együtt.
|
|
|
Egyébként rajzoláskor nem kell az indexbuffert is bindolni? Mármint ez nem lehet a probléma, mert akkor más sem lenne igazán jó, csak kérdezem.
|
|
|
Gondolom az IBO mindenhol rendesen be van kötve csak lemaradt az idézetből 
Még meg lehetne nézni a Blender oldali mesh statisztikát és azt amit renderelsz.
Háromszög-szám ill. vertex-szám.
Gyanús, h assimp csinál vmit furcsán. Esetleg csinál vertex cache optim.-t?
Esetleg csontanimálva van a modell?
alias aalberik
|
|
|
Külön.
Kód: class ShadedMesh
{
private:
std::vector<Mesh> mMeshes;
...
class Mesh
{
private:
GLuint mVB;
GLuint mIB;
unsigned int mNumIndices;
...
|
|
|
Egy közös VBO + IBO-ba töltöd fel a mesheket vagy minden meshnek külön VBO + IBO-ja van?
alias aalberik
|
|
|
Biztos, hogy nincs túlcsordulás. Több mesh-ből áll a modell, és 5000 körüli a legnagyobb indexszám is.
Bufferek létrehozása egy mesh-re:
Kód: void Mesh::init(const std::vector<Vertex>& vertices,
const std::vector<unsigned int>& indices)
{
mNumIndices = indices.size();
glGenBuffers(1, &mVB);
glBindBuffer(GL_ARRAY_BUFFER, mVB);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)* vertices.size(),
&vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &mIB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIB);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)* mNumIndices,
&indices[0], GL_STATIC_DRAW);
}
Vertex és index listák kiszedése az importerből:
Kód: ShadedMesh::ShadedMesh(std::string name, const aiScene* scene)
{
mName = name;
mMeshes.resize(scene->mNumMeshes);
for (unsigned int i = 0; i < mMeshes.size(); i++)
{
const aiMesh* mesh = scene->mMeshes[i];
std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
const aiVector3D* pPos = &(mesh->mVertices[i]);
const aiVector3D* pNormal = &(mesh->mNormals[i]);
Vertex v(Math::float3(pPos->x, pPos->y, pPos->z),
Math::float3(pNormal->x, pNormal->y, pNormal->z));
vertices.push_back(v);
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
const aiFace& Face = mesh->mFaces[i];
assert(Face.mNumIndices == 3);
indices.push_back(Face.mIndices[0]);
indices.push_back(Face.mIndices[1]);
indices.push_back(Face.mIndices[2]);
}
mMeshes[i].init(vertices, indices);
} //meshes iteration
} //Model construktor
Egy mesh kirajzolása:
Kód: glBindBuffer(GL_ARRAY_BUFFER, mVB);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (const GLvoid*)sizeof(Math::float3));
glDrawElements(GL_TRIANGLES, mNumIndices, GL_UNSIGNED_INT, 0);
|
|
|
Bár elég valószínűtlen, de nem lehetséges, hogy több, mint 2^16 = 65536 vertex van, amit meg kell indexelni? Mert ha igen, és netán GL_UNSIGNED_SHORT (vagy nem is tudom hirtelen fejből a nevét) típusú indexeket használsz, akkor az a baj.  Ha viszont nem így van, akkor lehet, hogy az importer a rossz. Esetleg a draw-nál nem jó elemszám van megadva, ezért csak egy részét rajzolja ki. Esetleg egy VBO feltöltés + rajzolás (+ esetleg importálás) kódot, ha feltöltesz, lehet, hogy elbújt ott valami huncutság...
szerk.:
Áh, látom, syam megelőzött...
|
|
|
Vertex indexelési problémának tűnik.
Importkor lehet, hogy uint16-ban indexel viszont túl sok hozzá a vertex.
alias aalberik
|
|
|
Blenderben így néz ki egy modell, amit megpróbálok beimportálni Assimp segítségével.
Ez az eredmény.
Másik modellt probléma nélkül betölt. Bármi ötlet, hogy hol lehet a gond?
|
|
|
Nahát, erre még igazából nem is gondoltam, pedig nem rossz ötlet.  Eddig csak specifikus shadereket írtam meg, legfeljebb a statikus / animált vertex shaderek voltak egyben és define-okkal megoldva.
Ezt a dolgot akár úgy is meg lehet oldani, hogy van egy übershaderje az embernek, tele ifdefekkel, így a bejövő paraméterek függvényében készül el runtime a shaderkód, amit aztán lefordít.
|
|
|
Mindenképp kell vmiféle shader-rendszer.
Legjobb ha "surface shadert" készítesz, ami úgy is tudsz paraméterezni, hogy "érdes, kék, fém".
De ha simán modulárisan, pipeline-szerűen építed fel az is nyerő nagyon.
alias aalberik
|
|
|
Hát ez pedig ilyen. Nem egy nagy effort. Először nekem is kicsit fura volt, dx-ben anno teljesen manuálisan csináltam. Beállítottam a vertex shadert meg a pixel shadert külön-külön, így nem volt mindig muszáj váltani. Viszont hidd el, ha van egy jó kis rendszer rá, akkor sokkal követhetőbb így a dolog. Ráadásul nem olyan nagy effort shadert váltani.
Nálam pl. így néz ki egy shaderes rajzolás:
Kód: shader->begin();
shader->setXY(locXY, value);
draw();
shader->end();
Sokkal zavaróbb tud lenni, hogy egyáltalán semmi helper funkció nincs a shaderekhez. Azaz a define-olást és include-olást is kézzel kell megírnod. Persze nem egy nagy dolog, string-beszúrás az egész, de akkor is...
|
|
|
Hát igen. Mondjuk amíg nem kell a scale, addig nem lehet probléma.
Ha eljutok odáig, lemérem a teljesítménykülönbséget, és lehet kiszedem én is
Ha más nem, ha vminek kell scale, akkor külön írok rá shader-t
Mondjuk már most is bosszant, hogy a shadereket egybe kell fordítani.
Amit tervezek, annál pl. az van, hogy sok vertexshaderhez két különböző pixelshader is tartozni fog. Mindegyik külön program
|
|
|

Az a lényeg, hogy megvan.  Egyébként lehet, hogy ezzel jól meg fogom szívni egyszer, mert én a mai napig a "sima" world mátrixot használom. Nem igazán tartom szerencsésnek mindig kiszámolni az összes inverzét, az animált modellekről nem is beszélve... Minden egyes animált modell minden egyes csontjához tartozó mátrix inverzét számolgatni / frame...
|
|
|
Kösz a segítséget!
Ilyenkor érzem nagy szerencsétlennek magam
Totál más volt a hiba: a hátsólapeldobásból elsőlapeldobás lett.
|
|
|
Én is "directx-es" mátrixokat használok opengl renderelővel, ahogy tapasztaltad is annyi a megoldás, hogy matrix * vertpos (hlsl-ben pedig mul(vertpos, matrix)) lesz a sorrend.
Normáloknál pedig a world inverse transpose-al kell szorozni. Viszont, ha jól rémlik, a transzponáltról annyit kell tudni, hogy:
A * v = v * AT
(ahol AT az A mátrix transzponáltja).
A sorrendet ennek figyelembe vételével határozd meg. Azaz ha csak sima inverzed van, akkor cseréld meg a szorzás sorrendjét, hogy jó legyen.  Egyébként meg gyorsan ki tudod deríteni, ha a fragment shaderben kiíratod a normalt, mint színt.
Egyébként első körben megpróbálhatod a (world * normal)-t, és azzal számolni. Csak bizonyos transzformációknál okozhat ez a számítás hibát (tipikusan a nem egységes skálázáskor). Ha azzal sem jó a megvilágítás, akkor máshol van a gond.
Konkrét kód esetén többet lehet mondani.
|
|
|
Adottak voltak egy kicsi és jó matek és kamera "könyvtár" forrásfájljai egy directx-es projectből, király makrókkal, meg minden segédfüggvénnyel, ami a 3d-s grafhoz csak kellhet.
Aztán miután megdöbbenve tapasztaltam, hogy bizonyos irányú mozgatás helyett forog a kép, és nagyon furán nyúlik a betöltött modell... mint kiderült, arra nem gondoltam, hogy az opengl és a directx különböző koordinátarendszerei ennyire bekavarnak.
Végül segítséggel azt a megoldást választottam, hogy a shaderben a vertex poziciójának számításakor felcseréltem a sorrendet:
pos = vektor * transmatrix helyett pos = transmatrix * vektor formába.
Ez megoldotta a gondot.
A normálvektorokat is úgy próbáltam meghatározni: amikor az inverzmátrix-al szorzom őket, ott felcseréltem az inverzmátrixot és a normálvektort. Viszont a színekből ítélve a normálok nem úgy vannak, ahogy lenniük kéne. Okozhatja ez a hibát, vagy máshol keressem?
Biztos ki tudnám matekozni igazából, csak sajnálom rá az időt 
Ha valaki vágja a témát, és tud válaszolni a kérdésre, azt megköszönném!
|
|
|
Idézet Eldor :
A glValidateProgram(..) nem a shader helyességét ellenőrzi, hanem azt, hogy helyesen vannak-e beállítva az állapotok (pl.: uniformok, attribútomok) az adott környezetben.
Jogos  Kicsit fáradt voltam már, bekavartam a dolgot
|
|
|
Idézet MaNiAc :
Idézet Eldor :
Szia!
A glValidateProgram(..) függvénnyel is megnézted? Nálam már volt rá példa, hogy fordult és minden jónak tűnt, mégis a validate hibát jelzett.
Azt írta, hogy az alap triangle-re működött a shader, szóval a shaderes rész kizárható. Szerintem a VAO-val/VBO-val lesz a bibi...
A glValidateProgram(..) nem a shader helyességét ellenőrzi, hanem azt, hogy helyesen vannak-e beállítva az állapotok (pl.: uniformok, attribútomok) az adott környezetben.
|
|
|
Műkszik mostmár királyul.
GlBindAttribLocation mindjárt pótlásra kerül.
Úgyis most szórakozok kicsit a shaderekkel: uniform változók, mvp mátrix, vmi alap árnyalás, miegymás.
|
|
|
Az attrib location kezelés hiánya elég veszélyes.
Ati driverek szokták azt csinálni, hogy nem a generikus sorrendben várják az attribokat így pl. a pozíciót nem a 0. csatornán várja, hanem mondjuk a normál csatornáján. Ilyenkor lesz minden meshből gömb és az embernek pedig wtf érzése
alias aalberik
|
|
|
Idézet Elodin :
GlBindAttribLocation nincs, de ez a háromszögnél sem okozott problémát...
Erre nem érdemes hagyatkozni  Legyen.
Egyébként most akkor jó, vagy nem? Kicsit nehezen követem.  Ha nem jó, esetleg a cull mode NONE-on? Lehet, hogy a háromszöget kézzel CW-ben adtad meg, de a modell CCW-ben van.
|
|
|
Enable volt, csak kimaradt egy köztes függvény, bocs.
Kód: void Model::render()
{
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
for (unsigned int i = 0; i < mMeshes.size(); i++)
{
mMeshes[i].render();
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
Szerk.:
glVertexAttribPointer() átírását vhogy nem sikerült mentenem, vagy nem tudom 
Azóta egykét dolgot még kijavítottam, és nézem, hogy ez megint rossz. Ismét kijavítottam, és ezúttal megy a dolog.
Kösz a segítséget, a progit meg különösen... szerintem nagy hasznomra lesz még.
GlBindAttribLocation nincs, de ez a háromszögnél sem okozott problémát...
Ezt a hozzászólást Elodin módosította (2014.03.25 22:25 GMT+1 óra, ---)
|
|
|
glEnableVertexAttribArray merre van?
Shader-kezeléskor van glbindattriblocation?
alias aalberik
|
|
|
Kösz!
Első körben én is a VBO-ra gyanakodtam, aztán ellenőriztem az általad ajánlott programmal.
Szerinte rendbe vannak: az index és a vertex buffer is pont úgy néz ki, mint kéne neki.
A kirajzolás kódja így néz ki jelenleg:
Kód: glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GraphEn::graphEn.getTechnique("basic")->enable();
Model* m = GraphEn::graphEn.getModelByName("giraffe");
if (m) m->render();
glutSwapBuffers();
A meghívott render függvény:
Kód:
glBindBuffer(GL_ARRAY_BUFFER, mVB);
glVertexAttribPointer(0, sizeof(Math::float3), GL_FLOAT, GL_FALSE,
sizeof(Vertex), 0);
glVertexAttribPointer(1, sizeof(Math::float2), GL_FLOAT, GL_FALSE,
sizeof(Vertex), (const GLvoid*)sizeof(Math::float3));
glVertexAttribPointer(2, sizeof(Math::float3), GL_FLOAT, GL_FALSE,
sizeof(Vertex),
(const GLvoid*) (sizeof(Math::float3) + sizeof(Math::float2)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIB);
glDrawElements(GL_TRIANGLES, mNumIndices, GL_UNSIGNED_INT, 0);
Sehol nincs error, minden fv meghívódik, aminek meg kell. A kép a clearert szín.
|
|
|
Idézet Eldor :
Szia!
A glValidateProgram(..) függvénnyel is megnézted? Nálam már volt rá példa, hogy fordult és minden jónak tűnt, mégis a validate hibát jelzett.
Azt írta, hogy az alap triangle-re működött a shader, szóval a shaderes rész kizárható. Szerintem a VAO-val/VBO-val lesz a bibi...
|
|
|
Szia!
A glValidateProgram(..) függvénnyel is megnézted? Nálam már volt rá példa, hogy fordult és minden jónak tűnt, mégis a validate hibát jelzett.
|
|
|
gDebugger nevű progi nekem bejött, ha ilyesmire gondoltál.
Esetleg ha gondolod, dobd be ide a VAO tartalmát megjelenítő kódot, aztán ránézünk.
|
|
|
Van vmi trükk/tool opengl debuggolásra?
Egyszerűen annyit csinálok, hogy betöltök egy modellt, annak a koordinátái a (-1,1) intervallumba esnek, és megpróbálom kirajzolni minden extra nélkül. Saját shadert használok, ami jelenleg nem csinál semmit gyakorlatilag (bemenetet továbbadja a vertex shader, a pixel shader meg konstans színt ad, háromszögre működött is). Amennyire c++ oldalról látom, minden rendben van... viszont nem rajzolódik semmi.
Szerk.: közben sikerült kicsit javítanom a dolgon. glGetError() segítségével rájöttem, hogy rosszul paramétereztem a glVertexAttribPointer() fv-t. Ezt ki is javítottam, most már nem is kapok errort... de ugyanúgy nem rajzol semmit ; (
Ezt a hozzászólást Elodin módosította (2014.03.25 19:40 GMT+1 óra, ---)
|
|
|
a webgl úgyis randomra elszáll alóluk pár frame után, mert a webfejlesztők szerencsére ezt sem bírták rendesen megoldani.
|
|
|
Idézet versio :
en csak azert emlitettem meg, mert en is agyfaszt kaptam a forditasi idoktol windows metrora programozva, soha nem ternek vissza se windowsra se c++-ra, nem ment el az eszem 
Ha nálad az a fejlesztés, hogy átírsz valamit, aztán lefordítod, a fordító kidobja a módosításból adódó esetleges hibákat és így tovább, akkor nem a C++ a hibás. Egyébként meg az /MP kapcsoló csodákra képes.
A másik, hogy manapság zömében annyira egyszerű játékok vannak és a fejlesztői eszközök, annyira modernek, hogy nincs is értelme egy nagy és bonyolult engine és a hozzá tartozó infrastruktúra használatát hónapokig tanulni. Egyszerűbb pár nap/hét alatt öszerkani a játékot OpenGL-el és a megfelelő platform specifikus részeket a platformokhoz tartozó SDK-val. Erre már rájöttek az engine fejlesztő cégek is és már szinte ingyen csinálhat az engine-el bárki bármit, ha ágyúval akar hangyára lőni.
Az a kevés cég, aki AAA-ra játszik pedig van annyira pro, hogy nem más kreálmányával heggeszt contenteket, hanem szintén megírja a motort magának.
Utolsó kapaszkodójuk az engine gyárosoknak a webfejlesztők, hátha bekajálják a motorjukat és a C++ ból generált js-el majd összegányolnak valamit, amire maguktól nem képesek.
|
|
|
Idézet versio :
en csak azert emlitettem meg, mert en is agyfaszt kaptam a forditasi idoktol windows metrora programozva, soha nem ternek vissza se windowsra se c++-ra, nem ment el az eszem 
Ez mindössze azért ciki, mert egy tetves szó sem volt a fordítási időkről...
Btw aki OpenGL-t akar programozni, az nyílván azért teszi, mert nem egy meglévő enginehez akar contentet csinálni, hanem mert OpenGL-t akar programozni.
|
|
|
en csak azert emlitettem meg, mert en is agyfaszt kaptam a forditasi idoktol windows metrora programozva, soha nem ternek vissza se windowsra se c++-ra, nem ment el az eszem
|
|
|
El se kezdjétek ezt a baromságot - ez nem a Unity topic!
|
|
|
|
bolyzsolt: a megoldas az unity
|
|
|
Arra esetleg megpróbálhatsz egy köztes dolgot: lehet, hogy az a kód, amit használsz egy csomó minden checket csinál, ha bizonyos dolgok definiálva vannak (amik debug esetén). Csinálsz egy custom targetet, aminek lecopyzod a release beállításait, csak kikapcsolod a kódoptiamlizálást,, debug infókat bekapcsolsz, stb.
Én arra gyanakszok, hogy debug módban a memóriát is nagyon figyeli (kiindexelés tömbből, ilyesmik), és az foghatja meg. Na de oda TODO-ztam, hogy release-re majd uncomment.
|
|
|
Idézet Pretender :
szerk. 2:
Aha, újabb tapasztalatok azt mutatják, hogy csak vs-ből indítva debuggerrel csinálja. Ha az elkészült exe-t indítom, akkor nincs akadás. Érdekes.
VS tud csinálni érdekes dolgokat... Én most egy meglévő (nem általam írt) kódalapra fejlesztek játékot, ami debug módban 2-3 FPS-t tud, releaseben 55-60-at. Azaz release módban tudok csak rendesen tesztelni, viszont ekkor a végső linkelés több, mint egy percig tart. :sóhaj
|
|
|
VBO update:
Több helyen is azt olvastam, hogy jó, ha a glBufferSubData előtt hívunk egy glBufferData-t null pointerrel, és ezzel xy dolgot jelzünk a drivernek. Így is tettem, és csak pislogtam, hogy mi a fene van, mert periodikusan néhány mp-enként megakadt az egész kb. fél mp-re. Ha kiszedem a glBufferData-s dolgot, akkor meg jól működik. Ez mennyire általános? Teljesen driver-függő legalább?
Így jó:
Kód: glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * vertexSize, _vertices);
Így nem:
Kód: glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, numVertices * vertexSize, 0, usageTypes[dynamic]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * vertexSize, _vertices);
Annyi megjegyzéssel, hogy a numVertices * vertexSize állandó, a buffer létrehozásakor számolom csak ki, azaz mindig a teljes buffer tartalmát lecserélem.
szerk.:
Ja igen, ATI/AMD kártyám és driverem van, lehet az a baj
szerk. 2:
Aha, újabb tapasztalatok azt mutatják, hogy csak vs-ből indítva debuggerrel csinálja. Ha az elkészült exe-t indítom, akkor nincs akadás. Érdekes.
Ezt a hozzászólást Pretender módosította (2014.03.20 19:56 GMT+1 óra, ---)
|
|
|
|
Idézet __z :
Idézet syam :
Viszont ha kliens memóriából töltöd fel az adatot minden frameben, akkor tud számítani a felesleges méret.
Jah, hát ezért kérdeztem. 
Viszont egyrészt a glDrawArrays-nál gondolom nem véletlenül kell megadni tartományt, másrészt a futás közbeni sebesség bőven jó (30+ FPS egy Alcatel 990-en).
Hogy mikor és mit művel a vertex arrayjal az a driver dolga. A "tartomány" csak annyit mond, h hány mettől meddig akarsz renderelni vagyis azokat fogja feldolgozni - hogy mennyi megy fel a gpunak az már driver kérdés.
Egyébként a drawarrayst nem szeretik, mert nem használod a vertex cachet. Ahol lehet indexelt geometriát használj. Ilyen esetben már extension optimalizálásra: glDrawRangeElements, aminek meg lehet mondani, hogy mekkora vertex mennyiséget fogsz felhasználni az arrayból.
De még egyszer: ha megfelelő / interaktív sebességű a framerate, akkor totál mindegy mit csinálsz, ha minden készüléken megy és ugyanúgy is néz ki
alias aalberik
|
|
|
Idézet syam :
Viszont ha kliens memóriából töltöd fel az adatot minden frameben, akkor tud számítani a felesleges méret.
Jah, hát ezért kérdeztem. 
Viszont egyrészt a glDrawArrays-nál gondolom nem véletlenül kell megadni tartományt, másrészt a futás közbeni sebesség bőven jó (30+ FPS egy Alcatel 990-en).
|
|
|
|
Idézet syam :
Én itt nem látok vbot csak vertex arrayt.
A lényeg, hogy működik...
|
|
|
Idézet __z :
Itt a konkrét kód (Android/Java):
Kód: FloatBuffer vertices = ByteBuffer.allocateDirect(49152).order(ByteOrder.nativeOrder()).asFloatBuffer(),
texCoords = ByteBuffer.allocateDirect(49152).order(ByteOrder.nativeOrder()).asFloatBuffer();
float[] array = new float[12];
int[] transform = new int[2];
float width, height;
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices.clear());
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords.clear());
void drawArrays(GL10 gl) {
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.position() / 2);
texCoords.clear();
vertices.clear();
}
void draw(float x, float y, int textureX, int textureY, int textureWidth, int textureHeight) {
if (vertices.remaining() == 0) drawArrays(gl);
array[10] = array[2] = array[0] = x;
array[9] = array[5] = array[1] = y;
array[8] = array[6] = array[4] = x + Math.abs(transform[0]) * textureWidth;
array[11] = array[7] = array[3] = y + Math.abs(transform[1]) * textureHeight;
vertices.put(array);
array[10] = array[2] = array[0] = (transform[0] > 0 ? textureX : textureX + textureWidth) / width;
array[9] = array[5] = array[1] = (transform[1] > 0 ? textureY : textureY + textureHeight) / height;
array[8] = array[6] = array[4] = (transform[0] < 0 ? textureX : textureX + textureWidth) / width;
array[11] = array[7] = array[3] = (transform[1] < 0 ? textureY : textureY + textureHeight) / height;
texCoords.put(array);
}
// a transform tömböt tükrözéshez és nagyításhoz használom
Én itt nem látok vbot csak vertex arrayt.
alias aalberik
|
|
|
Idézet syam :
VBO frissítése nem ajánlott dolog. Ha mégis muszáj, mert pl. uniformként nem kezelhető az adat, akkor buffersubdata esetleg dupla bufferelve. A mappelés annyira nem válik be.
Hát pedig ez a dynamic batchelés lényege. Minden frameben frissíteni. Csak az a kérdés, hogy milyen módszerrel invalidáljuk a régi adatot. A duble bufferinget is el lehet érni többféleképpen. Egyébként miért nem szereted a mapbuffer-t?
|
|
|
Itt a konkrét kód (Android/Java):
Kód: FloatBuffer vertices = ByteBuffer.allocateDirect(49152).order(ByteOrder.nativeOrder()).asFloatBuffer(),
texCoords = ByteBuffer.allocateDirect(49152).order(ByteOrder.nativeOrder()).asFloatBuffer();
float[] array = new float[12];
int[] transform = new int[2];
float width, height;
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices.clear());
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords.clear());
void drawArrays(GL10 gl) {
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.position() / 2);
texCoords.clear();
vertices.clear();
}
void draw(float x, float y, int textureX, int textureY, int textureWidth, int textureHeight) {
if (vertices.remaining() == 0) drawArrays(gl);
array[10] = array[2] = array[0] = x;
array[9] = array[5] = array[1] = y;
array[8] = array[6] = array[4] = x + Math.abs(transform[0]) * textureWidth;
array[11] = array[7] = array[3] = y + Math.abs(transform[1]) * textureHeight;
vertices.put(array);
array[10] = array[2] = array[0] = (transform[0] > 0 ? textureX : textureX + textureWidth) / width;
array[9] = array[5] = array[1] = (transform[1] > 0 ? textureY : textureY + textureHeight) / height;
array[8] = array[6] = array[4] = (transform[0] < 0 ? textureX : textureX + textureWidth) / width;
array[11] = array[7] = array[3] = (transform[1] < 0 ? textureY : textureY + textureHeight) / height;
texCoords.put(array);
}
// a transform tömböt tükrözéshez és nagyításhoz használom
|
|
|
Legújabb project:
Smashed Potatoes
Legutóbb frissített project:
Smashed Potatoes
Friss kép a galériából:
|