1

私は OpenGL ES 1.1 を初めて使用し、iPhone で単一のテクスチャから複数のスプライトをレンダリングする一連の関数を作成することからゆっくりと始めようとしています。期待どおりに動作していますが (明らかな間違いがある場合はお知らせください)、コードの最適化を検討しています。そのため、2 つの質問があります。

1) 以下のコードを高速化するにはどうすればよいですか? 私が理解しているように、レンダリングを高速化するために、同じ OpenGL テクスチャから複数の描画呼び出しをバッチ処理できるはずです。これを行うにはどうすればよいですか、知っておくべき良いコード例はありますか?

2) glOrthof を使用して、座標系を 0, 0 からデバイスの幅と高さに変更しました。glTexCoordPointer テクスチャ座標を渡すときに、ピクセル値を渡すことができる同様の処理方法はありますか?

参考までに、ここに私のコードがあります:

- (void)drawGLView
{
    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glClearColor( 0, 0, 0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, spriteTexture);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    for(Sprite *sprite in self.sprites)
    {
        [self drawAtPoint:sprite.location];
    }
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void)drawAtPoint:(CGPoint)point
{
    GLfloat x = point.x, y = point.y;
    GLfloat w = self.spritesheet.size.width;
    GLfloat h = self.spritesheet.size.height;
    GLfloat box[] = {
        x, y + h, 0,
        x, y, 0,
        x + w, y + h, 0,
        x + w, y , 0
    };
    GLfloat tex[] = {
        0, 1,
        0, 0,
        1, 1,
        1, 0
    };

    glVertexPointer(3, GL_FLOAT, 0, box);
    glTexCoordPointer(2, GL_FLOAT, 0, tex);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
4

1 に答える 1

0

1)これが私のパーティクルシステムに使用しているものです(C ++にありますが、要点はわかります)。テクスチャを一列に並べて(水平、すべて同じサイズ)、正しい方法で描画できますid、0-最初の tex 、1-秒など。

class gltAtlasRenderer
{
public:
    float* partVdata;
    float* partCdata;
    float* partTdata;

    int counter1,counter2,counter3;
    int count;
    bool isz;
    int tilesize;
    float tilesx;
    gltAtlasRenderer(int maxTextures,bool iszi,int numberoftiles)
    {
        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);
        tilesize=numberoftiles;
        tilesx=(float)(1.0f/numberoftiles);
    }
    void Draw(int id,float x,float y,float z,float scalex,float scaley,float angle,float r,float g,float b,float a)
    {
        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);
                squarevData2[c2] = (cos1*x) - ( sin1*y);
                squarevData2[c2+1] = (sin1*x) + ( cos1*y);
        }


        //up left
        partVdata[counter1++]=x+squarevData2[0];
        partVdata[counter1++]=y+squarevData2[1];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id;
        partTdata[counter3++]=1;

        //up right
        partVdata[counter1++]=x+squarevData2[2];
        partVdata[counter1++]=y+squarevData2[3];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id+tilesx;
        partTdata[counter3++]=1;


        //down left
        partVdata[counter1++]=x+squarevData2[4];
        partVdata[counter1++]=y+squarevData2[5];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id;
        partTdata[counter3++]=0;

        //up right
        partVdata[counter1++]=x+squarevData2[6];
        partVdata[counter1++]=y+squarevData2[7];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id+tilesx;
        partTdata[counter3++]=1;

        //down right
        partVdata[counter1++]=x+squarevData2[8];
        partVdata[counter1++]=y+squarevData2[9];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id+tilesx;
        partTdata[counter3++]=0;


        //down left
        partVdata[counter1++]=x+squarevData2[10];
        partVdata[counter1++]=y+squarevData2[11];
        if(isz)partVdata[counter1++]=z;
        partCdata[counter2++]=r;
        partCdata[counter2++]=g;
        partCdata[counter2++]=b;
        partCdata[counter2++]=a;
        partTdata[counter3++]=tilesx*id;
        partTdata[counter3++]=0;

        count++;

    }
    void RenderStart()
    {
        counter1=counter2=count=counter3=0;

    }
    void RenderStop(int textureid)
    {
        glEnable(GL_TEXTURE_2D);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
        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);

    }
};

gltAtlasRenderer ar=new gltAtlasRenderer(100,false,5);//max textures, is there z,max textures in texture
ar.RenderStart();
void Render()
{
     for(int c=0;c<100;c++)ar.Draw(0,x,y,z,scalex,scaley,rotation,r,g,b,a);
}
ar.RenderStop(textureid);

2)私が正しいことを理解していれば、テクスチャのサイズでテクスチャ座標を使用したい(0から1のスケールの代わりに)

たとえば、テクスチャ 512x512 では、テクスチャ座標は次のようになります。

float cv(float maxsize,float num)
{
     return (num/maxsize);
}

cv(0),cv(0)//bot,left
cv(512),cv(0)//bot,right
cv(512),cv(512)//top,right
cv(0),cv(512)//bot,left
于 2012-08-12T17:29:48.453 に答える