/** * Copyright 2010 The ForPlay Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package forplay.html; import static com.google.gwt.webgl.client.WebGLRenderingContext.*; import com.google.gwt.webgl.client.WebGLFramebuffer; import com.google.gwt.webgl.client.WebGLRenderingContext; import com.google.gwt.webgl.client.WebGLTexture; import forplay.core.Asserts; import forplay.core.Surface; import forplay.core.SurfaceLayer; import forplay.core.Transform; class HtmlSurfaceLayerGL extends HtmlLayerGL implements SurfaceLayer { private WebGLFramebuffer fbuf; private WebGLTexture tex; private HtmlSurfaceGL surface; private final int width; private final int height; HtmlSurfaceLayerGL(HtmlGraphicsGL gfx, int width, int height) { super(gfx); this.width = width; this.height = height; gfx.flush(); WebGLRenderingContext gl = gfx.gl; tex = gfx.createTexture(false, false); gl.texImage2D(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, UNSIGNED_BYTE, null); fbuf = gl.createFramebuffer(); gl.bindFramebuffer(FRAMEBUFFER, fbuf); gl.framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, tex, 0); gl.bindTexture(TEXTURE_2D, null); gfx.bindFramebuffer(); surface = new HtmlSurfaceGL(gfx, fbuf, width, height); } @Override public void destroy() { super.destroy(); gfx.destroyTexture(tex); gfx.gl.deleteFramebuffer(fbuf); tex = null; fbuf = null; surface = null; } @Override public Surface surface() { return surface; } @Override void paint(WebGLRenderingContext gl, Transform parentTransform, float parentAlpha) { if (!visible()) return; // Draw this layer to the screen upside-down, because its contents are flipped // (This happens because it uses the same vertex program as everything else, // which flips vertically to put the origin at the top-left). gfx.drawTexture(tex, width, height, localTransform(parentTransform), 0, height, width, -height, false, false, parentAlpha * alpha); } @Override public float width() { Asserts.checkNotNull(surface, "Surface must not be null"); return surface.width(); } @Override public float height() { Asserts.checkNotNull(surface, "Surface must not be null"); return surface.height(); } @Override public float scaledWidth() { return transform().scaleX() * width(); } @Override public float scaledHeight() { return transform().scaleY() * height(); } }