2

iOS用のiosペイントアプリを作成していますが、特定のポイントでペイントテクスチャを回転させてストロークの方向に向けるのが最も困難です。

ユーザーがタッチするたびに、テクスチャを数ピクセル離して描画しています。頂点は、x 座標と y 座標を持つ 2 次元の点として表現され、頂点バッファーに格納され、画面にレンダリングされます。描画に使用しているコードは次のとおりです。

 count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1);
 GLfloat *vBuffer = malloc(2 * sizeof(GLfloat));
 for(i = 0; i < count; i++) {

    vBuffer[0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
    vBuffer[1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
    CGFloat degrees = atan2(end.y - start.y, end.x - start.x) * 180 / M_PI;

    glMatrixMode(GL_TEXTURE);
    glPushMatrix();
    glVertexPointer(2, GL_FLOAT, 0, vBuffer);
    glDrawArrays(GL_POINTS, 0, count);
    glRotatef(degrees, 0, 0, 1);
    glPopMatrix();
 }

 // render to screen
 glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer);
 [context presentRenderbuffer:GL_RENDERBUFFER_OES];

これでは、2 点間の偏差を表す角度で各頂点のテクスチャを回転させるという、目的の効果が得られません。

私が持っている質問は次のとおりです。

  • すべてのポイントでテクスチャだけを回転するにはどうすればよいですか?
  • 各頂点を x、y 座標だけで表すのに十分ですか、それとも 3 点以上にする必要がありますか?
  • テクスチャ マッピングを有効にする必要がありますか? それが、各頂点でテクスチャを個別に回転させるのを妨げているのですか? もしそうなら、頂点配列のテクスチャ座標配列を上記のように表現するにはどうすればよいですか? 私はその部分を理解することができませんでした。

事前に助けてくれてありがとう!

アップデート:

私はこれを理解することができ、ここに私の答えを投稿しました: https://stackoverflow.com/a/11298219/111856

4

3 に答える 3

5

If you have arrived at this page from a google search (which nearly everyone does) You probably want to know how to rotate sprites rendered using gl_PointCoord. The accepted answer by SteveL incorrectly says this isn't possible but Joel Murphy points out how to do this.

Here is some additional information that may be relevant to you if you use Joel's suggestion. (In my book additional, contributory information is as near to an actual answer as makes no difference!)

  1. The image needs to be root 2 times the size of the original i.e. 1.414 x, not 15% bigger
  2. It is significantly more efficient to do the trigonometry work in the vertex shader. So I have:

    precision mediump float;
    
    attribute vec3 vertex;
    attribute vec3 normal;
    
    uniform mat4 modelviewmatrix[2];
    uniform vec3 unib[4];
    
    varying float dist;
    varying mat2 rotn;
    
    void main(void) {
      gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
      dist = vertex[2];
      rotn = mat2(cos(normal[0]), sin(normal[0]),
                 -sin(normal[0]), cos(normal[0])); 
      gl_PointSize = unib[2][2] / dist;
    }
    

    fragment shader:

    precision mediump float;
    
    uniform sampler2D tex0;
    uniform vec3 unib[4];
    
    varying float dist;
    varying mat2 rotn;
    
    void main(void) {
      vec2 centre = vec2(0.5, 0.5);
      vec2 rot_coord = rotn * (gl_PointCoord - centre) + centre;
      vec4 texc = texture2D(tex0, rot_coord);
      if (dist < 1.0 || texc.a < unib[0][2]) discard;
      gl_FragColor = texc;
    }
    

PS I switched from using highp variables because some of the phone gpus used in the soc boards such as beaglebone and cubitruck don't support it.

PPS As an extension to this approach I have added a version of this shader to pi3d which also uses an offset to use the texture2D() as a sprite atlas. vertex fragment

于 2015-03-25T07:43:47.070 に答える
0

GL_POINTS として描画するときにポイントを回転させることはできません。テクスチャを GL_TRIANGLES として描画するなど、他の方法を使用する必要があります。

于 2012-06-30T19:47:49.213 に答える