2016-05-18 12 views
0

Ich habe einen benutzerdefinierten ImageTextButton, in dem ich die Schaltfläche zu einem FrameBuffer zuerst rendere und dann mit frameBuffer.getColorBufferTexture() zeichne. Ich möchte das nicht wirklich machen, aber ich benutze einen benutzerdefinierten Shader mit diesem Knopf, der einige visuelle Effekte erzeugt und die einzige Möglichkeit, dies zu erreichen, ist mit einem FrameBuffer. Ich war überrascht zu sehen, dass dies tatsächlich sehr flüssig und schnell funktioniert, der ganze Prozess dauert 1-2ms auf langsamen Geräten und mehrere Instanzen verursachen keinen Framerate-Abfall, also bin ich glücklich mit diesem Bit.LibGDX - Problem mit FrameBuffer, Scene2D Tabelle und Ausschnitt

Das Problem, das ich habe, ist, wenn ich Clipping auf dem ImageTextButton aktivieren (mit setClip (true)). Der Grund dafür ist, dass die Schaltfläche die Breite ändern kann und ich möchte, dass der Text innerhalb der Grenzen der Schaltfläche abgeschnitten wird. Wenn ich den FrameBuffer deaktiviere und normal rende, funktioniert dieser Teil auch sehr gut. Wenn ich die 2 kombiniere, scheint der Clipping-Prozess verwirrt zu sein und das Ergebnis ist entweder kein Text oder sehr kleine Teile des Textes.

Also hier ist der entsprechende Code. Ich nahm an, dass es war, weil ich die FrameBuffer und SpriteBatch Größe/Projektionsmatrix nur für den aktiven Bereich (für die Effizienz), aber wenn ich keine davon ändern und verwenden Sie die gleiche Stapel/Projektionsmatrix, so dass der FrameBuffer verwaltet Ganzer Bildschirm, es ist immer noch das gleiche Ergebnis.

public void initFrameBuffer(){ 
    xCache = (int) super.getX(); yCache = (int) super.getY(); 
    widthCache = (int) super.getWidth(); heightCache = (int) super.getHeight(); 

    frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, widthCache, heightCache, false); 

    fboProjectionMatrix.setToOrtho2D(xCache, yCache+heightCache, widthCache, -heightCache); 

    this.fbBatch = new SpriteBatch(); 
    this.fbBatch.setProjectionMatrix(fboProjectionMatrix); 

    this.frameBufferReady = true; 
} 

public void doFrameBuffer(Batch batch, float parentAlpha){ 
    batch.end(); 

    frameBuffer.begin(); 
    fbBatch.begin(); 
    Gdx.gl20.glClearColor(0f, 0.0f, 0.0f, 0.0f); 
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 
    super.draw(fbBatch, parentAlpha); 
    fbBatch.end(); 
    frameBuffer.end(); 

    batch.begin(); 
} 

public void drawFrameBufferObject(Batch batch, float parentAlpha){ 
    batchColorCache = batch.getColor(); 
    batch.setColor(1.0f, 1.0f, 1.0f, parentAlpha); 
    batch.draw(frameBuffer.getColorBufferTexture(), getX(), getY()); 
    batch.setColor(batchColorCache); 
} 

@Override 
public void draw(Batch batch, float parentAlpha) { 
    if (!this.frameBufferReady) initFrameBuffer(); 
    doFrameBuffer(batch, parentAlpha); 
    drawFrameBufferObject(batch, parentAlpha); 
} 

Sorry für den langen Code, ist es tatsächlich schwer für die notwendigen Teile abgespeckte .. Hilfe enorm wie immer willkommen!

Antwort

0

Nach viel spielen, die Lösung, die ich gefunden habe, ist eine, die wahrscheinlich in anderen Situationen nützlich sein könnte, und das ist wahre Clipping des BitmapFontCache durch Vertexmodifikation, keine Schere beteiligt! Wenn also jemand das nützlich findet, ist der Code;

 float xStart = ...start position of clip 
     float xEnd = ...end position of clip 

     //vertex offset numbers 
     int x_1 = 0, x_2 = 5, x2_1 = 10, x2_2 = 15; 
     int u_1 = 3, u_2 = 8, u2_1 = 13, u2_2 = 18; 

     for (int j = 0, n = pageCount; j < n; j++) { 
      int c = cache.getVertexCount(j); 
      int newIdx = 0; 
      if (c > 0) { // ignore if this texture has no glyphs 
       float[] vertices = cache.getVertices(j); 
       for(int i = 0; i < vertices.length; i+=20){ 

        //if any of the vertices are outside the label, don't put them in the new cache 
        if(vertices[i+x2_1] > xStart && vertices[i+x_1] < xEnd){ 
         for(int k = 0; k < 20; k++){ 
          clippedVerts[j][newIdx+k] = vertices[i+k]; 
         } 

         //case on major left glyph 
         if(vertices[i+x_1] < xStart){ 
          float xDiff = vertices[i+x2_1]-xStart; //difference between right of glyph and clip 
          float xRatio = xDiff/(vertices[i+x2_1]-vertices[i+x_1]); 
          float uDiff = vertices[i+u2_1] - vertices[i+u_1]; 
          float newU = vertices[i+u2_1] - uDiff*xRatio; 

          clippedVerts[j][newIdx+x_1] = xStart; 
          clippedVerts[j][newIdx+x_2] = xStart; 
          clippedVerts[j][newIdx+u_1] = newU; 
          clippedVerts[j][newIdx+u_2] = newU; 
         } 

         //case on major right glyph 
         if(vertices[i+x2_1] > xEnd){ 
          float xDiff = xEnd-vertices[i+x_1]; //difference between left of glyph and clip 
          float xRatio = xDiff/(vertices[i+x2_1]-vertices[i+x_1]); 
          float uDiff = vertices[i+u2_1] - vertices[i+u_1]; 
          float newU_2 = vertices[i+u_1] + uDiff*xRatio; 

          clippedVerts[j][newIdx+x2_1] = xEnd; 
          clippedVerts[j][newIdx+x2_2] = xEnd; 
          clippedVerts[j][newIdx+u2_1] = newU_2; 
          clippedVerts[j][newIdx+u2_2] = newU_2; 
         } 
         newIdx += 20; 
        } 
       } 
      } 
      clippedIdx[j] = newIdx; 
     } 

     for (int j = 0, n = pageCount; j < n; j++) { 
      int idx = clippedIdx[j]; 
      if (idx > 0) { // ignore if this texture has no glyphs 
       float[] vertices = clippedVerts[j]; 
       batch.draw(regions.get(j).getTexture(), vertices, 0, idx); 
      } 
     } 
Verwandte Themen