是否可能将一个视图(比如WebView)渲染到FBO中,以便在OpenGL组合中用作纹理?
我整合了一个完整的演示项目,在此repo中可找到,它以高效的方式实时将视图渲染成GL纹理,作为示例展示了如何将WebView实时渲染为GL纹理。
此外,这个项目的简短代码可以看起来像下面这样(取自上述repo的演示项目):
public class GLWebView extends WebView {
private ViewToGLRenderer mViewToGLRenderer;
...
// drawing magic
@Override
public void draw( Canvas canvas ) {
//returns canvas attached to gl texture to draw on
Canvas glAttachedCanvas = mViewToGLRenderer.onDrawViewBegin();
if(glAttachedCanvas != null) {
//translate canvas to reflect view scrolling
float xScale = glAttachedCanvas.getWidth() / (float)canvas.getWidth();
glAttachedCanvas.scale(xScale, xScale);
glAttachedCanvas.translate(-getScrollX(), -getScrollY());
//draw the view to provided canvas
super.draw(glAttachedCanvas);
}
// notify the canvas is updated
mViewToGLRenderer.onDrawViewEnd();
}
...
}
public class ViewToGLRenderer implements GLSurfaceView.Renderer{
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
private int mGlSurfaceTexture;
private Canvas mSurfaceCanvas;
...
@Override
public void onDrawFrame(GL10 gl){
synchronized (this){
// update texture
mSurfaceTexture.updateTexImage();
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height){
releaseSurface();
mGlSurfaceTexture = createTexture();
if (mGlSurfaceTexture > 0){
//attach the texture to a surface.
//It's a clue class for rendering an android view to gl level
mSurfaceTexture = new SurfaceTexture(mGlSurfaceTexture);
mSurfaceTexture.setDefaultBufferSize(mTextureWidth, mTextureHeight);
mSurface = new Surface(mSurfaceTexture);
}
}
public Canvas onDrawViewBegin(){
mSurfaceCanvas = null;
if (mSurface != null) {
try {
mSurfaceCanvas = mSurface.lockCanvas(null);
}catch (Exception e){
Log.e(TAG, "error while rendering view to gl: " + e);
}
}
return mSurfaceCanvas;
}
public void onDrawViewEnd(){
if(mSurfaceCanvas != null) {
mSurface.unlockCanvasAndPost(mSurfaceCanvas);
}
mSurfaceCanvas = null;
}
}
演示输出截图:
是的,这肯定是可能的。我已经编写了一份说明文档,可以在此处找到:http://www.felixjones.co.uk/neo%20website/Android_View/
但是对于静态元素而言,使用位图选项可能更好。
至少有人成功地以这种方式呈现了文本:
它描述了我使用OpenGL ES 1.0和TrueType/OpenType字体文件高效呈现高质量动态文本的方法。
[...]
整个过程实际上非常简单。我们生成位图(作为纹理),计算并存储每个字符的大小以及其在纹理上的位置(UV坐标)。还有一些其他细节,但我们会讲到那些内容。