绘制为 GL_POINTS(仅指定 2 个坐标)时,是否可以在顶点旋转纹理?

kaj*_*ham 2 opengl-es ios

我正在为 iOS 创建一个 ios 绘画应用程序,并且最难的是在特定点旋转绘画纹理以使其面向笔划的方向。

我在用户的每次触摸之间绘制纹理相距几个像素。顶点被表示为一个带有 x 和 y 坐标的 2d 点到一个顶点缓冲区中,然后渲染到屏幕上。这是我用来绘制的代码:

 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];
Run Code Online (Sandbox Code Playgroud)

这并没有给我想要的效果,即纹理在每个顶点旋转的角度表示两点之间的偏差。

我的问题是:

  • 如何在每个点只旋转纹理?
  • 仅用 x、y 坐标表示每个顶点是否足够,还是必须为 3 个或更多点?
  • 我需要启用纹理映射吗?那是什么阻止我在每个顶点独立旋转纹理?如果是这样,我如何表示上面表示的顶点数组的纹理坐标数组?我一直无法弄清楚那部分。

非常感谢您的帮助!

更新:

我能够弄清楚这一点并在此处发布我的答案:https : //stackoverflow.com/a/11298219/111856

pad*_*dyg 5

如果您是通过谷歌搜索(几乎每个人都这样做)到达此页面的,您可能想知道如何旋转使用 gl_PointCoord 渲染的精灵。SteveL 接受的答案错误地表示这是不可能的,但 Joel Murphy 指出了如何做到这一点。

如果您使用 Joel 的建议,以下是一些可能与您相关的附加信息。(在我的书中,补充信息与实际答案一样接近,没有区别!)

  1. 图像需要是原始大小的 2 倍,即 1.414 x,而不是大 15%
  2. 在顶点着色器中执行三角函数的效率要高得多。所以我有:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    片段着色器:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

PS 我从使用 highp 变量切换过来,因为在 soc 板中使用的一些手机 gpus,如 beaglebone 和 cubitruck 不支持它。

PPS 作为此方法的扩展,我已将此着色器的一个版本添加到 pi3d,它也使用偏移量将 texture2D() 用作精灵图集。顶点 片段