传递具有不同含义的两个矩形,从几何到片段着色器

时间:2015-09-09 16:54:32

标签: opengl

我已经将Cinder库签名的距离字体处理改编为Delphi,现在正在实施一个扭曲,在一次调用中上传多个文本的所有数据,并在缩放时对相对大小进行控制(使用统一代替几何着色器中的1.0001因子,但尚未在此代码中工作)

基本的有符号距离处理不会改变,我只尝试使用几何着色器计算所需的矩形。我理解如何使用triangle_strip创建目标矩形(字符必须出现的位置),但是在将texcoord传递给片段着色器时遇到了问题。

  • 目标矩形:输入topleft.xy + widthheight(维度)用于计算屏幕上每个字符的目标矩形。使用gl_position。

  • 纹理源矩形2:texcoordtl + texdimens,topleft point +字体纹理中字符的尺寸。这是我不确定的要点。使用texcoord in / out param传递给片段。

我会感激任何研究的指针或途径,并特别想知道我计算texcoord坐标并传递它们的方式 片段着色器。

以下记录的数组与GL_ARRAY_BUFFER绑定,并使用一系列glGetAttribLocation / glEnableVertexAttribArray / glVertexAttribPointer调用进行描述)

使用

完成绘图
glDrawArrays(GL_POINTS, 0, numberofelements_in_array );

记录:

  TGLCharacter = packed record // 5*2* single + 1*4 byte color + 1*4 byte detail. = 48 bytes per character drawn
              origin     : TGLVectorf2;  // origin of text   ( = glfloat[2])
              topleft    : TGLVectorf2;  // origin of this character
              widthheight: TGLVectorf2;  // width and heght this chracter
              texcoordtl : TGLVectorf2;  // coordinates topleft in texture.
              texdimens  : TGLVectorf2;  // sizes in texture
              col        : TGLVectorub4; // 4 colors, 1 per rect vertex
              detail     : integer;      // layer. Not used in this example.
              end;

几何代码首先是因为我期待这里的问题:

    #version 150 compatibility
    layout(points) in;
    layout(triangle_strip, max_vertices = 4) out;

    in vec2 gorigin[];
    in vec2 gtopleft[];
    in vec2 gwidthheight[];
    in vec2 gtexcoordtl[];
    in vec2 gtexdimens[];
    in vec4 gcolor[];

    out vec3 fColor;
    out vec2 texcoord;

    void main() {
        // calculate distance cur char - first char of this text
        vec2 dxcoordinate = (gtopleft[0]-gorigin[0]);
        // now multiply with uniform here and calc new coordinate:
        // for now we use uniform slightly close to 1 to make debugging easier and avoid
        // nvidia's shadercompiler to optimize gorigin out.
        // equal to 1, and the nvidia shader optimizes it out.
        vec2 x1y1 = 1.0001*gorigin[0]+dxcoordinate;
        vec2 x2y2 = x1y1+gwidthheight[0]*1.0001;
        vec2 texx1y1 = gtexcoordtl[0];
        vec2 texx2y2 = gtexcoordtl[0]+gtexdimens[0];

        fColor = vec3(gcolor[0].rgb);


        gl_Position = gl_ModelViewProjectionMatrix * vec4(x1y1,0,1.0);
        texcoord = texx1y1.xy;
        EmitVertex();
        gl_Position = gl_ModelViewProjectionMatrix * vec4(x2y2.x,x1y1.y,0,1.0);
        texcoord = vec2(texx2y2.x,texx1y1.y);
        EmitVertex();
        gl_Position= gl_ModelViewProjectionMatrix * vec4(x1y1.x,x2y2.y,0,1.0);
        texcoord = vec2(texx1y1.x,texx2y2.y);
        EmitVertex();
        gl_Position = gl_ModelViewProjectionMatrix * vec4(x2y2,0,1.0);
        texcoord = texx2y2.xy;
        EmitVertex();
        EndPrimitive();
    }

frag code:

#version 150 compatibility

uniform sampler2D   font_map;
uniform float      smoothness;

const float gamma = 2.2;

in vec3 fColor;
in vec2 texcoord;
void main()
{
  // retrieve signed distance
  float sdf = texture2D( font_map, texcoord.xy ).r;

  // perform adaptive anti-aliasing of the edges
  float w = clamp( smoothness * (abs(dFdx(texcoord.x)) + abs(dFdy(texcoord.y))), 0.0, 0.5);
  float a = smoothstep(0.5-w, 0.5+w, sdf);

  // gamma correction for linear attenuation
  a = pow(a, 1.0/gamma);

  if (a<0.1)
  discard;

  // final color
  gl_FragColor.rgb = fColor.rgb;
  gl_FragColor.a = gl_Color.a * a;
}

我认为顶点代码可能正常。

#version 150 compatibility

in vec2 anorigin;
in vec2 topleft;
in vec2 widthheight;
in vec2 texcoordtl;
in vec2 texdimens;
in vec4 color;


out vec2 gorigin;
out vec2 gtopleft;
out vec2 gwidthheight;
out vec2 gtexcoordtl;
out vec2 gtexdimens;
out vec4 gcolor;


void main()
{
  gorigin=anorigin;
  gtopleft=topleft;
  gwidthheight=widthheight;
  gtexcoordtl=texcoordtl;
  gtexdimens=texdimens;
  gcolor=color;

  gl_Position = gl_ModelViewProjectionMatrix * vec4(anorigin.xy,0,1.0);;
}

1 个答案:

答案 0 :(得分:1)

以上代码有效。问题在于上传代码,因此上传了错误的顶点数据。我在调试时对上面的代码做了一些小修改,并将其添加到问题中,以便现在问题显示工作代码。

以下是一些可能的代码,用于更改frag着色器的最后两行以创建轮廓字体。虽然我还不高兴。当缩小字体的颜色似乎改变

  vec3 othercol; // to be added to declarations
丢弃声明下面的

.. rest shader变为:

  othercol=vec3(1.0,1.0,1.0);
  if (sqrt(0.299 * fColor.r*fColor.r + 0.587 * fColor.g*fColor.g + 0.114 * fColor.b*fColor.b)>0.5)
    {  othercol=vec3(0,0,0);}

  // final color
  if (sdf>0.25 && sdf<0.75)
     {gl_FragColor.rgb = othercol.rgb;}
     else
     {gl_FragColor.rgb = fColor.rgb;}


  gl_FragColor.a = gl_Color.a * a;
}