我有一个自定义ImageTextButton,在该图像中我首先将按钮呈现到FrameBuffer,然后使用frameBuffer.getColorBufferTexture()进行绘制。我并不是真的想要这样做,但是我使用了带有此按钮的自定义着色器,它创建了一些视觉效果,而我能够实现的唯一方法是使用FrameBuffer。我很惊讶地发现它实际上非常顺畅和快速,整个过程在慢速设备上需要1-2ms的时间,并且拥有多个实例不会导致任何帧率下降,因此我对此感到满意。
我遇到的问题是当我启用对ImageTextButton的剪辑(使用setClip(true))时。原因是按钮可以改变宽度,我希望它可以将文本剪切到按钮的范围内。如果我禁用了FrameBuffer并正常渲染,那么这部分效果也很好。如果将2组合起来,则似乎剪切过程变得混乱,结果是没有文本或文本的一小部分。
所以这是相关的代码。我以为是因为我设置FrameBuffer和SpriteBatch大小/投影矩阵只是为了处理活动区域(以提高效率),但是,如果我不对此进行任何修改并使用相同的批处理/投影矩阵,则FrameBuffer会管理整个屏幕,仍然是相同的结果。
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);
}
很抱歉,很长的代码,实际上已经对必要的部分进行了精简。.一如既往地提供帮助,不胜感激!
经过大量的研究,我发现的解决方案可能在其他情况下可能有用,那就是通过顶点修改对BitmapFontCache进行真正的裁剪,而无需使用剪刀!因此,如果有人觉得这很有用,那么代码就是;
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);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句