Opengl es Opengl。如何在同一绘制调用中多次渲染同一纹理三角形?

Opengl es Opengl。如何在同一绘制调用中多次渲染同一纹理三角形?,opengl-es,Opengl Es,我必须在屏幕的不同点渲染相同的纹理三角形。当渲染超过10次时,我注意到性能受到很大的影响。如何在绘制之前多次渲染相同的纹理三角形 我试图在绘制之前向顶点数组添加新几何体,但没有成功。我认为步长值不正确: 这是顶点和纹理坐标。我想画两个有纹理的正方形,所以我只是复制数组中的数据 在DrawArray中,我将4更改为8。第一个方块看起来不错,第二个肯定不好 GLES20.GlDrawArray(GLES20.GL_三角带,0,8) 在每个纹理中,而不是使用DrawArray,您需要将其顶点和纹理坐标

我必须在屏幕的不同点渲染相同的纹理三角形。当渲染超过10次时,我注意到性能受到很大的影响。如何在绘制之前多次渲染相同的纹理三角形

我试图在绘制之前向顶点数组添加新几何体,但没有成功。我认为步长值不正确:

这是顶点和纹理坐标。我想画两个有纹理的正方形,所以我只是复制数组中的数据

在DrawArray中,我将4更改为8。第一个方块看起来不错,第二个肯定不好 GLES20.GlDrawArray(GLES20.GL_三角带,0,8)


在每个纹理中,而不是使用DrawArray,您需要将其顶点和纹理坐标以正确的旋转和平移保存到一个大数组中,然后使用DrawArray仅绘制此数组。(嗯……我无法更好地解释:))

这是我的密码:

    float squarevData[12]={
            -1,1,
            1,1,
            -1,-1,
            1,1,
            1,-1,
            -1,-1,
        };
    float squarevData2[12]={
            -1,1,
            1,1,
            -1,-1,
            1,1,
            1,-1,
            -1,-1,
        };
    class BatchRenderer
    {
    public:
        float* partVdata;
        float* partCdata;
        float* partTdata;

    int counter1,counter2,counter3;
    int count;
    bool isz;
    BatchRenderer(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);
    }

    void Draw(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);
        }

        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++]=0;
        partTdata[counter3++]=1;


        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++]=1;
        partTdata[counter3++]=1;

        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++]=0;
        partTdata[counter3++]=0;

        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++]=1;
        partTdata[counter3++]=1;

        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++]=1;
        partTdata[counter3++]=0;

        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++]=0;
        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);

    }
};
float squareddata[12]={
-1,1,
1,1,
-1,-1,
1,1,
1,-1,
-1,-1,
};
浮点平方VData2[12]={
-1,1,
1,1,
-1,-1,
1,1,
1,-1,
-1,-1,
};
类批处理渲染器
{
公众:
浮动*部分数据;
浮动*部分CDATA;
浮动*部分数据;
int计数器1、计数器2、计数器3;
整数计数;
布尔伊斯兹;
BatchRenderer(int-maxTextures,bool-iszi)
{
isz=iszi;
如果(isz)partVdata=(float*)malloc(maxtures*18*4);
else partVdata=(float*)malloc(maxTextures*12*4);
partCdata=(浮点*)malloc(maxTextures*24*4);
partTdata=(float*)malloc(maxtures*12*4);
}
虚线绘制(浮标x、浮标y、浮标z、浮标x、浮标y、浮标角度、浮标r、浮标g、浮标b、浮标a)
{
角度*=0.017453f;
对于(int c2=0;c2RenderStart();
对于(intc=0;cDraw(p[c].x,p[c].y,0,p[c].scalex,p[c].scaly,p[c].angle,p[c].r,p[c].g,p[c].b,p[c].a);
}
br->RenderStop(yourtextureid);
}

您可以使用mid设备以60 fps的速度绘制500多个纹理,您可以在每个纹理中为每个

拥有唯一的比例、旋转和颜色,而不是使用DrawArray。您需要将其顶点和纹理坐标以正确的旋转和平移保存到一个大数组中,然后使用DrawArray仅绘制此数组。(嗯……我无法更好地解释:))

这是我的密码:

    float squarevData[12]={
            -1,1,
            1,1,
            -1,-1,
            1,1,
            1,-1,
            -1,-1,
        };
    float squarevData2[12]={
            -1,1,
            1,1,
            -1,-1,
            1,1,
            1,-1,
            -1,-1,
        };
    class BatchRenderer
    {
    public:
        float* partVdata;
        float* partCdata;
        float* partTdata;

    int counter1,counter2,counter3;
    int count;
    bool isz;
    BatchRenderer(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);
    }

    void Draw(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);
        }

        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++]=0;
        partTdata[counter3++]=1;


        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++]=1;
        partTdata[counter3++]=1;

        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++]=0;
        partTdata[counter3++]=0;

        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++]=1;
        partTdata[counter3++]=1;

        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++]=1;
        partTdata[counter3++]=0;

        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++]=0;
        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);

    }
};
float squareddata[12]={
-1,1,
1,1,
-1,-1,
1,1,
1,-1,
-1,-1,
};
浮点平方VData2[12]={
-1,1,
1,1,
-1,-1,
1,1,
1,-1,
-1,-1,
};
类批处理渲染器
{
公众:
浮动*部分数据;
浮动*部分CDATA;
浮动*部分数据;
int计数器1、计数器2、计数器3;
整数计数;
布尔伊斯兹;
BatchRenderer(int-maxTextures,bool-iszi)
{
isz=iszi;
如果(isz)partVdata=(float*)malloc(maxtures*18*4);
else partVdata=(float*)malloc(maxTextures*12*4);
partCdata=(浮点*)malloc(maxTextures*24*4);
partTdata=(float*)malloc(maxtures*12*4);
}
虚线绘制(浮标x、浮标y、浮标z、浮标x、浮标y、浮标角度、浮标r、浮标g、浮标b、浮标a)
{
角度*=0.017453f;
对于(int c2=0;c2RenderStart();
对于(intc=0;cDraw(p[c].x,p[c].y,0,p[c].scalex,p[c].scaly,p[c].angle,p[c].r,p[c].g,p[c].b,p[c].a);
}
br->RenderStop(yourtextureid);
}

你可以用mid设备以60 fps的速度绘制500多个纹理,并且每个纹理都有独特的比例、旋转和颜色

你的代码可能没有经过优化。我现在没有代码。但它当然没有经过优化,这是我的问题,我怎么能…每次绘制三角形时,不要调用glBindTexture。如果你的图像很大这也会降低渲染速度。显示代码会帮助我发现冗余谢谢你的建议。实际上我会在每一帧绑定纹理。所以如果我在绘图方法之外绑定纹理就可以了,对吗?我一到家就会写代码。感谢Nicolasyea,当你使用相同的纹理进行ea时,不需要重新绑定图像ch triangle,无需重新绑定顶点缓冲区,否则您的代码可能未优化。我现在没有代码。但当然它未优化,这是我的问题,我如何…每次绘制三角形时,不要调用glBindTexture。如果您有一个大图像,也会降低渲染速度。显示代码将有助于我spot redundanciesThanks谢谢你的建议。实际上,我会在每一帧绑定纹理。因此,如果我在绘图方法之外绑定纹理就可以了,对吗?我一到家就会写代码。感谢Nicolasyea,当你对每个三角形使用相同的纹理时,不需要重新绑定图像,也不需要重新绑定顶点缓冲区回答。这正是我想要的。但是,我在我的项目中做同样的事情时遇到了一些麻烦。用java编写。我现在要添加我正在尝试的代码…如果你想在不同的点上绘制多个正方形,你不能使用GL_三角形带。你需要为每个正方形提供6个顶点,并将它们绘制为GL_三角形谢谢回答。这正是我想要的。但是,我在我的项目中做同样的事情时遇到了一些麻烦。用java编写。我现在要添加我正在尝试的代码…如果你想在不同的点上绘制多个正方形,你不能使用GL_TRIANGLE_STRIP。你需要为每个正方形提供6个顶点,并将它们绘制为GL_三角形
BatchRenderer* br=new BatchRenderer(500,false)//the max number of textures that can be drawn , and if you want z axis

void Render()
{
      br->RenderStart();
      for(int c=0;c<POINTS;c++)
      {                          
    br->Draw(p[c].x,p[c].y,0,p[c].scalex,p[c].scaly,p[c].angle,p[c].r,p[c].g,p[c].b,p[c].a);
      }
      br->RenderStop(yourtextureid);

}