2012-12-29 1 views
2

많은 입자에 대한 모든 정점 데이터를 단일 배열로 결합했습니다. 고유 한 번역을 유지하는 방식으로 모든 입자를 일괄 처리하는 방법은 무엇입니까?OpenGL ES 2.0 - 고유 한 변환, 회전, 비율 및 알파가있는 입자를 일괄 처리하는 방법은 무엇입니까?

나는 이것을 어떻게하는지 혼란 스럽다. 이미이 문제에 대한 두 개의 게시물을 작성했지만 여전히 혼란 스럽습니다.

모두 높은 수준의 접근 방식을 설명,하지만 난 입자의 배치를 렌더링하는 방법을 을 알 필요가 어디에서 각 입자의 이동, 회전, 스케일은 모든 프레임으로 바뀝니다. 귀하의 답변이 CPU에서 번역을 계산하는 것이라면, 그 예를 보여주십시오.

현재 구현시 Vertex Array Objects를 사용하고 있습니다. 최상의 성능을 위해 VBO를 사용해야합니다. VBO를 구현 하겠지만, 먼저 배치를 구현하고 싶습니다. 성공적인 일괄 처리가 완료되면 VAO를 VBO로 변경합니다. 따라서이 질문의 초점은 VAO로이를 수행하는 방법입니다.

여기에 배치하기 전에 내 코드가 있었는데, 모델 뷰 매트릭스에서 새 행렬을 삽입하고, 렌더링되고있는 현재 액터에 따라 번역, 회전, 크기 조절 및 알파를 적용하고 현재 액터의 정점과 텍스처 코드를 그립니다. 렌더링 :

glPushMatrix(); 

    glTranslatef(translation.x, translation.y, translation.z); 

    // rotation 
    glRotatef(rotation.x, 1, 0, 0); 
    glRotatef(rotation.y, 0, 1, 0); 
    glRotatef(rotation.z, 0, 0, 1); 

    // scale 
    glScalef(scale.x, scale.y, scale.z); 

    // color and alpha 
    glColor4f(1.0, 1.0, 1.0, alpha); 

    glVertexPointer(2, GL_FLOAT, 0, aSprite.vertices); 
    glEnableClientState(GL_VERTEX_ARRAY); 


    glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glDrawArrays(GL_TRIANGLES, 0, 6); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glPopMatrix(); 

을 지금, 나는이 배치 배열에 모든 입자 배우의 정점과 textureCoords를 조합 한 것을 주어, 나는 그의 정점과 textureCoords를 모델 뷰 행렬에 새로운 매트릭스를 밀어 그릴 싶습니다 적절한 번역, 회전, 축척, 알파 등의 액터 ...

그래서 내

static GLFloat verticesBatched[appropriate_length] = ...; // I have a method to populate this array based on the Actors to render 

    static GLFloat textureCoordsBatched[appropriate_length] = ...; // I have a method to populate this array based on the Actors to render 

    glPushMatrix(); 

    // perform CPU matrix manipulation to manually translate, rotate, and scale all vertices   

    glVertexPointer(2, GL_FLOAT, 0, verticesBatched); 
    glEnableClientState(GL_VERTEX_ARRAY); 


    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordsBatched); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glDrawArrays(GL_TRIANGLES, 0, 6); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glPopMatrix(); 

유효한 대답은 명확하게이 문제에 대한 해결책을 설명하는 코드 예제 하나입니다 : 추측은 같은 soemthing을 보일 것입니다.

답변

0

모든 입자가 같은 질감을 가지고 있기 때문에,이 작업을 수행합니다

float squarevData[12]={ 
    -1,1, 
    1,1, 
    -1,-1, 
    1,1, 
    1,-1, 
    -1,-1, 
}; 
float squarevDataSteady[12]={ 
    -1,1, 
    1,1, 
    -1,-1, 
    1,1, 
    1,-1, 
    -1,-1, 
}; 

class BatchRenderer 
{ 
public: 
    float* partVdata; 
    float* partCdata; 
    float* partTdata; 
    bool isanydrawed; 
    int counter1,counter2,counter3; 
    int count; 
    bool isz; 
    bool textured; 
    void Innit(int maxTextures,bool iszi) 
    { 
     isz=iszi; 
     if(isz)partVdata=(float*)malloc(maxTextures*18*4); 
     else partVdata=(float*)malloc(maxTextures*12*4); 

     partCdata=(float*)malloc(maxTextures*24*4); 
     partTdata=(float*)malloc(maxTextures*12*4); 

     isanydrawed=false; 
    } 
    void Draw(float x,float y,float z,float scalex,float scaley,float angle,float r,float g,float b,float a) 
    { 
     isanydrawed=true; 

     angle*=0.017453f; 
     for(int c2=0;c2<12;c2+=2) 
     { 
      float x=squarevData[c2]*scalex; 
      float y=squarevData[c2+1]*scaley; 
      float cos1=cos(angle); 
      float sin1=sin(angle); 
      squarevDataSteady[c2] = (cos1*x) - (sin1*y); 
      squarevDataSteady[c2+1] = (sin1*x) + (cos1*y); 
     } 

     partVdata[counter1++]=x+squarevDataSteady[0]; 
     partVdata[counter1++]=y+squarevDataSteady[1]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=0; 
     partTdata[counter3++]=1; 


     partVdata[counter1++]=x+squarevDataSteady[2]; 
     partVdata[counter1++]=y+squarevDataSteady[3]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=1; 
     partTdata[counter3++]=1; 

     partVdata[counter1++]=x+squarevDataSteady[4]; 
     partVdata[counter1++]=y+squarevDataSteady[5]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=0; 
     partTdata[counter3++]=0; 

     partVdata[counter1++]=x+squarevDataSteady[6]; 
     partVdata[counter1++]=y+squarevDataSteady[7]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=1; 
     partTdata[counter3++]=1; 

     partVdata[counter1++]=x+squarevDataSteady[8]; 
     partVdata[counter1++]=y+squarevDataSteady[9]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=1; 
     partTdata[counter3++]=0; 

     partVdata[counter1++]=x+squarevDataSteady[10]; 
     partVdata[counter1++]=y+squarevDataSteady[11]; 
     if(isz)partVdata[counter1++]=z; 
     partCdata[counter2++]=r; 
     partCdata[counter2++]=g; 
     partCdata[counter2++]=b; 
     partCdata[counter2++]=a; 
     partTdata[counter3++]=0; 
     partTdata[counter3++]=0; 

     count++; 

    } 
    void RenderStart() 
    { 
     counter1=counter2=count=counter3=0; 
    } 
    void RenderStop(int textureid) 
    { 
     if(!isanydrawed)return; 

      glEnable(GL_TEXTURE_2D); 
      glEnableClientState(GL_COLOR_ARRAY); 
      glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
      glEnableClientState(GL_VERTEX_ARRAY); 
      glBindTexture(GL_TEXTURE_2D, textureid); 
      glTexCoordPointer(2, GL_FLOAT, 0, partTdata); 
     glColorPointer(4, GL_FLOAT, 0,partCdata); 
     if(isz)glVertexPointer(3, GL_FLOAT, 0, partVdata); 
     else glVertexPointer(2, GL_FLOAT, 0, partVdata); 
     glDrawArrays(GL_TRIANGLES, 0, count*6); 
     glDisableClientState(GL_COLOR_ARRAY); 
     glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
     glDisableClientState(GL_VERTEX_ARRAY); 

     isanydrawed=false; 
    } 
}; 

귀하의 코드 : 나는 지금 코드를 테스트하지 못할

BatchRenderer* br=new BatchRenderer(MAX_TEXTURES_NUM,true);//true since you are drawing 3d 
void onParticlesRender() 
{ 
     br->RenderStart(); 
     for(int c=0;c<PARTICLES_SIZE;c++) 
     { 
      br->Draw(p[c].pos.x,p[c].pos.y,p[c].pos.z,p[c].scale.x,p[c].scale.y,p[c].angle,p[c].r,p[c].g,p[c].b,p[c].a); 
     } 
     br->RenderStop(yourTextureID); 
} 

의 작업없이 만약 그렇다면 문제는 pls 알려주세요

VBO는 일괄 렌더링에서 gpu 모든 프레임의 새 버텍스 데이터를 업로드하는 이유로 유용하지 않습니다.