mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
1990 lines
56 KiB
Java
1990 lines
56 KiB
Java
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
|
|
/*
|
|
Part of the Processing project - http://processing.org
|
|
|
|
Copyright (c) 2012-15 The Processing Foundation
|
|
Copyright (c) 2004-12 Ben Fry and Casey Reas
|
|
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation, version 2.1.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General
|
|
Public License along with this library; if not, write to the
|
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
package processing.opengl;
|
|
|
|
import java.awt.Font;
|
|
import java.awt.FontMetrics;
|
|
import java.awt.Shape;
|
|
import java.awt.Toolkit;
|
|
import java.awt.font.FontRenderContext;
|
|
import java.awt.font.GlyphVector;
|
|
import java.awt.geom.PathIterator;
|
|
import java.io.IOException;
|
|
import java.net.URL;
|
|
import java.nio.Buffer;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.IntBuffer;
|
|
|
|
import com.jogamp.common.util.VersionNumber;
|
|
import com.jogamp.opengl.GL;
|
|
import com.jogamp.opengl.GL2;
|
|
import com.jogamp.opengl.GL2ES2;
|
|
import com.jogamp.opengl.GL2ES3;
|
|
import com.jogamp.opengl.GL2GL3;
|
|
import com.jogamp.opengl.GL3ES3;
|
|
import com.jogamp.opengl.GLAutoDrawable;
|
|
import com.jogamp.opengl.GLCapabilities;
|
|
import com.jogamp.opengl.GLCapabilitiesImmutable;
|
|
import com.jogamp.opengl.GLContext;
|
|
import com.jogamp.opengl.GLDrawable;
|
|
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
|
|
import com.jogamp.opengl.glu.GLU;
|
|
import com.jogamp.opengl.glu.GLUtessellator;
|
|
import com.jogamp.opengl.glu.GLUtessellatorCallbackAdapter;
|
|
|
|
import processing.core.PApplet;
|
|
import processing.core.PGraphics;
|
|
import processing.core.PMatrix3D;
|
|
import processing.core.PSurface;
|
|
|
|
|
|
public class PJOGL extends PGL {
|
|
// OpenGL profile to use (2, 3 or 4)
|
|
public static int profile = 2;
|
|
|
|
// User-provided icons to override defaults
|
|
protected static String[] icons = null;
|
|
|
|
// The two windowing toolkits available to use in JOGL:
|
|
public static final int AWT = 0; // http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing
|
|
public static final int NEWT = 1; // http://jogamp.org/jogl/doc/NEWT-Overview.html
|
|
|
|
// ........................................................
|
|
|
|
// Public members to access the underlying GL objects and context
|
|
|
|
/** Basic GL functionality, common to all profiles */
|
|
public GL gl;
|
|
|
|
/** GLU interface **/
|
|
public GLU glu;
|
|
|
|
/** The rendering context (holds rendering state info) */
|
|
public GLContext context;
|
|
|
|
// ........................................................
|
|
|
|
// Additional parameters
|
|
|
|
/** Time that the Processing's animation thread will wait for JOGL's rendering
|
|
* thread to be done with a single frame.
|
|
*/
|
|
protected static int DRAW_TIMEOUT_MILLIS = 500;
|
|
|
|
// ........................................................
|
|
|
|
// Protected JOGL-specific objects needed to access the GL profiles
|
|
|
|
/** The capabilities of the OpenGL rendering surface */
|
|
protected GLCapabilitiesImmutable capabilities;
|
|
|
|
/** The rendering surface */
|
|
protected GLDrawable drawable;
|
|
|
|
/** GLES2 functionality (shaders, etc) */
|
|
protected GL2ES2 gl2;
|
|
|
|
/** GL3 interface */
|
|
protected GL2GL3 gl3;
|
|
|
|
/** GL2 desktop functionality (blit framebuffer, map buffer range,
|
|
* multisampled renderbuffers) */
|
|
protected GL2 gl2x;
|
|
|
|
/** GL3ES3 interface */
|
|
protected GL3ES3 gl3es3;
|
|
|
|
/** Stores exceptions that ocurred during drawing */
|
|
protected Exception drawException;
|
|
|
|
// ........................................................
|
|
|
|
// Utility arrays to copy projection/modelview matrices to GL
|
|
|
|
protected float[] projMatrix;
|
|
protected float[] mvMatrix;
|
|
|
|
// ........................................................
|
|
|
|
// Static initialization for some parameters that need to be different for
|
|
// JOGL
|
|
|
|
static {
|
|
MIN_DIRECT_BUFFER_SIZE = 2;
|
|
INDEX_TYPE = GL.GL_UNSIGNED_SHORT;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
// Initialization, finalization
|
|
|
|
|
|
public PJOGL(PGraphicsOpenGL pg) {
|
|
super(pg);
|
|
glu = new GLU();
|
|
}
|
|
|
|
|
|
@Override
|
|
public Object getNative() {
|
|
return sketch.getSurface().getNative();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void setFrameRate(float fps) {}
|
|
|
|
|
|
@Override
|
|
protected void initSurface(int antialias) {}
|
|
|
|
|
|
@Override
|
|
protected void reinitSurface() {}
|
|
|
|
|
|
@Override
|
|
protected void registerListeners() {}
|
|
|
|
|
|
static public void setIcon(String... icons) {
|
|
PJOGL.icons = new String[icons.length];
|
|
PApplet.arrayCopy(icons, PJOGL.icons);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
// Public methods to get/set renderer's properties
|
|
|
|
|
|
public void setCaps(GLCapabilities caps) {
|
|
reqNumSamples = caps.getNumSamples();
|
|
capabilities = caps;
|
|
}
|
|
|
|
|
|
public GLCapabilitiesImmutable getCaps() {
|
|
return capabilities;
|
|
}
|
|
|
|
|
|
public void setFps(float fps) {
|
|
if (!setFps || targetFps != fps) {
|
|
if (60 < fps) {
|
|
// Disables v-sync
|
|
gl.setSwapInterval(0);
|
|
} else if (30 < fps) {
|
|
gl.setSwapInterval(1);
|
|
} else {
|
|
gl.setSwapInterval(2);
|
|
}
|
|
targetFps = currentFps = fps;
|
|
setFps = true;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getDepthBits() {
|
|
return capabilities.getDepthBits();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getStencilBits() {
|
|
return capabilities.getStencilBits();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected float getPixelScale() {
|
|
PSurface surf = sketch.getSurface();
|
|
if (surf == null) {
|
|
return graphics.pixelDensity;
|
|
} else if (surf instanceof PSurfaceJOGL) {
|
|
return ((PSurfaceJOGL)surf).getPixelScale();
|
|
} else {
|
|
throw new RuntimeException("Renderer cannot find a JOGL surface");
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void getGL(PGL pgl) {
|
|
PJOGL pjogl = (PJOGL)pgl;
|
|
|
|
this.drawable = pjogl.drawable;
|
|
this.context = pjogl.context;
|
|
this.glContext = pjogl.glContext;
|
|
setThread(pjogl.glThread);
|
|
|
|
this.gl = pjogl.gl;
|
|
this.gl2 = pjogl.gl2;
|
|
this.gl2x = pjogl.gl2x;
|
|
this.gl3 = pjogl.gl3;
|
|
this.gl3es3 = pjogl.gl3es3;
|
|
}
|
|
|
|
|
|
public void getGL(GLAutoDrawable glDrawable) {
|
|
context = glDrawable.getContext();
|
|
glContext = context.hashCode();
|
|
setThread(Thread.currentThread());
|
|
|
|
gl = context.getGL();
|
|
gl2 = gl.getGL2ES2();
|
|
try {
|
|
gl2x = gl.getGL2();
|
|
} catch (com.jogamp.opengl.GLException e) {
|
|
gl2x = null;
|
|
}
|
|
try {
|
|
gl3 = gl.getGL2GL3();
|
|
} catch (com.jogamp.opengl.GLException e) {
|
|
gl3 = null;
|
|
}
|
|
try {
|
|
gl3es3 = gl.getGL3ES3();
|
|
} catch (com.jogamp.opengl.GLException e) {
|
|
gl3es3 = null;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected boolean canDraw() { return true; }
|
|
|
|
|
|
@Override
|
|
protected void requestFocus() {}
|
|
|
|
|
|
@Override
|
|
protected void requestDraw() {}
|
|
|
|
|
|
@Override
|
|
protected void swapBuffers() {
|
|
PSurfaceJOGL surf = (PSurfaceJOGL)sketch.getSurface();
|
|
surf.window.swapBuffers();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void initFBOLayer() {
|
|
if (0 < sketch.frameCount) {
|
|
if (isES()) initFBOLayerES();
|
|
else initFBOLayerGL();
|
|
}
|
|
}
|
|
|
|
|
|
private void initFBOLayerES() {
|
|
IntBuffer buf = allocateDirectIntBuffer(fboWidth * fboHeight);
|
|
|
|
if (hasReadBuffer()) readBuffer(BACK);
|
|
readPixelsImpl(0, 0, fboWidth, fboHeight, RGBA, UNSIGNED_BYTE, buf);
|
|
bindTexture(TEXTURE_2D, glColorTex.get(frontTex));
|
|
texSubImage2D(TEXTURE_2D, 0, 0, 0, fboWidth, fboHeight, RGBA, UNSIGNED_BYTE, buf);
|
|
|
|
bindTexture(TEXTURE_2D, glColorTex.get(backTex));
|
|
texSubImage2D(TEXTURE_2D, 0, 0, 0, fboWidth, fboHeight, RGBA, UNSIGNED_BYTE, buf);
|
|
|
|
bindTexture(TEXTURE_2D, 0);
|
|
bindFramebufferImpl(FRAMEBUFFER, 0);
|
|
}
|
|
|
|
|
|
private void initFBOLayerGL() {
|
|
// Copy the contents of the front and back screen buffers to the textures
|
|
// of the FBO, so they are properly initialized. Note that the front buffer
|
|
// of the default framebuffer (the screen) contains the previous frame:
|
|
// https://www.opengl.org/wiki/Default_Framebuffer
|
|
// so it is copied to the front texture of the FBO layer:
|
|
if (pclearColor || 0 < pgeomCount || !sketch.isLooping()) {
|
|
if (hasReadBuffer()) readBuffer(FRONT);
|
|
} else {
|
|
// ...except when the previous frame has not been cleared and nothing was
|
|
// rendered while looping. In this case the back buffer, which holds the
|
|
// initial state of the previous frame, still contains the most up-to-date
|
|
// screen state.
|
|
readBuffer(BACK);
|
|
}
|
|
bindFramebufferImpl(DRAW_FRAMEBUFFER, glColorFbo.get(0));
|
|
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
|
TEXTURE_2D, glColorTex.get(frontTex), 0);
|
|
if (hasDrawBuffer()) drawBuffer(COLOR_ATTACHMENT0);
|
|
blitFramebuffer(0, 0, fboWidth, fboHeight,
|
|
0, 0, fboWidth, fboHeight,
|
|
COLOR_BUFFER_BIT, NEAREST);
|
|
|
|
readBuffer(BACK);
|
|
bindFramebufferImpl(DRAW_FRAMEBUFFER, glColorFbo.get(0));
|
|
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
|
TEXTURE_2D, glColorTex.get(backTex), 0);
|
|
drawBuffer(COLOR_ATTACHMENT0);
|
|
blitFramebuffer(0, 0, fboWidth, fboHeight,
|
|
0, 0, fboWidth, fboHeight,
|
|
COLOR_BUFFER_BIT, NEAREST);
|
|
|
|
bindFramebufferImpl(FRAMEBUFFER, 0);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void beginGL() {
|
|
PMatrix3D proj = graphics.projection;
|
|
PMatrix3D mdl = graphics.modelview;
|
|
if (gl2x != null) {
|
|
if (projMatrix == null) {
|
|
projMatrix = new float[16];
|
|
}
|
|
gl2x.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
|
|
projMatrix[ 0] = proj.m00;
|
|
projMatrix[ 1] = proj.m10;
|
|
projMatrix[ 2] = proj.m20;
|
|
projMatrix[ 3] = proj.m30;
|
|
projMatrix[ 4] = proj.m01;
|
|
projMatrix[ 5] = proj.m11;
|
|
projMatrix[ 6] = proj.m21;
|
|
projMatrix[ 7] = proj.m31;
|
|
projMatrix[ 8] = proj.m02;
|
|
projMatrix[ 9] = proj.m12;
|
|
projMatrix[10] = proj.m22;
|
|
projMatrix[11] = proj.m32;
|
|
projMatrix[12] = proj.m03;
|
|
projMatrix[13] = proj.m13;
|
|
projMatrix[14] = proj.m23;
|
|
projMatrix[15] = proj.m33;
|
|
gl2x.glLoadMatrixf(projMatrix, 0);
|
|
|
|
if (mvMatrix == null) {
|
|
mvMatrix = new float[16];
|
|
}
|
|
gl2x.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
|
mvMatrix[ 0] = mdl.m00;
|
|
mvMatrix[ 1] = mdl.m10;
|
|
mvMatrix[ 2] = mdl.m20;
|
|
mvMatrix[ 3] = mdl.m30;
|
|
mvMatrix[ 4] = mdl.m01;
|
|
mvMatrix[ 5] = mdl.m11;
|
|
mvMatrix[ 6] = mdl.m21;
|
|
mvMatrix[ 7] = mdl.m31;
|
|
mvMatrix[ 8] = mdl.m02;
|
|
mvMatrix[ 9] = mdl.m12;
|
|
mvMatrix[10] = mdl.m22;
|
|
mvMatrix[11] = mdl.m32;
|
|
mvMatrix[12] = mdl.m03;
|
|
mvMatrix[13] = mdl.m13;
|
|
mvMatrix[14] = mdl.m23;
|
|
mvMatrix[15] = mdl.m33;
|
|
gl2x.glLoadMatrixf(mvMatrix, 0);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected boolean hasFBOs() {
|
|
if (context.hasBasicFBOSupport()) return true;
|
|
else return super.hasFBOs();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected boolean hasShaders() {
|
|
if (context.hasGLSL()) return true;
|
|
else return super.hasShaders();
|
|
}
|
|
|
|
|
|
public void init(GLAutoDrawable glDrawable) {
|
|
capabilities = glDrawable.getChosenGLCapabilities();
|
|
if (!hasFBOs()) {
|
|
throw new RuntimeException(MISSING_FBO_ERROR);
|
|
}
|
|
if (!hasShaders()) {
|
|
throw new RuntimeException(MISSING_GLSL_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Utility functions
|
|
|
|
|
|
@Override
|
|
protected void enableTexturing(int target) {
|
|
if (target == TEXTURE_2D) {
|
|
texturingTargets[0] = true;
|
|
} else if (target == TEXTURE_RECTANGLE) {
|
|
texturingTargets[1] = true;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void disableTexturing(int target) {
|
|
if (target == TEXTURE_2D) {
|
|
texturingTargets[0] = false;
|
|
} else if (target == TEXTURE_RECTANGLE) {
|
|
texturingTargets[1] = false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Convenience method to get a legit FontMetrics object. Where possible,
|
|
* override this any renderer subclass so that you're not using what's
|
|
* returned by getDefaultToolkit() to get your metrics.
|
|
*/
|
|
@SuppressWarnings("deprecation")
|
|
private FontMetrics getFontMetrics(Font font) { // ignore
|
|
return Toolkit.getDefaultToolkit().getFontMetrics(font);
|
|
}
|
|
|
|
|
|
/**
|
|
* Convenience method to jump through some Java2D hoops and get an FRC.
|
|
*/
|
|
private FontRenderContext getFontRenderContext(Font font) { // ignore
|
|
return getFontMetrics(font).getFontRenderContext();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getFontAscent(Object font) {
|
|
return getFontMetrics((Font) font).getAscent();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getFontDescent(Object font) {
|
|
return getFontMetrics((Font) font).getDescent();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getTextWidth(Object font, char[] buffer, int start, int stop) {
|
|
// maybe should use one of the newer/fancier functions for this?
|
|
int length = stop - start;
|
|
FontMetrics metrics = getFontMetrics((Font) font);
|
|
return metrics.charsWidth(buffer, start, length);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected Object getDerivedFont(Object font, float size) {
|
|
return ((Font) font).deriveFont(size);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected int getGLSLVersion() {
|
|
VersionNumber vn = context.getGLSLVersionNumber();
|
|
return vn.getMajor() * 100 + vn.getMinor();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String getGLSLVersionSuffix() {
|
|
VersionNumber vn = context.getGLSLVersionNumber();
|
|
if (context.isGLESProfile() && 1 < vn.getMajor()) {
|
|
return " es";
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadVertexShader(String filename) {
|
|
return loadVertexShader(filename, getGLSLVersion(), getGLSLVersionSuffix());
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadFragmentShader(String filename) {
|
|
return loadFragmentShader(filename, getGLSLVersion(), getGLSLVersionSuffix());
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadVertexShader(URL url) {
|
|
return loadVertexShader(url, getGLSLVersion(), getGLSLVersionSuffix());
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadFragmentShader(URL url) {
|
|
return loadFragmentShader(url, getGLSLVersion(), getGLSLVersionSuffix());
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadFragmentShader(String filename, int version, String versionSuffix) {
|
|
String[] fragSrc0 = sketch.loadStrings(filename);
|
|
return preprocessFragmentSource(fragSrc0, version, versionSuffix);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadVertexShader(String filename, int version, String versionSuffix) {
|
|
String[] vertSrc0 = sketch.loadStrings(filename);
|
|
return preprocessVertexSource(vertSrc0, version, versionSuffix);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadFragmentShader(URL url, int version, String versionSuffix) {
|
|
try {
|
|
String[] fragSrc0 = PApplet.loadStrings(url.openStream());
|
|
return preprocessFragmentSource(fragSrc0, version, versionSuffix);
|
|
} catch (IOException e) {
|
|
PGraphics.showException("Cannot load fragment shader " + url.getFile());
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String[] loadVertexShader(URL url, int version, String versionSuffix) {
|
|
try {
|
|
String[] vertSrc0 = PApplet.loadStrings(url.openStream());
|
|
return preprocessVertexSource(vertSrc0, version, versionSuffix);
|
|
} catch (IOException e) {
|
|
PGraphics.showException("Cannot load vertex shader " + url.getFile());
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Tessellator
|
|
|
|
|
|
@Override
|
|
protected Tessellator createTessellator(TessellatorCallback callback) {
|
|
return new Tessellator(callback);
|
|
}
|
|
|
|
|
|
protected static class Tessellator implements PGL.Tessellator {
|
|
protected GLUtessellator tess;
|
|
protected TessellatorCallback callback;
|
|
protected GLUCallback gluCallback;
|
|
|
|
public Tessellator(TessellatorCallback callback) {
|
|
this.callback = callback;
|
|
tess = GLU.gluNewTess();
|
|
gluCallback = new GLUCallback();
|
|
|
|
GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, gluCallback);
|
|
GLU.gluTessCallback(tess, GLU.GLU_TESS_END, gluCallback);
|
|
GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, gluCallback);
|
|
GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE, gluCallback);
|
|
GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, gluCallback);
|
|
}
|
|
|
|
@Override
|
|
public void setCallback(int flag) {
|
|
GLU.gluTessCallback(tess, flag, gluCallback);
|
|
}
|
|
|
|
@Override
|
|
public void setWindingRule(int rule) {
|
|
setProperty(GLU.GLU_TESS_WINDING_RULE, rule);
|
|
}
|
|
|
|
public void setProperty(int property, int value) {
|
|
GLU.gluTessProperty(tess, property, value);
|
|
}
|
|
|
|
@Override
|
|
public void beginPolygon() {
|
|
beginPolygon(null);
|
|
}
|
|
|
|
@Override
|
|
public void beginPolygon(Object data) {
|
|
GLU.gluTessBeginPolygon(tess, data);
|
|
}
|
|
|
|
@Override
|
|
public void endPolygon() {
|
|
GLU.gluTessEndPolygon(tess);
|
|
}
|
|
|
|
@Override
|
|
public void beginContour() {
|
|
GLU.gluTessBeginContour(tess);
|
|
}
|
|
|
|
@Override
|
|
public void endContour() {
|
|
GLU.gluTessEndContour(tess);
|
|
}
|
|
|
|
@Override
|
|
public void addVertex(double[] v) {
|
|
addVertex(v, 0, v);
|
|
}
|
|
|
|
@Override
|
|
public void addVertex(double[] v, int n, Object data) {
|
|
GLU.gluTessVertex(tess, v, n, data);
|
|
}
|
|
|
|
protected class GLUCallback extends GLUtessellatorCallbackAdapter {
|
|
@Override
|
|
public void begin(int type) {
|
|
callback.begin(type);
|
|
}
|
|
|
|
@Override
|
|
public void end() {
|
|
callback.end();
|
|
}
|
|
|
|
@Override
|
|
public void vertex(Object data) {
|
|
callback.vertex(data);
|
|
}
|
|
|
|
@Override
|
|
public void combine(double[] coords, Object[] data,
|
|
float[] weight, Object[] outData) {
|
|
callback.combine(coords, data, weight, outData);
|
|
}
|
|
|
|
@Override
|
|
public void error(int errnum) {
|
|
callback.error(errnum);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected String tessError(int err) {
|
|
return glu.gluErrorString(err);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Font outline
|
|
|
|
|
|
static {
|
|
SHAPE_TEXT_SUPPORTED = true;
|
|
SEG_MOVETO = PathIterator.SEG_MOVETO;
|
|
SEG_LINETO = PathIterator.SEG_LINETO;
|
|
SEG_QUADTO = PathIterator.SEG_QUADTO;
|
|
SEG_CUBICTO = PathIterator.SEG_CUBICTO;
|
|
SEG_CLOSE = PathIterator.SEG_CLOSE;
|
|
}
|
|
|
|
|
|
@Override
|
|
protected FontOutline createFontOutline(char ch, Object font) {
|
|
return new FontOutline(ch, (Font) font);
|
|
}
|
|
|
|
|
|
protected class FontOutline implements PGL.FontOutline {
|
|
PathIterator iter;
|
|
|
|
public FontOutline(char ch, Font font) {
|
|
char[] textArray = new char[] { ch };
|
|
FontRenderContext frc = getFontRenderContext(font);
|
|
GlyphVector gv = font.createGlyphVector(frc, textArray);
|
|
Shape shp = gv.getOutline();
|
|
iter = shp.getPathIterator(null);
|
|
}
|
|
|
|
public boolean isDone() {
|
|
return iter.isDone();
|
|
}
|
|
|
|
public int currentSegment(float[] coords) {
|
|
return iter.currentSegment(coords);
|
|
}
|
|
|
|
public void next() {
|
|
iter.next();
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Constants
|
|
|
|
static {
|
|
FALSE = GL.GL_FALSE;
|
|
TRUE = GL.GL_TRUE;
|
|
|
|
INT = GL2ES2.GL_INT;
|
|
BYTE = GL.GL_BYTE;
|
|
SHORT = GL.GL_SHORT;
|
|
FLOAT = GL.GL_FLOAT;
|
|
BOOL = GL2ES2.GL_BOOL;
|
|
UNSIGNED_INT = GL.GL_UNSIGNED_INT;
|
|
UNSIGNED_BYTE = GL.GL_UNSIGNED_BYTE;
|
|
UNSIGNED_SHORT = GL.GL_UNSIGNED_SHORT;
|
|
|
|
RGB = GL.GL_RGB;
|
|
RGBA = GL.GL_RGBA;
|
|
ALPHA = GL.GL_ALPHA;
|
|
LUMINANCE = GL.GL_LUMINANCE;
|
|
LUMINANCE_ALPHA = GL.GL_LUMINANCE_ALPHA;
|
|
|
|
UNSIGNED_SHORT_5_6_5 = GL.GL_UNSIGNED_SHORT_5_6_5;
|
|
UNSIGNED_SHORT_4_4_4_4 = GL.GL_UNSIGNED_SHORT_4_4_4_4;
|
|
UNSIGNED_SHORT_5_5_5_1 = GL.GL_UNSIGNED_SHORT_5_5_5_1;
|
|
|
|
RGBA4 = GL.GL_RGBA4;
|
|
RGB5_A1 = GL.GL_RGB5_A1;
|
|
RGB565 = GL.GL_RGB565;
|
|
RGB8 = GL.GL_RGB8;
|
|
RGBA8 = GL.GL_RGBA8;
|
|
ALPHA8 = GL.GL_ALPHA8;
|
|
|
|
READ_ONLY = GL2ES3.GL_READ_ONLY;
|
|
WRITE_ONLY = GL.GL_WRITE_ONLY;
|
|
READ_WRITE = GL2ES3.GL_READ_WRITE;
|
|
|
|
TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO;
|
|
TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD;
|
|
TESS_EDGE_FLAG = GLU.GLU_TESS_EDGE_FLAG;
|
|
|
|
GENERATE_MIPMAP_HINT = GL.GL_GENERATE_MIPMAP_HINT;
|
|
FASTEST = GL.GL_FASTEST;
|
|
NICEST = GL.GL_NICEST;
|
|
DONT_CARE = GL.GL_DONT_CARE;
|
|
|
|
VENDOR = GL.GL_VENDOR;
|
|
RENDERER = GL.GL_RENDERER;
|
|
VERSION = GL.GL_VERSION;
|
|
EXTENSIONS = GL.GL_EXTENSIONS;
|
|
SHADING_LANGUAGE_VERSION = GL2ES2.GL_SHADING_LANGUAGE_VERSION;
|
|
|
|
MAX_SAMPLES = GL.GL_MAX_SAMPLES;
|
|
SAMPLES = GL.GL_SAMPLES;
|
|
|
|
ALIASED_LINE_WIDTH_RANGE = GL.GL_ALIASED_LINE_WIDTH_RANGE;
|
|
ALIASED_POINT_SIZE_RANGE = GL.GL_ALIASED_POINT_SIZE_RANGE;
|
|
|
|
DEPTH_BITS = GL.GL_DEPTH_BITS;
|
|
STENCIL_BITS = GL.GL_STENCIL_BITS;
|
|
|
|
CCW = GL.GL_CCW;
|
|
CW = GL.GL_CW;
|
|
|
|
VIEWPORT = GL.GL_VIEWPORT;
|
|
|
|
ARRAY_BUFFER = GL.GL_ARRAY_BUFFER;
|
|
ELEMENT_ARRAY_BUFFER = GL.GL_ELEMENT_ARRAY_BUFFER;
|
|
PIXEL_PACK_BUFFER = GL2ES3.GL_PIXEL_PACK_BUFFER;
|
|
|
|
MAX_VERTEX_ATTRIBS = GL2ES2.GL_MAX_VERTEX_ATTRIBS;
|
|
|
|
STATIC_DRAW = GL.GL_STATIC_DRAW;
|
|
DYNAMIC_DRAW = GL.GL_DYNAMIC_DRAW;
|
|
STREAM_DRAW = GL2ES2.GL_STREAM_DRAW;
|
|
STREAM_READ = GL2ES3.GL_STREAM_READ;
|
|
|
|
BUFFER_SIZE = GL.GL_BUFFER_SIZE;
|
|
BUFFER_USAGE = GL.GL_BUFFER_USAGE;
|
|
|
|
POINTS = GL.GL_POINTS;
|
|
LINE_STRIP = GL.GL_LINE_STRIP;
|
|
LINE_LOOP = GL.GL_LINE_LOOP;
|
|
LINES = GL.GL_LINES;
|
|
TRIANGLE_FAN = GL.GL_TRIANGLE_FAN;
|
|
TRIANGLE_STRIP = GL.GL_TRIANGLE_STRIP;
|
|
TRIANGLES = GL.GL_TRIANGLES;
|
|
|
|
CULL_FACE = GL.GL_CULL_FACE;
|
|
FRONT = GL.GL_FRONT;
|
|
BACK = GL.GL_BACK;
|
|
FRONT_AND_BACK = GL.GL_FRONT_AND_BACK;
|
|
|
|
POLYGON_OFFSET_FILL = GL.GL_POLYGON_OFFSET_FILL;
|
|
|
|
UNPACK_ALIGNMENT = GL.GL_UNPACK_ALIGNMENT;
|
|
PACK_ALIGNMENT = GL.GL_PACK_ALIGNMENT;
|
|
|
|
TEXTURE_2D = GL.GL_TEXTURE_2D;
|
|
TEXTURE_RECTANGLE = GL2GL3.GL_TEXTURE_RECTANGLE;
|
|
|
|
TEXTURE_BINDING_2D = GL.GL_TEXTURE_BINDING_2D;
|
|
TEXTURE_BINDING_RECTANGLE = GL2GL3.GL_TEXTURE_BINDING_RECTANGLE;
|
|
|
|
MAX_TEXTURE_SIZE = GL.GL_MAX_TEXTURE_SIZE;
|
|
TEXTURE_MAX_ANISOTROPY = GL.GL_TEXTURE_MAX_ANISOTROPY_EXT;
|
|
MAX_TEXTURE_MAX_ANISOTROPY = GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT;
|
|
|
|
MAX_VERTEX_TEXTURE_IMAGE_UNITS = GL2ES2.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
|
|
MAX_TEXTURE_IMAGE_UNITS = GL2ES2.GL_MAX_TEXTURE_IMAGE_UNITS;
|
|
MAX_COMBINED_TEXTURE_IMAGE_UNITS = GL2ES2.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
|
|
|
|
NUM_COMPRESSED_TEXTURE_FORMATS = GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS;
|
|
COMPRESSED_TEXTURE_FORMATS = GL.GL_COMPRESSED_TEXTURE_FORMATS;
|
|
|
|
NEAREST = GL.GL_NEAREST;
|
|
LINEAR = GL.GL_LINEAR;
|
|
LINEAR_MIPMAP_NEAREST = GL.GL_LINEAR_MIPMAP_NEAREST;
|
|
LINEAR_MIPMAP_LINEAR = GL.GL_LINEAR_MIPMAP_LINEAR;
|
|
|
|
CLAMP_TO_EDGE = GL.GL_CLAMP_TO_EDGE;
|
|
REPEAT = GL.GL_REPEAT;
|
|
|
|
TEXTURE0 = GL.GL_TEXTURE0;
|
|
TEXTURE1 = GL.GL_TEXTURE1;
|
|
TEXTURE2 = GL.GL_TEXTURE2;
|
|
TEXTURE3 = GL.GL_TEXTURE3;
|
|
TEXTURE_MIN_FILTER = GL.GL_TEXTURE_MIN_FILTER;
|
|
TEXTURE_MAG_FILTER = GL.GL_TEXTURE_MAG_FILTER;
|
|
TEXTURE_WRAP_S = GL.GL_TEXTURE_WRAP_S;
|
|
TEXTURE_WRAP_T = GL.GL_TEXTURE_WRAP_T;
|
|
TEXTURE_WRAP_R = GL2ES2.GL_TEXTURE_WRAP_R;
|
|
|
|
TEXTURE_CUBE_MAP = GL.GL_TEXTURE_CUBE_MAP;
|
|
TEXTURE_CUBE_MAP_POSITIVE_X = GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
TEXTURE_CUBE_MAP_POSITIVE_Y = GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
|
|
TEXTURE_CUBE_MAP_POSITIVE_Z = GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
|
|
TEXTURE_CUBE_MAP_NEGATIVE_X = GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
|
|
TEXTURE_CUBE_MAP_NEGATIVE_Y = GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
|
|
TEXTURE_CUBE_MAP_NEGATIVE_Z = GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
|
|
|
VERTEX_SHADER = GL2ES2.GL_VERTEX_SHADER;
|
|
FRAGMENT_SHADER = GL2ES2.GL_FRAGMENT_SHADER;
|
|
INFO_LOG_LENGTH = GL2ES2.GL_INFO_LOG_LENGTH;
|
|
SHADER_SOURCE_LENGTH = GL2ES2.GL_SHADER_SOURCE_LENGTH;
|
|
COMPILE_STATUS = GL2ES2.GL_COMPILE_STATUS;
|
|
LINK_STATUS = GL2ES2.GL_LINK_STATUS;
|
|
VALIDATE_STATUS = GL2ES2.GL_VALIDATE_STATUS;
|
|
SHADER_TYPE = GL2ES2.GL_SHADER_TYPE;
|
|
DELETE_STATUS = GL2ES2.GL_DELETE_STATUS;
|
|
|
|
FLOAT_VEC2 = GL2ES2.GL_FLOAT_VEC2;
|
|
FLOAT_VEC3 = GL2ES2.GL_FLOAT_VEC3;
|
|
FLOAT_VEC4 = GL2ES2.GL_FLOAT_VEC4;
|
|
FLOAT_MAT2 = GL2ES2.GL_FLOAT_MAT2;
|
|
FLOAT_MAT3 = GL2ES2.GL_FLOAT_MAT3;
|
|
FLOAT_MAT4 = GL2ES2.GL_FLOAT_MAT4;
|
|
INT_VEC2 = GL2ES2.GL_INT_VEC2;
|
|
INT_VEC3 = GL2ES2.GL_INT_VEC3;
|
|
INT_VEC4 = GL2ES2.GL_INT_VEC4;
|
|
BOOL_VEC2 = GL2ES2.GL_BOOL_VEC2;
|
|
BOOL_VEC3 = GL2ES2.GL_BOOL_VEC3;
|
|
BOOL_VEC4 = GL2ES2.GL_BOOL_VEC4;
|
|
SAMPLER_2D = GL2ES2.GL_SAMPLER_2D;
|
|
SAMPLER_CUBE = GL2ES2.GL_SAMPLER_CUBE;
|
|
|
|
LOW_FLOAT = GL2ES2.GL_LOW_FLOAT;
|
|
MEDIUM_FLOAT = GL2ES2.GL_MEDIUM_FLOAT;
|
|
HIGH_FLOAT = GL2ES2.GL_HIGH_FLOAT;
|
|
LOW_INT = GL2ES2.GL_LOW_INT;
|
|
MEDIUM_INT = GL2ES2.GL_MEDIUM_INT;
|
|
HIGH_INT = GL2ES2.GL_HIGH_INT;
|
|
|
|
CURRENT_VERTEX_ATTRIB = GL2ES2.GL_CURRENT_VERTEX_ATTRIB;
|
|
|
|
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING;
|
|
VERTEX_ATTRIB_ARRAY_ENABLED = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_ENABLED;
|
|
VERTEX_ATTRIB_ARRAY_SIZE = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_SIZE;
|
|
VERTEX_ATTRIB_ARRAY_STRIDE = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_STRIDE;
|
|
VERTEX_ATTRIB_ARRAY_TYPE = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_TYPE;
|
|
VERTEX_ATTRIB_ARRAY_NORMALIZED = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_NORMALIZED;
|
|
VERTEX_ATTRIB_ARRAY_POINTER = GL2ES2.GL_VERTEX_ATTRIB_ARRAY_POINTER;
|
|
|
|
BLEND = GL.GL_BLEND;
|
|
ONE = GL.GL_ONE;
|
|
ZERO = GL.GL_ZERO;
|
|
SRC_ALPHA = GL.GL_SRC_ALPHA;
|
|
DST_ALPHA = GL.GL_DST_ALPHA;
|
|
ONE_MINUS_SRC_ALPHA = GL.GL_ONE_MINUS_SRC_ALPHA;
|
|
ONE_MINUS_DST_COLOR = GL.GL_ONE_MINUS_DST_COLOR;
|
|
ONE_MINUS_SRC_COLOR = GL.GL_ONE_MINUS_SRC_COLOR;
|
|
DST_COLOR = GL.GL_DST_COLOR;
|
|
SRC_COLOR = GL.GL_SRC_COLOR;
|
|
|
|
SAMPLE_ALPHA_TO_COVERAGE = GL.GL_SAMPLE_ALPHA_TO_COVERAGE;
|
|
SAMPLE_COVERAGE = GL.GL_SAMPLE_COVERAGE;
|
|
|
|
KEEP = GL.GL_KEEP;
|
|
REPLACE = GL.GL_REPLACE;
|
|
INCR = GL.GL_INCR;
|
|
DECR = GL.GL_DECR;
|
|
INVERT = GL.GL_INVERT;
|
|
INCR_WRAP = GL.GL_INCR_WRAP;
|
|
DECR_WRAP = GL.GL_DECR_WRAP;
|
|
NEVER = GL.GL_NEVER;
|
|
ALWAYS = GL.GL_ALWAYS;
|
|
|
|
EQUAL = GL.GL_EQUAL;
|
|
LESS = GL.GL_LESS;
|
|
LEQUAL = GL.GL_LEQUAL;
|
|
GREATER = GL.GL_GREATER;
|
|
GEQUAL = GL.GL_GEQUAL;
|
|
NOTEQUAL = GL.GL_NOTEQUAL;
|
|
|
|
FUNC_ADD = GL.GL_FUNC_ADD;
|
|
FUNC_MIN = GL2ES3.GL_MIN;
|
|
FUNC_MAX = GL2ES3.GL_MAX;
|
|
FUNC_REVERSE_SUBTRACT = GL.GL_FUNC_REVERSE_SUBTRACT;
|
|
FUNC_SUBTRACT = GL.GL_FUNC_SUBTRACT;
|
|
|
|
DITHER = GL.GL_DITHER;
|
|
|
|
CONSTANT_COLOR = GL2ES2.GL_CONSTANT_COLOR;
|
|
CONSTANT_ALPHA = GL2ES2.GL_CONSTANT_ALPHA;
|
|
ONE_MINUS_CONSTANT_COLOR = GL2ES2.GL_ONE_MINUS_CONSTANT_COLOR;
|
|
ONE_MINUS_CONSTANT_ALPHA = GL2ES2.GL_ONE_MINUS_CONSTANT_ALPHA;
|
|
SRC_ALPHA_SATURATE = GL.GL_SRC_ALPHA_SATURATE;
|
|
|
|
SCISSOR_TEST = GL.GL_SCISSOR_TEST;
|
|
STENCIL_TEST = GL.GL_STENCIL_TEST;
|
|
DEPTH_TEST = GL.GL_DEPTH_TEST;
|
|
DEPTH_WRITEMASK = GL.GL_DEPTH_WRITEMASK;
|
|
|
|
COLOR_BUFFER_BIT = GL.GL_COLOR_BUFFER_BIT;
|
|
DEPTH_BUFFER_BIT = GL.GL_DEPTH_BUFFER_BIT;
|
|
STENCIL_BUFFER_BIT = GL.GL_STENCIL_BUFFER_BIT;
|
|
|
|
FRAMEBUFFER = GL.GL_FRAMEBUFFER;
|
|
COLOR_ATTACHMENT0 = GL.GL_COLOR_ATTACHMENT0;
|
|
COLOR_ATTACHMENT1 = GL2ES2.GL_COLOR_ATTACHMENT1;
|
|
COLOR_ATTACHMENT2 = GL2ES2.GL_COLOR_ATTACHMENT2;
|
|
COLOR_ATTACHMENT3 = GL2ES2.GL_COLOR_ATTACHMENT3;
|
|
RENDERBUFFER = GL.GL_RENDERBUFFER;
|
|
DEPTH_ATTACHMENT = GL.GL_DEPTH_ATTACHMENT;
|
|
STENCIL_ATTACHMENT = GL.GL_STENCIL_ATTACHMENT;
|
|
READ_FRAMEBUFFER = GL.GL_READ_FRAMEBUFFER;
|
|
DRAW_FRAMEBUFFER = GL.GL_DRAW_FRAMEBUFFER;
|
|
|
|
RGBA8 = GL.GL_RGBA8;
|
|
DEPTH24_STENCIL8 = GL.GL_DEPTH24_STENCIL8;
|
|
|
|
DEPTH_COMPONENT = GL2ES2.GL_DEPTH_COMPONENT;
|
|
DEPTH_COMPONENT16 = GL.GL_DEPTH_COMPONENT16;
|
|
DEPTH_COMPONENT24 = GL.GL_DEPTH_COMPONENT24;
|
|
DEPTH_COMPONENT32 = GL.GL_DEPTH_COMPONENT32;
|
|
|
|
STENCIL_INDEX = GL2ES2.GL_STENCIL_INDEX;
|
|
STENCIL_INDEX1 = GL.GL_STENCIL_INDEX1;
|
|
STENCIL_INDEX4 = GL.GL_STENCIL_INDEX4;
|
|
STENCIL_INDEX8 = GL.GL_STENCIL_INDEX8;
|
|
|
|
DEPTH_STENCIL = GL.GL_DEPTH_STENCIL;
|
|
|
|
FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE;
|
|
FRAMEBUFFER_UNDEFINED = GL2ES3.GL_FRAMEBUFFER_UNDEFINED;
|
|
FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
|
FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
|
|
FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
|
|
FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS;
|
|
FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER;
|
|
FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER;
|
|
FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED;
|
|
FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
|
FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = GL3ES3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
|
|
|
|
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE;
|
|
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME;
|
|
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = GL.GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL;
|
|
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = GL.GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE;
|
|
|
|
RENDERBUFFER_WIDTH = GL.GL_RENDERBUFFER_WIDTH;
|
|
RENDERBUFFER_HEIGHT = GL.GL_RENDERBUFFER_HEIGHT;
|
|
RENDERBUFFER_RED_SIZE = GL.GL_RENDERBUFFER_RED_SIZE;
|
|
RENDERBUFFER_GREEN_SIZE = GL.GL_RENDERBUFFER_GREEN_SIZE;
|
|
RENDERBUFFER_BLUE_SIZE = GL.GL_RENDERBUFFER_BLUE_SIZE;
|
|
RENDERBUFFER_ALPHA_SIZE = GL.GL_RENDERBUFFER_ALPHA_SIZE;
|
|
RENDERBUFFER_DEPTH_SIZE = GL.GL_RENDERBUFFER_DEPTH_SIZE;
|
|
RENDERBUFFER_STENCIL_SIZE = GL.GL_RENDERBUFFER_STENCIL_SIZE;
|
|
RENDERBUFFER_INTERNAL_FORMAT = GL.GL_RENDERBUFFER_INTERNAL_FORMAT;
|
|
|
|
MULTISAMPLE = GL.GL_MULTISAMPLE;
|
|
LINE_SMOOTH = GL.GL_LINE_SMOOTH;
|
|
POLYGON_SMOOTH = GL2GL3.GL_POLYGON_SMOOTH;
|
|
|
|
SYNC_GPU_COMMANDS_COMPLETE = GL3ES3.GL_SYNC_GPU_COMMANDS_COMPLETE;
|
|
ALREADY_SIGNALED = GL3ES3.GL_ALREADY_SIGNALED;
|
|
CONDITION_SATISFIED = GL3ES3.GL_CONDITION_SATISFIED;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Special Functions
|
|
|
|
@Override
|
|
public void flush() {
|
|
gl.glFlush();
|
|
}
|
|
|
|
@Override
|
|
public void finish() {
|
|
gl.glFinish();
|
|
}
|
|
|
|
@Override
|
|
public void hint(int target, int hint) {
|
|
gl.glHint(target, hint);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// State and State Requests
|
|
|
|
@Override
|
|
public void enable(int value) {
|
|
if (-1 < value) {
|
|
gl.glEnable(value);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void disable(int value) {
|
|
if (-1 < value) {
|
|
gl.glDisable(value);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void getBooleanv(int value, IntBuffer data) {
|
|
if (-1 < value) {
|
|
if (byteBuffer.capacity() < data.capacity()) {
|
|
byteBuffer = allocateDirectByteBuffer(data.capacity());
|
|
}
|
|
gl.glGetBooleanv(value, byteBuffer);
|
|
for (int i = 0; i < data.capacity(); i++) {
|
|
data.put(i, byteBuffer.get(i));
|
|
}
|
|
} else {
|
|
fillIntBuffer(data, 0, data.capacity() - 1, 0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void getIntegerv(int value, IntBuffer data) {
|
|
if (-1 < value) {
|
|
gl.glGetIntegerv(value, data);
|
|
} else {
|
|
fillIntBuffer(data, 0, data.capacity() - 1, 0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void getFloatv(int value, FloatBuffer data) {
|
|
if (-1 < value) {
|
|
gl.glGetFloatv(value, data);
|
|
} else {
|
|
fillFloatBuffer(data, 0, data.capacity() - 1, 0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isEnabled(int value) {
|
|
return gl.glIsEnabled(value);
|
|
}
|
|
|
|
@Override
|
|
public String getString(int name) {
|
|
return gl.glGetString(name);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Error Handling
|
|
|
|
@Override
|
|
public int getError() {
|
|
return gl.glGetError();
|
|
}
|
|
|
|
@Override
|
|
public String errorString(int err) {
|
|
return glu.gluErrorString(err);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Buffer Objects
|
|
|
|
@Override
|
|
public void genBuffers(int n, IntBuffer buffers) {
|
|
gl.glGenBuffers(n, buffers);
|
|
}
|
|
|
|
@Override
|
|
public void deleteBuffers(int n, IntBuffer buffers) {
|
|
gl.glDeleteBuffers(n, buffers);
|
|
}
|
|
|
|
@Override
|
|
public void bindBuffer(int target, int buffer) {
|
|
gl.glBindBuffer(target, buffer);
|
|
}
|
|
|
|
@Override
|
|
public void bufferData(int target, int size, Buffer data, int usage) {
|
|
gl.glBufferData(target, size, data, usage);
|
|
}
|
|
|
|
@Override
|
|
public void bufferSubData(int target, int offset, int size, Buffer data) {
|
|
gl.glBufferSubData(target, offset, size, data);
|
|
}
|
|
|
|
@Override
|
|
public void isBuffer(int buffer) {
|
|
gl.glIsBuffer(buffer);
|
|
}
|
|
|
|
@Override
|
|
public void getBufferParameteriv(int target, int value, IntBuffer data) {
|
|
gl.glGetBufferParameteriv(target, value, data);
|
|
}
|
|
|
|
@Override
|
|
public ByteBuffer mapBuffer(int target, int access) {
|
|
return gl2.glMapBuffer(target, access);
|
|
}
|
|
|
|
@Override
|
|
public ByteBuffer mapBufferRange(int target, int offset, int length, int access) {
|
|
if (gl2x != null) {
|
|
return gl2x.glMapBufferRange(target, offset, length, access);
|
|
} else if (gl3 != null) {
|
|
return gl3.glMapBufferRange(target, offset, length, access);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glMapBufferRange()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void unmapBuffer(int target) {
|
|
gl2.glUnmapBuffer(target);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Synchronization
|
|
|
|
@Override
|
|
public long fenceSync(int condition, int flags) {
|
|
if (gl3es3 != null) {
|
|
return gl3es3.glFenceSync(condition, flags);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "fenceSync()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void deleteSync(long sync) {
|
|
if (gl3es3 != null) {
|
|
gl3es3.glDeleteSync(sync);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "deleteSync()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int clientWaitSync(long sync, int flags, long timeout) {
|
|
if (gl3es3 != null) {
|
|
return gl3es3.glClientWaitSync(sync, flags, timeout);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "clientWaitSync()"));
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Viewport and Clipping
|
|
|
|
@Override
|
|
public void depthRangef(float n, float f) {
|
|
gl.glDepthRangef(n, f);
|
|
}
|
|
|
|
@Override
|
|
public void viewport(int x, int y, int w, int h) {
|
|
float scale = getPixelScale();
|
|
viewportImpl((int)scale * x, (int)(scale * y), (int)(scale * w), (int)(scale * h));
|
|
}
|
|
|
|
@Override
|
|
protected void viewportImpl(int x, int y, int w, int h) {
|
|
gl.glViewport(x, y, w, h);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Reading Pixels
|
|
|
|
@Override
|
|
protected void readPixelsImpl(int x, int y, int width, int height, int format, int type, Buffer buffer) {
|
|
gl.glReadPixels(x, y, width, height, format, type, buffer);
|
|
}
|
|
|
|
@Override
|
|
protected void readPixelsImpl(int x, int y, int width, int height, int format, int type, long offset) {
|
|
gl.glReadPixels(x, y, width, height, format, type, 0);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Vertices
|
|
|
|
@Override
|
|
public void vertexAttrib1f(int index, float value) {
|
|
gl2.glVertexAttrib1f(index, value);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib2f(int index, float value0, float value1) {
|
|
gl2.glVertexAttrib2f(index, value0, value1);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib3f(int index, float value0, float value1, float value2) {
|
|
gl2.glVertexAttrib3f(index, value0, value1, value2);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib4f(int index, float value0, float value1, float value2, float value3) {
|
|
gl2.glVertexAttrib4f(index, value0, value1, value2, value3);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib1fv(int index, FloatBuffer values) {
|
|
gl2.glVertexAttrib1fv(index, values);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib2fv(int index, FloatBuffer values) {
|
|
gl2.glVertexAttrib2fv(index, values);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib3fv(int index, FloatBuffer values) {
|
|
gl2.glVertexAttrib3fv(index, values);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttrib4fv(int index, FloatBuffer values) {
|
|
gl2.glVertexAttrib4fv(index, values);
|
|
}
|
|
|
|
@Override
|
|
public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, int offset) {
|
|
gl2.glVertexAttribPointer(index, size, type, normalized, stride, offset);
|
|
}
|
|
|
|
@Override
|
|
public void enableVertexAttribArray(int index) {
|
|
gl2.glEnableVertexAttribArray(index);
|
|
}
|
|
|
|
@Override
|
|
public void disableVertexAttribArray(int index) {
|
|
gl2.glDisableVertexAttribArray(index);
|
|
}
|
|
|
|
@Override
|
|
public void drawArraysImpl(int mode, int first, int count) {
|
|
gl.glDrawArrays(mode, first, count);
|
|
}
|
|
|
|
@Override
|
|
public void drawElementsImpl(int mode, int count, int type, int offset) {
|
|
gl.glDrawElements(mode, count, type, offset);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Rasterization
|
|
|
|
@Override
|
|
public void lineWidth(float width) {
|
|
gl.glLineWidth(width);
|
|
}
|
|
|
|
@Override
|
|
public void frontFace(int dir) {
|
|
gl.glFrontFace(dir);
|
|
}
|
|
|
|
@Override
|
|
public void cullFace(int mode) {
|
|
gl.glCullFace(mode);
|
|
}
|
|
|
|
@Override
|
|
public void polygonOffset(float factor, float units) {
|
|
gl.glPolygonOffset(factor, units);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Pixel Rectangles
|
|
|
|
@Override
|
|
public void pixelStorei(int pname, int param) {
|
|
gl.glPixelStorei(pname, param);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Texturing
|
|
|
|
@Override
|
|
public void texImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer data) {
|
|
gl.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
|
|
}
|
|
|
|
@Override
|
|
public void copyTexImage2D(int target, int level, int internalFormat, int x, int y, int width, int height, int border) {
|
|
gl.glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
|
|
}
|
|
|
|
@Override
|
|
public void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, Buffer data) {
|
|
gl.glTexSubImage2D(target, level, xOffset, yOffset, width, height, format, type, data);
|
|
}
|
|
|
|
@Override
|
|
public void copyTexSubImage2D(int target, int level, int xOffset, int yOffset, int x, int y, int width, int height) {
|
|
gl.glCopyTexSubImage2D(target, level, x, y, xOffset, yOffset, width, height);
|
|
}
|
|
|
|
@Override
|
|
public void compressedTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int imageSize, Buffer data) {
|
|
gl.glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data);
|
|
}
|
|
|
|
@Override
|
|
public void compressedTexSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int imageSize, Buffer data) {
|
|
gl.glCompressedTexSubImage2D(target, level, xOffset, yOffset, width, height, format, imageSize, data);
|
|
}
|
|
|
|
@Override
|
|
public void texParameteri(int target, int pname, int param) {
|
|
gl.glTexParameteri(target, pname, param);
|
|
}
|
|
|
|
@Override
|
|
public void texParameterf(int target, int pname, float param) {
|
|
gl.glTexParameterf(target, pname, param);
|
|
}
|
|
|
|
@Override
|
|
public void texParameteriv(int target, int pname, IntBuffer params) {
|
|
gl.glTexParameteriv(target, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void texParameterfv(int target, int pname, FloatBuffer params) {
|
|
gl.glTexParameterfv(target, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void generateMipmap(int target) {
|
|
gl.glGenerateMipmap(target);
|
|
}
|
|
|
|
@Override
|
|
public void genTextures(int n, IntBuffer textures) {
|
|
gl.glGenTextures(n, textures);
|
|
}
|
|
|
|
@Override
|
|
public void deleteTextures(int n, IntBuffer textures) {
|
|
gl.glDeleteTextures(n, textures);
|
|
}
|
|
|
|
@Override
|
|
public void getTexParameteriv(int target, int pname, IntBuffer params) {
|
|
gl.glGetTexParameteriv(target, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void getTexParameterfv(int target, int pname, FloatBuffer params) {
|
|
gl.glGetTexParameterfv(target, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public boolean isTexture(int texture) {
|
|
return gl.glIsTexture(texture);
|
|
}
|
|
|
|
@Override
|
|
protected void activeTextureImpl(int texture) {
|
|
gl.glActiveTexture(texture);
|
|
}
|
|
|
|
@Override
|
|
protected void bindTextureImpl(int target, int texture) {
|
|
gl.glBindTexture(target, texture);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Shaders and Programs
|
|
|
|
@Override
|
|
public int createShader(int type) {
|
|
return gl2.glCreateShader(type);
|
|
}
|
|
|
|
@Override
|
|
public void shaderSource(int shader, String source) {
|
|
gl2.glShaderSource(shader, 1, new String[] { source }, (int[]) null, 0);
|
|
}
|
|
|
|
@Override
|
|
public void compileShader(int shader) {
|
|
gl2.glCompileShader(shader);
|
|
}
|
|
|
|
@Override
|
|
public void releaseShaderCompiler() {
|
|
gl2.glReleaseShaderCompiler();
|
|
}
|
|
|
|
@Override
|
|
public void deleteShader(int shader) {
|
|
gl2.glDeleteShader(shader);
|
|
}
|
|
|
|
@Override
|
|
public void shaderBinary(int count, IntBuffer shaders, int binaryFormat, Buffer binary, int length) {
|
|
gl2.glShaderBinary(count, shaders, binaryFormat, binary, length);
|
|
}
|
|
|
|
@Override
|
|
public int createProgram() {
|
|
return gl2.glCreateProgram();
|
|
}
|
|
|
|
@Override
|
|
public void attachShader(int program, int shader) {
|
|
gl2.glAttachShader(program, shader);
|
|
}
|
|
|
|
@Override
|
|
public void detachShader(int program, int shader) {
|
|
gl2.glDetachShader(program, shader);
|
|
}
|
|
|
|
@Override
|
|
public void linkProgram(int program) {
|
|
gl2.glLinkProgram(program);
|
|
}
|
|
|
|
@Override
|
|
public void useProgram(int program) {
|
|
gl2.glUseProgram(program);
|
|
}
|
|
|
|
@Override
|
|
public void deleteProgram(int program) {
|
|
gl2.glDeleteProgram(program);
|
|
}
|
|
|
|
@Override
|
|
public String getActiveAttrib(int program, int index, IntBuffer size, IntBuffer type) {
|
|
int[] tmp = {0, 0, 0};
|
|
byte[] namebuf = new byte[1024];
|
|
gl2.glGetActiveAttrib(program, index, 1024, tmp, 0, tmp, 1, tmp, 2, namebuf, 0);
|
|
size.put(tmp[1]);
|
|
type.put(tmp[2]);
|
|
String name = new String(namebuf, 0, tmp[0]);
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public int getAttribLocation(int program, String name) {
|
|
return gl2.glGetAttribLocation(program, name);
|
|
}
|
|
|
|
@Override
|
|
public void bindAttribLocation(int program, int index, String name) {
|
|
gl2.glBindAttribLocation(program, index, name);
|
|
}
|
|
|
|
@Override
|
|
public int getUniformLocation(int program, String name) {
|
|
return gl2.glGetUniformLocation(program, name);
|
|
}
|
|
|
|
@Override
|
|
public String getActiveUniform(int program, int index, IntBuffer size, IntBuffer type) {
|
|
int[] tmp= {0, 0, 0};
|
|
byte[] namebuf = new byte[1024];
|
|
gl2.glGetActiveUniform(program, index, 1024, tmp, 0, tmp, 1, tmp, 2, namebuf, 0);
|
|
size.put(tmp[1]);
|
|
type.put(tmp[2]);
|
|
String name = new String(namebuf, 0, tmp[0]);
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public void uniform1i(int location, int value) {
|
|
gl2.glUniform1i(location, value);
|
|
}
|
|
|
|
@Override
|
|
public void uniform2i(int location, int value0, int value1) {
|
|
gl2.glUniform2i(location, value0, value1);
|
|
}
|
|
|
|
@Override
|
|
public void uniform3i(int location, int value0, int value1, int value2) {
|
|
gl2.glUniform3i(location, value0, value1, value2);
|
|
}
|
|
|
|
@Override
|
|
public void uniform4i(int location, int value0, int value1, int value2, int value3) {
|
|
gl2.glUniform4i(location, value0, value1, value2, value3);
|
|
}
|
|
|
|
@Override
|
|
public void uniform1f(int location, float value) {
|
|
gl2.glUniform1f(location, value);
|
|
}
|
|
|
|
@Override
|
|
public void uniform2f(int location, float value0, float value1) {
|
|
gl2.glUniform2f(location, value0, value1);
|
|
}
|
|
|
|
@Override
|
|
public void uniform3f(int location, float value0, float value1, float value2) {
|
|
gl2.glUniform3f(location, value0, value1, value2);
|
|
}
|
|
|
|
@Override
|
|
public void uniform4f(int location, float value0, float value1, float value2, float value3) {
|
|
gl2.glUniform4f(location, value0, value1, value2, value3);
|
|
}
|
|
|
|
@Override
|
|
public void uniform1iv(int location, int count, IntBuffer v) {
|
|
gl2.glUniform1iv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform2iv(int location, int count, IntBuffer v) {
|
|
gl2.glUniform2iv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform3iv(int location, int count, IntBuffer v) {
|
|
gl2.glUniform3iv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform4iv(int location, int count, IntBuffer v) {
|
|
gl2.glUniform4iv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform1fv(int location, int count, FloatBuffer v) {
|
|
gl2.glUniform1fv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform2fv(int location, int count, FloatBuffer v) {
|
|
gl2.glUniform2fv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform3fv(int location, int count, FloatBuffer v) {
|
|
gl2.glUniform3fv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniform4fv(int location, int count, FloatBuffer v) {
|
|
gl2.glUniform4fv(location, count, v);
|
|
}
|
|
|
|
@Override
|
|
public void uniformMatrix2fv(int location, int count, boolean transpose, FloatBuffer mat) {
|
|
gl2.glUniformMatrix2fv(location, count, transpose, mat);
|
|
}
|
|
|
|
@Override
|
|
public void uniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer mat) {
|
|
gl2.glUniformMatrix3fv(location, count, transpose, mat);
|
|
}
|
|
|
|
@Override
|
|
public void uniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer mat) {
|
|
gl2.glUniformMatrix4fv(location, count, transpose, mat);
|
|
}
|
|
|
|
@Override
|
|
public void validateProgram(int program) {
|
|
gl2.glValidateProgram(program);
|
|
}
|
|
|
|
@Override
|
|
public boolean isShader(int shader) {
|
|
return gl2.glIsShader(shader);
|
|
}
|
|
|
|
@Override
|
|
public void getShaderiv(int shader, int pname, IntBuffer params) {
|
|
gl2.glGetShaderiv(shader, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void getAttachedShaders(int program, int maxCount, IntBuffer count, IntBuffer shaders) {
|
|
gl2.glGetAttachedShaders(program, maxCount, count, shaders);
|
|
}
|
|
|
|
@Override
|
|
public String getShaderInfoLog(int shader) {
|
|
int[] val = { 0 };
|
|
gl2.glGetShaderiv(shader, GL2ES2.GL_INFO_LOG_LENGTH, val, 0);
|
|
int length = val[0];
|
|
|
|
byte[] log = new byte[length];
|
|
gl2.glGetShaderInfoLog(shader, length, val, 0, log, 0);
|
|
return new String(log);
|
|
}
|
|
|
|
@Override
|
|
public String getShaderSource(int shader) {
|
|
int[] len = {0};
|
|
byte[] buf = new byte[1024];
|
|
gl2.glGetShaderSource(shader, 1024, len, 0, buf, 0);
|
|
return new String(buf, 0, len[0]);
|
|
}
|
|
|
|
@Override
|
|
public void getShaderPrecisionFormat(int shaderType, int precisionType, IntBuffer range, IntBuffer precision) {
|
|
gl2.glGetShaderPrecisionFormat(shaderType, precisionType, range, precision);
|
|
}
|
|
|
|
@Override
|
|
public void getVertexAttribfv(int index, int pname, FloatBuffer params) {
|
|
gl2.glGetVertexAttribfv(index, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void getVertexAttribiv(int index, int pname, IntBuffer params) {
|
|
gl2.glGetVertexAttribiv(index, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void getVertexAttribPointerv(int index, int pname, ByteBuffer data) {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glGetVertexAttribPointerv()"));
|
|
}
|
|
|
|
@Override
|
|
public void getUniformfv(int program, int location, FloatBuffer params) {
|
|
gl2.glGetUniformfv(program, location, params);
|
|
}
|
|
|
|
@Override
|
|
public void getUniformiv(int program, int location, IntBuffer params) {
|
|
gl2.glGetUniformiv(program, location, params);
|
|
}
|
|
|
|
@Override
|
|
public boolean isProgram(int program) {
|
|
return gl2.glIsProgram(program);
|
|
}
|
|
|
|
@Override
|
|
public void getProgramiv(int program, int pname, IntBuffer params) {
|
|
gl2.glGetProgramiv(program, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public String getProgramInfoLog(int program) {
|
|
int[] val = { 0 };
|
|
gl2.glGetProgramiv(program, GL2ES2.GL_INFO_LOG_LENGTH, val, 0);
|
|
int length = val[0];
|
|
|
|
if (0 < length) {
|
|
byte[] log = new byte[length];
|
|
gl2.glGetProgramInfoLog(program, length, val, 0, log, 0);
|
|
return new String(log);
|
|
} else {
|
|
return "Unknown error";
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Per-Fragment Operations
|
|
|
|
@Override
|
|
public void scissor(int x, int y, int w, int h) {
|
|
float scale = getPixelScale();
|
|
gl.glScissor((int)scale * x, (int)(scale * y), (int)(scale * w), (int)(scale * h));
|
|
// gl.glScissor(x, y, w, h);
|
|
}
|
|
|
|
@Override
|
|
public void sampleCoverage(float value, boolean invert) {
|
|
gl2.glSampleCoverage(value, invert);
|
|
}
|
|
|
|
@Override
|
|
public void stencilFunc(int func, int ref, int mask) {
|
|
gl2.glStencilFunc(func, ref, mask);
|
|
}
|
|
|
|
@Override
|
|
public void stencilFuncSeparate(int face, int func, int ref, int mask) {
|
|
gl2.glStencilFuncSeparate(face, func, ref, mask);
|
|
}
|
|
|
|
@Override
|
|
public void stencilOp(int sfail, int dpfail, int dppass) {
|
|
gl2.glStencilOp(sfail, dpfail, dppass);
|
|
}
|
|
|
|
@Override
|
|
public void stencilOpSeparate(int face, int sfail, int dpfail, int dppass) {
|
|
gl2.glStencilOpSeparate(face, sfail, dpfail, dppass);
|
|
}
|
|
|
|
@Override
|
|
public void depthFunc(int func) {
|
|
gl.glDepthFunc(func);
|
|
}
|
|
|
|
@Override
|
|
public void blendEquation(int mode) {
|
|
gl.glBlendEquation(mode);
|
|
}
|
|
|
|
@Override
|
|
public void blendEquationSeparate(int modeRGB, int modeAlpha) {
|
|
gl.glBlendEquationSeparate(modeRGB, modeAlpha);
|
|
}
|
|
|
|
@Override
|
|
public void blendFunc(int src, int dst) {
|
|
gl.glBlendFunc(src, dst);
|
|
}
|
|
|
|
@Override
|
|
public void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
|
|
gl.glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
|
|
}
|
|
|
|
@Override
|
|
public void blendColor(float red, float green, float blue, float alpha) {
|
|
gl2.glBlendColor(red, green, blue, alpha);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Whole Framebuffer Operations
|
|
|
|
@Override
|
|
public void colorMask(boolean r, boolean g, boolean b, boolean a) {
|
|
gl.glColorMask(r, g, b, a);
|
|
}
|
|
|
|
@Override
|
|
public void depthMask(boolean mask) {
|
|
gl.glDepthMask(mask);
|
|
}
|
|
|
|
@Override
|
|
public void stencilMask(int mask) {
|
|
gl.glStencilMask(mask);
|
|
}
|
|
|
|
@Override
|
|
public void stencilMaskSeparate(int face, int mask) {
|
|
gl2.glStencilMaskSeparate(face, mask);
|
|
}
|
|
|
|
@Override
|
|
public void clearColor(float r, float g, float b, float a) {
|
|
gl.glClearColor(r, g, b, a);
|
|
}
|
|
|
|
@Override
|
|
public void clearDepth(float d) {
|
|
gl.glClearDepth(d);
|
|
}
|
|
|
|
@Override
|
|
public void clearStencil(int s) {
|
|
gl.glClearStencil(s);
|
|
}
|
|
|
|
@Override
|
|
public void clear(int buf) {
|
|
gl.glClear(buf);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Framebuffers Objects
|
|
|
|
@Override
|
|
protected void bindFramebufferImpl(int target, int framebuffer) {
|
|
gl.glBindFramebuffer(target, framebuffer);
|
|
}
|
|
|
|
@Override
|
|
public void deleteFramebuffers(int n, IntBuffer framebuffers) {
|
|
gl.glDeleteFramebuffers(n, framebuffers);
|
|
}
|
|
|
|
@Override
|
|
public void genFramebuffers(int n, IntBuffer framebuffers) {
|
|
gl.glGenFramebuffers(n, framebuffers);
|
|
}
|
|
|
|
@Override
|
|
public void bindRenderbuffer(int target, int renderbuffer) {
|
|
gl.glBindRenderbuffer(target, renderbuffer);
|
|
}
|
|
|
|
@Override
|
|
public void deleteRenderbuffers(int n, IntBuffer renderbuffers) {
|
|
gl.glDeleteRenderbuffers(n, renderbuffers);
|
|
}
|
|
|
|
@Override
|
|
public void genRenderbuffers(int n, IntBuffer renderbuffers) {
|
|
gl.glGenRenderbuffers(n, renderbuffers);
|
|
}
|
|
|
|
@Override
|
|
public void renderbufferStorage(int target, int internalFormat, int width, int height) {
|
|
gl.glRenderbufferStorage(target, internalFormat, width, height);
|
|
}
|
|
|
|
@Override
|
|
public void framebufferRenderbuffer(int target, int attachment, int rendbuferfTarget, int renderbuffer) {
|
|
gl.glFramebufferRenderbuffer(target, attachment, rendbuferfTarget, renderbuffer);
|
|
}
|
|
|
|
@Override
|
|
public void framebufferTexture2D(int target, int attachment, int texTarget, int texture, int level) {
|
|
gl.glFramebufferTexture2D(target, attachment, texTarget, texture, level);
|
|
}
|
|
|
|
@Override
|
|
public int checkFramebufferStatus(int target) {
|
|
return gl.glCheckFramebufferStatus(target);
|
|
}
|
|
|
|
@Override
|
|
public boolean isFramebuffer(int framebuffer) {
|
|
return gl2.glIsFramebuffer(framebuffer);
|
|
}
|
|
|
|
@Override
|
|
public void getFramebufferAttachmentParameteriv(int target, int attachment, int pname, IntBuffer params) {
|
|
gl2.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public boolean isRenderbuffer(int renderbuffer) {
|
|
return gl2.glIsRenderbuffer(renderbuffer);
|
|
}
|
|
|
|
@Override
|
|
public void getRenderbufferParameteriv(int target, int pname, IntBuffer params) {
|
|
gl2.glGetRenderbufferParameteriv(target, pname, params);
|
|
}
|
|
|
|
@Override
|
|
public void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
|
|
if (gl2x != null) {
|
|
gl2x.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
|
} else if (gl3 != null) {
|
|
gl3.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
|
} else if (gl3es3 != null) {
|
|
gl3es3.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glBlitFramebuffer()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void renderbufferStorageMultisample(int target, int samples, int format, int width, int height) {
|
|
if (gl2x != null) {
|
|
gl2x.glRenderbufferStorageMultisample(target, samples, format, width, height);
|
|
} else if (gl3 != null) {
|
|
gl3.glRenderbufferStorageMultisample(target, samples, format, width, height);
|
|
} else if (gl3es3 != null) {
|
|
gl3es3.glRenderbufferStorageMultisample(target, samples, format, width, height);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glRenderbufferStorageMultisample()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void readBuffer(int buf) {
|
|
if (gl2x != null) {
|
|
gl2x.glReadBuffer(buf);
|
|
} else if (gl3 != null) {
|
|
gl3.glReadBuffer(buf);
|
|
} else if (gl3es3 != null) {
|
|
gl3es3.glReadBuffer(buf);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glReadBuffer()"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void drawBuffer(int buf) {
|
|
if (gl2x != null) {
|
|
gl2x.glDrawBuffer(buf);
|
|
} else if (gl3 != null) {
|
|
gl3.glDrawBuffer(buf);
|
|
} else if (gl3es3 != null) {
|
|
IntBuffer intBuffer = IntBuffer.allocate(1);
|
|
intBuffer.put(buf);
|
|
intBuffer.rewind();
|
|
gl3es3.glDrawBuffers(1, intBuffer);
|
|
} else {
|
|
throw new RuntimeException(String.format(MISSING_GLFUNC_ERROR, "glDrawBuffer()"));
|
|
}
|
|
}
|
|
}
|