在屏幕上的不同点渲染多个纹理,而不使用点精灵 [英] Rendering multiple textures at different points on screen without using point sprites

查看:123
本文介绍了在屏幕上的不同点渲染多个纹理,而不使用点精灵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个ios绘图应用程序,并且很难在屏幕上的不同点绘制绘画纹理。大多数在线教程都是指在屏幕上渲染一定大小的单个纹理。

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 texture of a certain size on screen.

然而,我正在寻找的是提供一个2d顶点的数组,绘制基于用户在屏幕上触摸的位置计算的绘制纹理。

However, what I'm looking for is to provide an array of 2d vertices at which to draw the paint texture that is computed based on where the user touches on the screen.

我使用的是点精灵,它不需要我指定纹理坐标和hte用于绘制纹理的原始对象。

I was using point sprites which didn't require me to specify the texture coordinates and hte primitive object used to draw the texture.

但是,我想使用纹理坐标来提供一个原始对象(就像用三角形条绘制的四边形)。

However, I'd like to use texture-coordinates to provide a primitive object (like a quad drawn with triangle strips).

关于如何做到这一点的任何想法?任何指针都会有所帮助。

Any ideas on how to do this? Any pointers would be helpful.

Kunal

推荐答案

如果我理解的话纠正你想要在用户触摸屏幕的点处绘制许多纹理(相同的图像)。对于我的粒子系统,我使用它:

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

    }
};

如何使用?

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

}

你可以用60 fps绘制500多个纹理mid设备,你可以为每个

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

这篇关于在屏幕上的不同点渲染多个纹理,而不使用点精灵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆