Рендеринг нескольких текстур в разных точках на экране без использования точечных спрайтов

Я создаю приложение для рисования ios и с трудом отрисовываю текстуры краски на экране в разных точках. Большинство онлайн-уроков касаются визуализации одной текстуры определенного размера на экране.

Однако то, что я искал, - это предоставить массив 2d вершин, в котором можно нарисовать текстуру краски, которая вычисляется в зависимости от того, где пользователь касается экрана.

Я использовал точечные спрайты, которые не требовали, чтобы я указывал координаты текстуры и примитивный объект, используемый для рисования текстуры.

Однако я хотел бы использовать текстурные координаты для предоставления примитивного объекта (например, квадрата, нарисованного треугольными полосами).

Есть идеи, как это сделать? Любые указатели будут полезны.

Кунал

 kajham30 июн. 2012 г., 17:44
То, что я не могу понять, - это как предоставить координаты для примитивов одним касанием пользователя. Я, вероятно, хочу нарисовать их как GL_TRIANGLE_STRIPS, верно? В каком случае я должен был бы предоставить 3 вершины для каждого треугольника?
 Tim30 июн. 2012 г., 09:05
Я не совсем уверен, с чем конкретно у вас проблемы. Просто нарисуйте столько примитивов, сколько вы хотите, с одной текстурой, свяжите другую текстуру, нарисуйте больше примитивов и т. Д., Пока вы не закончите. Или я что-то пропустил?

Ответы на вопрос(2)

Я наконец получил это, чтобы работать. Я рисовал каждую точку, где пользователь касается примитива TRIANGLE_STRIP, две из которых вместе приводят к квадрату.

    GLfloat *tBuffer = malloc(4 * 2 * sizeof(GLfloat));
    tBuffer[0] = 0.0;
    tBuffer[1] = 1.0;
    tBuffer[2] = 1.0;
    tBuffer[3] = 1.0;
    tBuffer[4] = 0.0;
    tBuffer[5] = 0.0;
    tBuffer[6] = 1.0;
    tBuffer[7] = 0.0;
    glTexCoordPointer(2, GL_FLOAT, 0, tBuffer);

    CGFloat padding = 16;
    vBuffer[0] = xCenter - padding;
    vBuffer[1] = yCenter - padding;

    vBuffer[2] = xCenter + padding;
    vBuffer[3] = yCenter - padding;

    vBuffer[4] = xCenter - padding;
    vBuffer[5] = yCenter + padding;

    vBuffer[6] = xCenter + padding;
    vBuffer[7] = yCenter + padding;

    CGFloat degrees = atan2(end.y - start.y, end.x - start.x) * 180 / M_PI;

    // rotate the texture in the direction of the stroke.
    glMatrixMode(GL_TEXTURE);
    glPushMatrix();
    glTranslatef(0.5, 0.5, 0);
    glRotatef(degrees, 0, 0, 1);
    glTranslatef(-0.5, -0.5, 0);
    glVertexPointer(2, GL_FLOAT, 0, vBuffer);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

xCenter, yCenter - это то, к чему прикасается пользователь. Отступ определяет размер примитива.

Я также поворачиваю текстуру, но перед поворотом перевожу ее в центр, так как в противном случае вращение происходит с опорой в начале координат.

Надеюсь это поможет!

UPDATE:

Мне удалось сократить количество вызовов openGL на 1, выполнив вместо этого следующий набор команд для ротации:

Обратите внимание, что мне удалось сократить количество вызовов OpenGL на 1, выполнив следующий набор команд для поворота (удаление матрицы push / pop)

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glTranslatef(0.5, 0.5, 0);
    [GLManager rotateBrush:degrees];
    glTranslatef(-0.5, -0.5, 0);
    [GLManager drawVertexBuffer:vBuffer withVertexNumber:4];
    glMatrixMode(GL_MODELVIEW);`

Если я правильно понимаю, вы хотите нарисовать много текстур (одного и того же изображения) в точках, которые пользователь коснулся экрана. Для моей системы частиц я использую это:

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

}

Вы можете нарисовать более 500 текстур со скоростью 60 кадров в секунду на среднем устройстве, и у вас может быть уникальный масштаб, поворот и цвет для каждого

Ваш ответ на вопрос