Results 1 to 10 of 39

Thread: OpenGL GLSL - Text rendering query

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    (too long; didn't fit)
    Code:
    //replacement for GL_LINE_STRIP used in GUI everywhere
    procedure TDumbUniMesh.AddLine(c: array of const;  width: float);
    begin
      GenerateLineMesh(ParseAOCToVector2f(c), width, false);
    end;
    
    procedure TDumbUniMesh.AddLineLoop(c: array of const;  width: float);
    begin
      GenerateLineMesh(ParseAOCToVector2f(c), width, true);
    end;
    
    procedure TDumbUniMesh.AddLine(points: array of TVector2f;  width: float);
    begin
      GenerateLineMesh(points, width, false);
    end;
    
    procedure TDumbUniMesh.AddLineLoop(points: array of TVector2f;  width: float);
    begin
      GenerateLineMesh(points, width, true);
    end;
    
    function TDumbUniMesh.ParseAOCToVector2f(var c: array of const): TVector2fArray;
    var
      i, k, n: integer;
      v: float;
    begin
      if (Length(c) mod 2) <> 0 then Die(MI_ERROR_PROGRAMMER_NO_BAKA, [
                       'Odd number of parameters passed to TDumbLineMesh.AddLine']);
      SetLength(Result, Length(c) div 2);
      n:= 0;
      k:= 0;
      for i:= 0 to High(c) do begin
        case c[i].Vtype of
          vtInteger:    v:= c[i].VInteger;
          vtExtended:   v:= c[i].VExtended^;
        else
          Die(MI_ERROR_PROGRAMMER_NO_BAKA,
                      ['Wrong parameter type passed to TDumbUniMesh.AddLine, Vtype='
                                                           + IntToStr(c[i].Vtype)]);
        end;
        Result[n][k]:= v;
        k:= 1 - k;
        if k = 0 then Inc(n);
      end;
    end;
    
    
    procedure TDumbUniMesh.SetLineTexCoords(a, b: TVector2f; _repeat: boolean); overload;
    begin
      lineTC[0]:= a;
      lineTC[1]:= b - a;
      lineTCrepeat:= _repeat;
    end;
    
    procedure TDumbUniMesh.SetLineTexCoords; // default glyph from | character in the font
    var pv4: PVector4f;
    begin
      pv4:= @Mother^.Text.BuiltinFont[Mother^.Text.FixedFontQuality].GlyphTexCoords^[bifgglyph_Pipe];
      lineTC[0][0]:= pv4^[0];
      lineTC[0][1]:= pv4^[1];
      lineTC[1][0]:= pv4^[2] - pv4^[0];
      lineTC[1][1]:= pv4^[3] - pv4^[1];
      lineTCrepeat:= true;
    end;
    
    
    
    procedure TDumbUniMesh.GenerateLineMesh(points: array of TVector2f;
                                                      width: float;  loop: boolean);
    var
      vectors, //vector goes from i to point i + 1
      rightnormals, conormals, // normal goes clockwise in my GUI
        // coordinate system (X axis goes right, Y axis goes down from the top left
        // screen corner, which is NOT how GL usually is set up)
      v, //vertex buffer. Calculate in 2df before copying to real vertices field
      tc //texcoords.
        : array of TVector2f;
      idx: array of integer; //index buffer. To be copied to the real indices.
      connect, degenerate: array of boolean;//the segment i connects smoothly with segment i - 1
      i, j, a, b, c, numConnections, startInd, startVert, curV, curI: integer;
      anglecosine, veclen, confrac, ffrac: float;
    begin
    
    
      if Length(points) < 2 then Die(MI_ERROR_PROGRAMMER_NO_BAKA,
                      ['Not enough points passed to TDumbUniMesh.GenerateLineMesh']);
      if loop then j:= length(points) else j:= length(points) - 1;
      SetLength(vectors, j);
      SetLength(rightnormals, j);
      SetLength(conormals, j);
      SetLength(connect, j);
      SetLength(degenerate, j);
      for i:= 0 to length(points) - 2 do
        vectors[i]:= points[i + 1] - points[i];
      if loop then
        vectors[j - 1]:= points[0] - points[High(points)];
    
      for i:= 0 to High(vectors) do begin
        rightnormals[i][0]:= - vectors[i][1]; // points clockwise 90 deg from the vector
        rightnormals[i][1]:= vectors[i][0];
        QuickNormalize(rightnormals[i]);
        ffrac:= FastInverseSquareRoot(sqr(vectors[i][0]) + sqr(vectors[i][1]));
        conormals[i]:= vectors[i] * ffrac;
        degenerate[i]:= ffrac > (1 / width);
      end;
    
      numConnections:= 0;
      if loop then a:= 0
      else begin
        a:= 1;
        connect[0]:= false;
      end;
      for i:= a to j - 1 do begin
        if i = 0 then b:= j - 1 else b:= i - 1;
        //connect *only* if angle is less that 90 degrees !
        //otherwise render as separate (overlapping) segments
        anglecosine:= DotProduct(rightnormals[b], rightnormals[i]);
        connect[i]:= (anglecosine >= 0) and not degenerate[i] and not degenerate[b];
        if connect[i] then inc(numConnections);
      end;
    
      width*= 0.5;
    
      //finally generate the mesh
      startInd:= MaxIndex + 1;
      curI:= 0;
      SetLength(idx, (2 * 3 * j) + (4 * 3 * numConnections));
    //addlog('i/i %0/%1 %2 %3 %4 ',[curI, length(idx), j, numConnections, connect[0]]);
    
      startVert:= MaxVertex + 1;
      curV:= 0;
      SetLength(v, (4 * j) + (1 * numConnections));
      if renc_Texcoord in components then begin
        SetLength(tc, Length(v));
      end;
    
      for i:= 0 to j - 1 do begin
        if i = (j - 1)
          then a:= 0 //next point index
          else a:= i + 1;
    
        if connect[i] or connect[a]
          then confrac:= 0.5 * ( 2 * width / QuickLength(vectors[i]));
    
        if connect[i] then begin
          //adding the 4 triangles of the connection
    
          if i > 0
            then c:= curV //vertices added by the previous segment
            else c:= length(v); //vertices that *will* be added by the last segment
              // It's a good thing our algorithm is 100% predictable, isn't it?
    
          idx[curI + 0]:= (* CurV - 1;
          Так вот где таилась погибель моя!
          Мне смертию кость угрожала!
          Из мёртвой главы Access Violation in ig4icd32.dll,
          Шипя, между тем, выползало *) c - 1;
          idx[curI + 1]:= c - 3;
          idx[curI + 2]:= CurV + 0 ;
    
          idx[curI + 3]:= CurV + 1;
          idx[curI + 4]:= c - 2;
          idx[curI + 5]:= c - 1;
    
          idx[curI + 6]:= CurV + 0;
          idx[curI + 7]:= CurV + 1;
          idx[curI + 8]:= c - 1;
    
          idx[curI + 9]:= c - 1;
          idx[curI +10]:= c - 2;
          idx[curI +11]:= c - 3;
    
          inc(curI, 12);
    
          v[curV + 0]:= points[i] + ((conormals[i] - rightnormals[i]) * width);
          v[curV + 1]:= points[i] + ((conormals[i] + rightnormals[i]) * width);
          if renc_Texcoord in components then begin
            tc[curV + 0]:= lineTC[0] + lineTC[1] * ToVector2f(0, confrac);
            tc[curV + 1]:= lineTC[0] + lineTC[1] * ToVector2f(1, confrac);
          end;
        end
        else begin
          v[curV + 0]:= points[i] - (rightnormals[i] * width);
          v[curV + 1]:= points[i] + (rightnormals[i] * width);
          if renc_Texcoord in components then begin
            tc[curV + 0]:= lineTC[0];
            tc[curV + 1]:= lineTC[0]+ lineTC[1] * ToVector2f(1, 0);
          end;
        end;
    
        idx[curI + 0]:= curV + 1; //1st body triangle
        idx[curI + 1]:= curV + 0;
        idx[curI + 2]:= curV + 2;
    
        idx[curI + 3]:= curV + 2; //2nd body triangle
        idx[curI + 4]:= curV + 3;
        idx[curI + 5]:= curV + 1;
    
        inc(curI, 6);
    
        if connect[a] then begin
          v[curV + 2]:= points[a] - ((conormals[i] + rightnormals[i]) * width);
          v[curV + 3]:= points[a] - ((conormals[i] - rightnormals[i]) * width);
          if renc_Texcoord in components then begin
            tc[curV + 2]:= lineTC[0] + lineTC[1] * ToVector2f(0, 1 - confrac);
            tc[curV + 3]:= lineTC[0] + lineTC[1] * ToVector2f(1, 1 - confrac);
          end;
    
          //middle vertex
          v[curV + 4]:= points[a] + (conormals[a] - conormals[i]) * width * 0.5;
          if renc_Texcoord in components then begin
            tc[curV + 4]:= lineTC[0] + lineTC[1] * ToVector2f(0.5, 1);
          end;
    
          inc(curV, 5);
        end
        else begin
          v[curV + 2]:= points[a] - (rightnormals[i] * width);
          v[curV + 3]:= points[a] + (rightnormals[i] * width);
          if renc_Texcoord in components then begin
          tc[curV + 2]:= lineTC[0] + lineTC[1] * ToVector2f(0, 1);
          tc[curV + 3]:= lineTC[0] + lineTC[1] * ToVector2f(1, 1);
          end;
    
          inc(curV, 4);
        end;
      end;
    
      inc (MaxIndex, Length(idx));
      inc (MaxVertex, Length(v));
      EnlargeBuffersIfNecessary;
    
      for i:= 0 to High(idx) do begin
        indices[startInd + i]:= startVert + idx[i];
      end;
    
      ffrac:= 1 / High(v);
      for i:= 0 to High(v) do begin
        vertices[startVert + i]:= v[i];
        if renc_Texcoord in components
          then texcoords[startVert + i]:= tc[i];
        if renc_Normal in components
          then normals[startVert + i]:= currentNormal;
        if renc_Texcoord in components
          then colors[startVert + i]:= currentColor + lineGrad * (i * ffrac);
      end;
    end;
    
    procedure TDumbUniMesh.SetLineGradientTo(c: TVector4f);
    begin
      lineGrad:= c - currentColor;
    end;
    .. and usage (converted my old uber-crappy code to this less-crappy abstraction layer):
    Code:
       Mesh:= TDumbUniMesh.Create;
       Mesh.Color4f(
          f * Mother^.Display.FadeIn, f * Mother^.Display.FadeIn, f * Mother^.Display.FadeIn, 1);
       Mesh.AddQuad2d(
         0, 0, Mother^.Display.ClientRect.Width, Mother^.Display.ClientRect.Height,
         0, 0, 1, 1);
       TGAPI.SetGLStatesForGUI;
       case  Mother^.GAPI.Mode of
        {$ifndef glesonly}
         gapi_GL21 : begin
           glDisable(GL_ALPHA_TEST);
         end;
        {$endif glesonly}
         gapi_GLES2: begin
         end;
       else
         DieUnsupportedGLMode;
       end;
    
       //f_current_bgtex
       //f_current_bgw
       //f_current_bgh
    
       glDisable(GL_BLEND);
       //glEnable(GL_TEXTURE_2D);
       if Mother^.Display.Background.custom = 0
         then glBindTexture(GL_TEXTURE_2D, f_bgtex[Mother^.Display.Background._default])
         else glBindTexture(GL_TEXTURE_2D, Mother^.Display.Background.custom);
       Mesh.Render;
       Mesh.Free;
    {
       glColor4f(f * Mother^.Display.FadeIn, f * Mother^.Display.FadeIn, f * Mother^.Display.FadeIn, 1);
       glBindTexture(GL_TEXTURE_2D, f_bgtex);
       glBegin(GL_QUADS);
         glTexCoord2f(0, 0);
         glVertex2f(0, 0); //bottom left corner
         glTexCoord2f(0, 1);
         glVertex2f(0, Mother^.Display.WindowClientRect.Height);
         glTexCoord2f(1, 1);
         glVertex2f(Mother^.Display.WindowClientRect.Width, Mother^.Display.WindowClientRect.Height);
         glTexCoord2f(1, 0);
         glVertex2f(Mother^.Display.WindowClientRect.Width, 0);
       glEnd;
       glEnable(GL_ALPHA_TEST);
       glEnable(GL_BLEND);
    }

  2. #2
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2
    Whilst I appreciate the advice that I shouldn't use glBegin... unfortunately posting a class that apparently doesn't use it doesn't really help me as it's way to complicated for me right now. I have no idea what the other alternatives are so I don't have a clue where to start looking in that class.

    glBegin is how I've done all my OpenGL stuff and it's fine for what I'm doing at the moment. I know much of what I'm doing is less than optimal, but that aside, any advice on the question regarding shaders?
    :: AthenaOfDelphi :: My Blog :: My Software ::

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •