Rendering multiple textures at different points on screen without using point sprites

后端 未结 2 1352
后悔当初
后悔当初 2020-12-20 07:55

I\'m building an ios drawing app and am having a hard time how to draw paint textures on the screen at different points. Most tutorials online refer to rendering a single te

2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-20 08:56

    If i understand correct you want to draw many textures (same image) at points that the user touched the screen . For my particle system i use this:

    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);
    
        }
    };
    

    How to use it?

    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;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);
    
    }
    

    You can draw more than 500 textures in 60 fps with a mid device and you can have unique scale,rotation and color for each

提交回复
热议问题