perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 2. listopad 2013, 17:51:12 Předmět: OpenGL ES - instancing |
|
|
Mám problém Programuju na mobil a potřebuju podporu instancingu, která ale v GLES 2.0 nějak není.
Co jsem udělal je, že jsem udělal dva VB a v jednom sedí geometrie a v druhém transformační matice. So far, so good. A teď problém.
Pokud potřebuju instancing aktivovat nad libovolným modelem, jsem v háji. Na "velkém" OpenGL akorát vytvořím druhý buffer pro matice, ale jinak kreslím pořád z původního modelu (1 VB a IB), což teď nejde. Takže jsem došel k jedinému řešení, zkopírovat VB a IB do nového a zvětšit ho
Příklad
kód: |
Původní model
VB: ABC
IB: 012
Instancovaný model
VB: ABC|ABC|ABC|...
IB_ins: 012|345|678|..
VB_ins2: W1|W2|W3|....
|
Jenomže další problém, jak vytahat data z VB / IB... nebo jak to celé udělat jinak, pokud někdo ví.. Je to víceméně postup před tím, než bylo OpenGL 3 a jejich drawinstanced _________________ Perry.cz |
|
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 3. listopad 2013, 20:30:03 Předmět: |
|
|
Tak pro budoucí generace (třeba se to někomu bude hodit).. už jsem to obešel pomocí EXTension "glMapBufferRange", které by mělo na iPhonu v GLES2 existovat. Postnutý kód je napsaný v GLES3, ale nahrazení funkce tou EXT by mělo fungovat
Kód je těžká prasečina, ale pro moje potřeby to stačí. Proměnné jsou definovány na různých místech ale pro pochopení co a jak to taky stačí.
kód: |
GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, this->mainObject->vertexBuffer[0]->buffer ) );
float * unitdata = NULL;
uint32 vbOrigSize = this->mainObject->vertexBuffer[0]->info.numVertices * this->mainObject->vertexBuffer[0]->info.vertexSize;
GL_CHECK( unitdata = static_cast<float *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, vbOrigSize, GL_MAP_READ_BIT)) );
vbOrigSize /= sizeof(float);
float * instBuffer = new float[vbOrigSize * this->instanceCount];
int index = 0;
for (int i = 0; i < this->instanceCount; i++)
{
for (int j = 0; j < vbOrigSize; j++)
{
instBuffer[index++] = unitdata[j];
}
}
this->mainObjectVBCopy = new GLESVertexBuffer(this->device);
this->mainObjectVBCopy->InitBuffer(instBuffer, vbOrigSize * this->instanceCount, sizeof(float), false);
SAFE_DELETE_ARRAY(instBuffer);
GL_CHECK( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, this->mainObject->indexBuffer[0] ) );
void * ibdata = NULL;
uint32 ibOrigSize = this->mainObject->numIndices[0] * this->mainObject->indexSize[0];
GL_CHECK( ibdata = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, ibOrigSize, GL_MAP_READ_BIT) );
ibOrigSize /= this->mainObject->indexSize[0];
uint32 * ibBuffer = new uint32[ibOrigSize * this->instanceCount]; //tady teoreticky pozor, GLES2 nemusí umět intový IB - pro malé objeky a malý počet instancí změnit na uint16
index = 0;
for (int i = 0; i < this->instanceCount; i++)
{
for (int j = 0; j < ibOrigSize; j++)
{
if (this->mainObject->indexSize[0] == sizeof(uint16))
{
ibBuffer[index] = ((uint16 *)ibdata)[j];
ibBuffer[index] += i * this->mainObject->vertexBuffer[0]->info.numVertices;
index++;
}
}
}
GL_CHECK( glGenBuffers(1, &this->mainObjectIBCopy) );
GL_CHECK( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->mainObjectIBCopy) );
if (dynamic)
{
GL_CHECK( glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibOrigSize * this->instanceCount * sizeof(uint32), ibBuffer, GL_DYNAMIC_DRAW) );
}
else
{
GL_CHECK( glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibOrigSize * this->instanceCount * sizeof(uint32), ibBuffer, GL_STATIC_DRAW) );
}
GL_CHECK( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
SAFE_DELETE_ARRAY(ibBuffer);
|
_________________ Perry.cz |
|