在屏幕上的不同点上渲染多个纹理,而不使用点精灵

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

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

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

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

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

注:Kunal

如果我理解正确,你想绘制很多纹理(相同的图像)在用户触摸屏幕的点。 对于我的粒子系统,我使用这个:

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个纹理,并且可以为每个纹理设置独特的比例,旋转和颜色

我终于得到这个工作。 我画了用户触及的每个点作为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是用户触摸的地方。 填充决定了图元的大小。

我也旋转纹理,但在旋转之前将其翻译为中心,因为旋转发生在原点处的枢轴处,否则。

希望这可以帮助!

更新

我可以通过运行下面的一组旋转命令来将openGL调用的数量减less1:

请注意,我可以通过运行以下一组用于旋转的命令(删除push / popmatrix)来将OpenGL调用的数量减less1

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