more refactoring/testing with non-static fields in PGL

This commit is contained in:
codeanticode
2014-01-20 16:48:19 -05:00
parent 9aef0a1426
commit 9110cebd0d
5 changed files with 431 additions and 367 deletions
+21 -21
View File
@@ -174,15 +174,15 @@ public class FrameBuffer implements PConstants {
}
public void clear() {
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
pgl.clearDepth(1);
pgl.clearStencil(0);
pgl.clearColor(0, 0, 0, 0);
pgl.clear(PGL.DEPTH_BUFFER_BIT |
PGL.STENCIL_BUFFER_BIT |
PGL.COLOR_BUFFER_BIT);
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
public void copy(FrameBuffer dest, FrameBuffer current) {
@@ -273,8 +273,8 @@ public class FrameBuffer implements PConstants {
colorBufferTex[i] = textures[i];
}
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
// Making sure nothing is attached.
for (int i = 0; i < numColorBuffers; i++) {
@@ -290,7 +290,7 @@ public class FrameBuffer implements PConstants {
pgl.validateFramebuffer();
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
@@ -302,8 +302,8 @@ public class FrameBuffer implements PConstants {
colorBufferTex[i1] = tmp;
}
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
for (int i = 0; i < numColorBuffers; i++) {
pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i,
colorBufferTex[i].glTarget,
@@ -311,7 +311,7 @@ public class FrameBuffer implements PConstants {
}
pgl.validateFramebuffer();
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
@@ -422,8 +422,8 @@ public class FrameBuffer implements PConstants {
protected void createColorBufferMultisample() {
if (screenFb) return;
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glMultisample = PGraphicsOpenGL.createRenderBufferObject(context, pgl);
pgl.bindRenderbuffer(PGL.RENDERBUFFER, glMultisample);
@@ -432,7 +432,7 @@ public class FrameBuffer implements PConstants {
pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0,
PGL.RENDERBUFFER, glMultisample);
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
@@ -443,8 +443,8 @@ public class FrameBuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glDepthStencil = PGraphicsOpenGL.createRenderBufferObject(context, pgl);
pgl.bindRenderbuffer(PGL.RENDERBUFFER, glDepthStencil);
@@ -462,7 +462,7 @@ public class FrameBuffer implements PConstants {
pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT,
PGL.RENDERBUFFER, glDepthStencil);
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
@@ -473,8 +473,8 @@ public class FrameBuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glDepth = PGraphicsOpenGL.createRenderBufferObject(context, pgl);
pgl.bindRenderbuffer(PGL.RENDERBUFFER, glDepth);
@@ -498,7 +498,7 @@ public class FrameBuffer implements PConstants {
pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT,
PGL.RENDERBUFFER, glDepth);
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
@@ -509,8 +509,8 @@ public class FrameBuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glStencil = PGraphicsOpenGL.createRenderBufferObject(context, pgl);
pgl.bindRenderbuffer(PGL.RENDERBUFFER, glStencil);
@@ -533,7 +533,7 @@ public class FrameBuffer implements PConstants {
pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT,
PGL.RENDERBUFFER, glStencil);
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
}
+231 -164
View File
@@ -57,6 +57,9 @@ public abstract class PGL {
/** ID of the GL context associated to the surface **/
protected int glContext;
/** true if this is the GL interface for a primary surface PGraphics */
protected boolean primaryPGL;
// ........................................................
// Parameters
@@ -131,21 +134,21 @@ public abstract class PGL {
// FBO layer
protected static boolean fboLayerRequested = false;
protected static boolean fboLayerCreated = false;
protected static boolean fboLayerInUse = false;
protected static boolean firstFrame = true;
protected static int reqNumSamples;
protected static int numSamples;
protected static IntBuffer glColorFbo;
protected static IntBuffer glMultiFbo;
protected static IntBuffer glColorBuf;
protected static IntBuffer glColorTex;
protected static IntBuffer glDepthStencil;
protected static IntBuffer glDepth;
protected static IntBuffer glStencil;
protected static int fboWidth, fboHeight;
protected static int backTex, frontTex;
protected boolean fboLayerRequested = false;
protected boolean fboLayerCreated = false;
protected boolean fboLayerInUse = false;
protected boolean firstFrame = true;
protected int reqNumSamples;
protected int numSamples;
protected IntBuffer glColorFbo;
protected IntBuffer glMultiFbo;
protected IntBuffer glColorBuf;
protected IntBuffer glColorTex;
protected IntBuffer glDepthStencil;
protected IntBuffer glDepth;
protected IntBuffer glStencil;
protected int fboWidth, fboHeight;
protected int backTex, frontTex;
/** Flags used to handle the creation of a separate front texture */
protected boolean usingFrontTex = false;
@@ -155,33 +158,33 @@ public abstract class PGL {
// Texture rendering
protected static boolean loadedTex2DShader = false;
protected static int tex2DShaderProgram;
protected static int tex2DVertShader;
protected static int tex2DFragShader;
protected static int tex2DShaderContext;
protected static int texGeoVBO;
protected static int tex2DVertLoc;
protected static int tex2DTCoordLoc;
protected static int tex2DSamplerLoc;
protected boolean loadedTex2DShader = false;
protected int tex2DShaderProgram;
protected int tex2DVertShader;
protected int tex2DFragShader;
protected int tex2DShaderContext;
protected int texGeoVBO;
protected int tex2DVertLoc;
protected int tex2DTCoordLoc;
protected int tex2DSamplerLoc;
protected static boolean loadedTexRectShader = false;
protected static int texRectShaderProgram;
protected static int texRectVertShader;
protected static int texRectFragShader;
protected static int texRectShaderContext;
protected static int texRectVertLoc;
protected static int texRectTCoordLoc;
protected static int texRectSamplerLoc;
protected boolean loadedTexRectShader = false;
protected int texRectShaderProgram;
protected int texRectVertShader;
protected int texRectFragShader;
protected int texRectShaderContext;
protected int texRectVertLoc;
protected int texRectTCoordLoc;
protected int texRectSamplerLoc;
protected static float[] texCoords = {
protected float[] texCoords = {
// X, Y, U, V
-1.0f, -1.0f, 0.0f, 0.0f,
+1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, +1.0f, 0.0f, 1.0f,
+1.0f, +1.0f, 1.0f, 1.0f
};
protected static FloatBuffer texData;
protected FloatBuffer texData;
protected static final String SHADER_PREPROCESSOR_DIRECTIVE =
"#ifdef GL_ES\n" +
@@ -218,12 +221,12 @@ public abstract class PGL {
};
/** Which texturing targets are enabled */
protected static boolean[] texturingTargets = { false, false };
protected boolean[] texturingTargets = { false, false };
/** Used to keep track of which textures are bound to each target */
protected static int maxTexUnits;
protected static int activeTexUnit = 0;
protected static int[][] boundTextures;
protected int maxTexUnits;
protected int activeTexUnit = 0;
protected int[][] boundTextures;
// ........................................................
@@ -270,6 +273,13 @@ public abstract class PGL {
protected static final String TEXUNIT_ERROR =
"Number of texture units not supported by this hardware (or driver)" + WIKI;
protected static final String NONPRIMARY_ERROR =
"The renderer is trying to call a PGL function that can only be called on a primary PGL. " +
"This is most likely due to a bug in the renderer's code, please report it with an " +
"issue on Processing's github page https://github.com/processing/processing/issues?state=open " +
"if using any of the built-in OpenGL renderers. If you are using a contributed " +
"library, contact the library's developers.";
// ........................................................
// Constants
@@ -334,6 +344,17 @@ public abstract class PGL {
}
public void setPrimary(boolean primary) {
primaryPGL = primary;
}
protected void checkPrimary() {
if (!primaryPGL) {
throw new RuntimeException(NONPRIMARY_ERROR);
}
}
/**
* Return the native canvas the OpenGL context associated to this PGL object
* is rendering to (if any).
@@ -354,6 +375,8 @@ public abstract class PGL {
protected void deleteSurface() {
checkPrimary();
if (threadIsCurrent() && fboLayerCreated) {
deleteTextures(2, glColorTex);
deleteFramebuffers(1, glColorFbo);
@@ -371,11 +394,13 @@ public abstract class PGL {
protected int getReadFramebuffer() {
checkPrimary();
return fboLayerInUse ? glColorFbo.get(0) : 0;
}
protected int getDrawFramebuffer() {
checkPrimary();
if (fboLayerInUse) return 1 < numSamples ? glMultiFbo.get(0) :
glColorFbo.get(0);
else return 0;
@@ -383,26 +408,31 @@ public abstract class PGL {
protected int getDefaultDrawBuffer() {
checkPrimary();
return fboLayerInUse ? COLOR_ATTACHMENT0 : FRONT;
}
protected int getDefaultReadBuffer() {
checkPrimary();
return fboLayerInUse ? COLOR_ATTACHMENT0 : FRONT;
}
protected boolean isFBOBacked() {
checkPrimary();
return fboLayerInUse;
}
protected void requestFBOLayer() {
checkPrimary();
fboLayerRequested = true;
}
protected boolean isMultisampled() {
checkPrimary();
return 1 < numSamples;
}
@@ -436,6 +466,7 @@ public abstract class PGL {
protected Texture wrapBackTexture(Texture texture) {
checkPrimary();
if (texture == null) {
texture = new Texture(pg);
texture.init(pg.width, pg.height,
@@ -453,6 +484,7 @@ public abstract class PGL {
protected Texture wrapFrontTexture(Texture texture) {
checkPrimary();
if (texture == null) {
texture = new Texture(pg);
texture.init(pg.width, pg.height,
@@ -469,6 +501,7 @@ public abstract class PGL {
protected void bindFrontTexture() {
checkPrimary();
usingFrontTex = true;
if (!texturingIsEnabled(TEXTURE_2D)) {
enableTexturing(TEXTURE_2D);
@@ -478,6 +511,7 @@ public abstract class PGL {
protected void unbindFrontTexture() {
checkPrimary();
if (textureIsBound(TEXTURE_2D, glColorTex.get(frontTex))) {
// We don't want to unbind another texture
// that might be bound instead of this one.
@@ -493,6 +527,7 @@ public abstract class PGL {
protected void syncBackTexture() {
checkPrimary();
if (usingFrontTex) needSepFrontTex = true;
if (1 < numSamples) {
bindFramebuffer(READ_FRAMEBUFFER, glMultiFbo.get(0));
@@ -504,18 +539,122 @@ public abstract class PGL {
}
protected int qualityToSamples(int quality) {
if (quality <= 1) {
return 1;
///////////////////////////////////////////////////////////
// Frame rendering
protected void beginDraw(boolean clear0) {
checkPrimary();
if (needFBOLayer(clear0)) {
if (!fboLayerCreated) createFBOLayer();
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
TEXTURE_2D, glColorTex.get(backTex), 0);
if (1 < numSamples) {
bindFramebuffer(FRAMEBUFFER, glMultiFbo.get(0));
}
if (firstFrame) {
// No need to draw back color buffer because we are in the first frame.
int argb = pg.backgroundColor;
float a = ((argb >> 24) & 0xff) / 255.0f;
float r = ((argb >> 16) & 0xff) / 255.0f;
float g = ((argb >> 8) & 0xff) / 255.0f;
float b = ((argb) & 0xff) / 255.0f;
clearColor(r, g, b, a);
clear(COLOR_BUFFER_BIT);
} else if (!clear0) {
// Render previous back texture (now is the front) as background,
// because no background() is being used ("incremental drawing")
drawTexture(TEXTURE_2D, glColorTex.get(frontTex),
fboWidth, fboHeight, pg.width, pg.height,
0, 0, pg.width, pg.height,
0, 0, pg.width, pg.height);
}
fboLayerInUse = true;
} else {
// Number of samples is always an even number:
int n = 2 * (quality / 2);
return n;
fboLayerInUse = false;
}
if (firstFrame) {
firstFrame = false;
}
if (!USE_FBOLAYER_BY_DEFAULT) {
// The result of this assignment is the following: if the user requested
// at some point the use of the FBO layer, but subsequently didn't
// request it again, then the rendering won't render to the FBO layer if
// not needed by the condif, since it is slower than simple onscreen
// rendering.
fboLayerRequested = false;
}
}
protected void createFBOLayer() {
protected void endDraw(boolean clear0) {
checkPrimary();
if (fboLayerInUse) {
syncBackTexture();
// Draw the contents of the back texture to the screen framebuffer.
bindFramebuffer(FRAMEBUFFER, 0);
clearDepth(1);
clearColor(0, 0, 0, 0);
clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
// Render current back texture to screen, without blending.
disable(BLEND);
drawTexture(TEXTURE_2D, glColorTex.get(backTex),
fboWidth, fboHeight, pg.width, pg.height,
0, 0, pg.width, pg.height,
0, 0, pg.width, pg.height);
// Swapping front and back textures.
int temp = frontTex;
frontTex = backTex;
backTex = temp;
}
}
protected abstract void getGL(PGL pgl);
protected abstract boolean canDraw();
protected abstract void requestFocus();
protected abstract void requestDraw();
protected abstract void swapBuffers();
protected boolean threadIsCurrent() {
return Thread.currentThread() == glThread;
}
protected void beginGL() { }
protected void endGL() { }
private boolean needFBOLayer(boolean clear0) {
return !clear0 || fboLayerRequested || 1 < numSamples;
}
private void createFBOLayer() {
System.out.println("Creating FBO layer");
String ext = getString(EXTENSIONS);
if (-1 < ext.indexOf("texture_non_power_of_two")) {
fboWidth = pg.width;
@@ -656,118 +795,6 @@ public abstract class PGL {
}
///////////////////////////////////////////////////////////
// Frame rendering
protected void beginDraw(boolean clear0) {
if (needFBOLayer(clear0)) {
if (!fboLayerCreated) createFBOLayer();
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
TEXTURE_2D, glColorTex.get(backTex), 0);
if (1 < numSamples) {
bindFramebuffer(FRAMEBUFFER, glMultiFbo.get(0));
}
if (firstFrame) {
// No need to draw back color buffer because we are in the first frame.
int argb = pg.backgroundColor;
float a = ((argb >> 24) & 0xff) / 255.0f;
float r = ((argb >> 16) & 0xff) / 255.0f;
float g = ((argb >> 8) & 0xff) / 255.0f;
float b = ((argb) & 0xff) / 255.0f;
clearColor(r, g, b, a);
clear(COLOR_BUFFER_BIT);
} else if (!clear0) {
// Render previous back texture (now is the front) as background,
// because no background() is being used ("incremental drawing")
drawTexture(TEXTURE_2D, glColorTex.get(frontTex),
fboWidth, fboHeight, pg.width, pg.height,
0, 0, pg.width, pg.height,
0, 0, pg.width, pg.height);
}
fboLayerInUse = true;
} else {
fboLayerInUse = false;
}
if (firstFrame) {
firstFrame = false;
}
if (!USE_FBOLAYER_BY_DEFAULT) {
// The result of this assignment is the following: if the user requested
// at some point the use of the FBO layer, but subsequently didn't
// request it again, then the rendering won't render to the FBO layer if
// not needed by the condif, since it is slower than simple onscreen
// rendering.
fboLayerRequested = false;
}
}
protected void endDraw(boolean clear0) {
if (fboLayerInUse) {
syncBackTexture();
// Draw the contents of the back texture to the screen framebuffer.
bindFramebuffer(FRAMEBUFFER, 0);
clearDepth(1);
clearColor(0, 0, 0, 0);
clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
// Render current back texture to screen, without blending.
disable(BLEND);
drawTexture(TEXTURE_2D, glColorTex.get(backTex),
fboWidth, fboHeight, pg.width, pg.height,
0, 0, pg.width, pg.height,
0, 0, pg.width, pg.height);
// Swapping front and back textures.
int temp = frontTex;
frontTex = backTex;
backTex = temp;
}
}
protected abstract void getGL(PGL pgl);
protected abstract boolean canDraw();
protected abstract void requestFocus();
protected abstract void requestDraw();
protected abstract void swapBuffers();
protected boolean threadIsCurrent() {
return Thread.currentThread() == glThread;
}
protected boolean needFBOLayer(boolean clear0) {
return !clear0 || fboLayerRequested || 1 < numSamples;
}
protected void beginGL() { }
protected void endGL() { }
///////////////////////////////////////////////////////////
// Context interface
@@ -906,8 +933,8 @@ public abstract class PGL {
protected void initTex2DShader() {
if (!loadedTex2DShader/* || tex2DShaderContext != glContext*/) {
System.out.println("initializing texture shader");
if (!loadedTex2DShader || tex2DShaderContext != glContext) {
System.out.println("Initializing PGL texture shader");
String vertSource = PApplet.join(texVertShaderSource, "\n");
String fragSource = PApplet.join(tex2DFragShaderSource, "\n");
tex2DVertShader = createShader(VERTEX_SHADER, vertSource);
@@ -927,6 +954,8 @@ public abstract class PGL {
texGeoVBO = intBuffer.get(0);
bindBuffer(ARRAY_BUFFER, texGeoVBO);
bufferData(ARRAY_BUFFER, 16 * SIZEOF_FLOAT, null, STATIC_DRAW);
System.out.println("Done!");
}
if (texData == null) {
@@ -1436,6 +1465,17 @@ public abstract class PGL {
}
protected static int qualityToSamples(int quality) {
if (quality <= 1) {
return 1;
} else {
// Number of samples is always an even number:
int n = 2 * (quality / 2);
return n;
}
}
protected String[] loadVertexShader(String filename) {
return pg.parent.loadStrings(filename);
}
@@ -1486,18 +1526,45 @@ public abstract class PGL {
}
protected String[] convertFragmentSource(String[] fragSrc0,
int version0, int version1) {
protected static String[] convertFragmentSource(String[] fragSrc0,
int version0, int version1) {
if (version0 == 120 && version1 == 150) {
String[] fragSrc = new String[fragSrc0.length + 2];
fragSrc[0] = "#version 150";
fragSrc[1] = "out vec4 fragColor;";
for (int i = 0; i < fragSrc0.length; i++) {
String line = fragSrc0[i];
line = line.replace("varying", "in");
line = line.replace("attribute", "in");
line = line.replace("gl_FragColor", "fragColor");
line = line.replace("texture", "texMap");
line = line.replace("texMap2D(", "texture(");
line = line.replace("texMap2DRect(", "texture(");
fragSrc[i + 2] = line;
}
return fragSrc;
}
return fragSrc0;
}
protected String[] convertVertexSource(String[] vertSrc0,
int version0, int version1) {
protected static String[] convertVertexSource(String[] vertSrc0,
int version0, int version1) {
if (version0 == 120 && version1 == 150) {
String[] vertSrc = new String[vertSrc0.length + 1];
vertSrc[0] = "#version 150";
for (int i = 0; i < vertSrc0.length; i++) {
String line = vertSrc0[i];
line = line.replace("attribute", "in");
line = line.replace("varying", "out");
vertSrc[i + 1] = line;
}
return vertSrc;
}
return vertSrc0;
}
protected int createShader(int shaderType, String source) {
int shader = createShader(shaderType);
if (shader != 0) {
+109 -100
View File
@@ -40,66 +40,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected PGraphicsOpenGL currentPG;
/** Font cache for texture objects. */
protected WeakHashMap<PFont, FontTexture> fontMap =
new WeakHashMap<PFont, FontTexture>();
// ........................................................
static final String OPENGL_THREAD_ERROR =
"Cannot run the OpenGL renderer outside the main thread, change your code" +
"\nso the drawing calls are all inside the main thread, " +
"\nor use the default renderer instead.";
static final String BLEND_DRIVER_ERROR =
"blendMode(%1$s) is not supported by this hardware (or driver)";
static final String BLEND_RENDERER_ERROR =
"blendMode(%1$s) is not supported by this renderer";
static final String ALREADY_BEGAN_CONTOUR_ERROR =
"Already called beginContour()";
static final String NO_BEGIN_CONTOUR_ERROR =
"Need to call beginContour() first";
static final String UNSUPPORTED_SMOOTH_LEVEL_ERROR =
"Smooth level %1$s is not available. Using %2$s instead";
static final String UNSUPPORTED_SMOOTH_ERROR =
"Smooth is not supported by this hardware (or driver)";
static final String TOO_MANY_SMOOTH_CALLS_ERROR =
"The smooth/noSmooth functions are being called too often.\n" +
"This results in screen flickering, so they will be disabled\n" +
"for the rest of the sketch's execution";
static final String UNSUPPORTED_SHAPE_FORMAT_ERROR =
"Unsupported shape format";
static final String MISSING_UV_TEXCOORDS_ERROR =
"No uv texture coordinates supplied with vertex() call";
static final String INVALID_FILTER_SHADER_ERROR =
"Your shader cannot be used as a filter because is of type POINT or LINES";
static final String INCONSISTENT_SHADER_TYPES =
"The vertex and fragment shaders have different types";
static final String WRONG_SHADER_TYPE_ERROR =
"shader() called with a wrong shader";
static final String SHADER_NEED_LIGHT_ATTRIBS =
"The provided shader needs light attributes (ambient, diffuse, etc.), but " +
"the current scene is unlit, so the default shader will be used instead";
static final String MISSING_FRAGMENT_SHADER =
"The fragment shader is missing, cannot create shader object";
static final String MISSING_VERTEX_SHADER =
"The vertex shader is missing, cannot create shader object";
static final String UNKNOWN_SHADER_KIND_ERROR =
"Unknown shader kind";
static final String NO_TEXLIGHT_SHADER_ERROR =
"Your shader needs to be of TEXLIGHT type " +
"to render this geometry properly, using default shader instead.";
static final String NO_LIGHT_SHADER_ERROR =
"Your shader needs to be of LIGHT type " +
"to render this geometry properly, using default shader instead.";
static final String NO_TEXTURE_SHADER_ERROR =
"Your shader needs to be of TEXTURE type " +
"to render this geometry properly, using default shader instead.";
static final String NO_COLOR_SHADER_ERROR =
"Your shader needs to be of COLOR type " +
"to render this geometry properly, using default shader instead.";
static final String TOO_LONG_STROKE_PATH_ERROR =
"Stroke path is too long, some bevel triangles won't be added";
static final String TESSELLATION_ERROR =
"Tessellation Error: %1$s";
protected WeakHashMap<PFont, FontTexture> fontMap;
// ........................................................
@@ -153,8 +94,8 @@ public class PGraphicsOpenGL extends PGraphics {
protected boolean pointBuffersCreated = false;
protected int pointBuffersContext;
protected static final int INIT_VERTEX_BUFFER_SIZE = 256;
protected static final int INIT_INDEX_BUFFER_SIZE = 512;
static protected final int INIT_VERTEX_BUFFER_SIZE = 256;
static protected final int INIT_INDEX_BUFFER_SIZE = 512;
// ........................................................
@@ -248,8 +189,8 @@ public class PGraphicsOpenGL extends PGraphics {
protected InGeometry inGeo;
protected TessGeometry tessGeo;
static protected Tessellator tessellator;
protected TexCache texCache;
static protected Tessellator tessellator;
// ........................................................
@@ -397,11 +338,11 @@ public class PGraphicsOpenGL extends PGraphics {
static protected final int FB_STACK_DEPTH = 16;
static protected int fbStackDepth;
static protected FrameBuffer[] fbStack = new FrameBuffer[FB_STACK_DEPTH];
static protected FrameBuffer drawFramebuffer;
static protected FrameBuffer readFramebuffer;
static protected FrameBuffer currentFramebuffer;
protected int fbStackDepth;
protected FrameBuffer[] fbStack;
protected FrameBuffer drawFramebuffer;
protected FrameBuffer readFramebuffer;
protected FrameBuffer currentFramebuffer;
// .......................................................
@@ -508,6 +449,67 @@ public class PGraphicsOpenGL extends PGraphics {
static protected IntBuffer intBuffer;
static protected FloatBuffer floatBuffer;
// ........................................................
// Error strings:
static final String OPENGL_THREAD_ERROR =
"Cannot run the OpenGL renderer outside the main thread, change your code" +
"\nso the drawing calls are all inside the main thread, " +
"\nor use the default renderer instead.";
static final String BLEND_DRIVER_ERROR =
"blendMode(%1$s) is not supported by this hardware (or driver)";
static final String BLEND_RENDERER_ERROR =
"blendMode(%1$s) is not supported by this renderer";
static final String ALREADY_BEGAN_CONTOUR_ERROR =
"Already called beginContour()";
static final String NO_BEGIN_CONTOUR_ERROR =
"Need to call beginContour() first";
static final String UNSUPPORTED_SMOOTH_LEVEL_ERROR =
"Smooth level %1$s is not available. Using %2$s instead";
static final String UNSUPPORTED_SMOOTH_ERROR =
"Smooth is not supported by this hardware (or driver)";
static final String TOO_MANY_SMOOTH_CALLS_ERROR =
"The smooth/noSmooth functions are being called too often.\n" +
"This results in screen flickering, so they will be disabled\n" +
"for the rest of the sketch's execution";
static final String UNSUPPORTED_SHAPE_FORMAT_ERROR =
"Unsupported shape format";
static final String MISSING_UV_TEXCOORDS_ERROR =
"No uv texture coordinates supplied with vertex() call";
static final String INVALID_FILTER_SHADER_ERROR =
"Your shader cannot be used as a filter because is of type POINT or LINES";
static final String INCONSISTENT_SHADER_TYPES =
"The vertex and fragment shaders have different types";
static final String WRONG_SHADER_TYPE_ERROR =
"shader() called with a wrong shader";
static final String SHADER_NEED_LIGHT_ATTRIBS =
"The provided shader needs light attributes (ambient, diffuse, etc.), but " +
"the current scene is unlit, so the default shader will be used instead";
static final String MISSING_FRAGMENT_SHADER =
"The fragment shader is missing, cannot create shader object";
static final String MISSING_VERTEX_SHADER =
"The vertex shader is missing, cannot create shader object";
static final String UNKNOWN_SHADER_KIND_ERROR =
"Unknown shader kind";
static final String NO_TEXLIGHT_SHADER_ERROR =
"Your shader needs to be of TEXLIGHT type " +
"to render this geometry properly, using default shader instead.";
static final String NO_LIGHT_SHADER_ERROR =
"Your shader needs to be of LIGHT type " +
"to render this geometry properly, using default shader instead.";
static final String NO_TEXTURE_SHADER_ERROR =
"Your shader needs to be of TEXTURE type " +
"to render this geometry properly, using default shader instead.";
static final String NO_COLOR_SHADER_ERROR =
"Your shader needs to be of COLOR type " +
"to render this geometry properly, using default shader instead.";
static final String TOO_LONG_STROKE_PATH_ERROR =
"Stroke path is too long, some bevel triangles won't be added";
static final String TESSELLATION_ERROR =
"Tessellation Error: %1$s";
//////////////////////////////////////////////////////////////
// INIT/ALLOCATE/FINISH
@@ -538,7 +540,12 @@ public class PGraphicsOpenGL extends PGraphics {
@Override
public void setPrimary(boolean primary) {
super.setPrimary(primary);
pgl.setPrimary(primary);
format = ARGB;
if (primary) {
fbStack = new FrameBuffer[FB_STACK_DEPTH];
fontMap = new WeakHashMap<PFont, FontTexture>();
}
}
@@ -643,12 +650,6 @@ public class PGraphicsOpenGL extends PGraphics {
if (primarySurface) {
pgl.deleteSurface();
// This next line is critical to release many static allocations.
// This is important in the context of, say, a unit test suite, which
// runs more than one OpenGL sketch within the same classloader
// (as in the case of processing.py). Please don't remove it!
//pgl = null;
}
}
@@ -1209,37 +1210,45 @@ public class PGraphicsOpenGL extends PGraphics {
// FRAMEBUFFERS
protected static void pushFramebuffer() {
if (fbStackDepth == FB_STACK_DEPTH) {
protected void pushFramebuffer() {
PGraphicsOpenGL ppg = getPrimaryPG();
if (ppg.fbStackDepth == FB_STACK_DEPTH) {
throw new RuntimeException("Too many pushFramebuffer calls");
}
fbStack[fbStackDepth] = currentFramebuffer;
fbStackDepth++;
ppg.fbStack[ppg.fbStackDepth] = ppg.currentFramebuffer;
ppg.fbStackDepth++;
}
protected static void setFramebuffer(FrameBuffer fbo) {
if (currentFramebuffer != fbo) {
currentFramebuffer = fbo;
currentFramebuffer.bind();
protected void setFramebuffer(FrameBuffer fbo) {
PGraphicsOpenGL ppg = getPrimaryPG();
if (ppg.currentFramebuffer != fbo) {
ppg.currentFramebuffer = fbo;
ppg.currentFramebuffer.bind();
}
}
protected static void popFramebuffer() {
if (fbStackDepth == 0) {
protected void popFramebuffer() {
PGraphicsOpenGL ppg = getPrimaryPG();
if (ppg.fbStackDepth == 0) {
throw new RuntimeException("popFramebuffer call is unbalanced.");
}
fbStackDepth--;
FrameBuffer fbo = fbStack[fbStackDepth];
if (currentFramebuffer != fbo) {
currentFramebuffer.finish();
currentFramebuffer = fbo;
currentFramebuffer.bind();
ppg.fbStackDepth--;
FrameBuffer fbo = ppg.fbStack[ppg.fbStackDepth];
if (ppg.currentFramebuffer != fbo) {
ppg.currentFramebuffer.finish();
ppg.currentFramebuffer = fbo;
ppg.currentFramebuffer.bind();
}
}
protected FrameBuffer getCurrentFB() {
return getPrimaryPG().currentFramebuffer;
}
//////////////////////////////////////////////////////////////
// FRAME RENDERING
@@ -1797,8 +1806,8 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.depthMask(true);
}
currentFramebuffer.bind();
pgl.drawBuffer(currentFramebuffer.getDefaultDrawBuffer());
getCurrentFB().bind();
pgl.drawBuffer(getCurrentFB().getDefaultDrawBuffer());
}
public void beginReadPixels() {
@@ -1831,7 +1840,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (op == OP_READ) {
if (offscreenMultisample) {
// Making sure the offscreen FBO is up-to-date
multisampleFramebuffer.copy(offscreenFramebuffer, currentFramebuffer);
multisampleFramebuffer.copy(offscreenFramebuffer, getCurrentFB());
}
// We always read the screen pixels from the color FBO.
pixfb = offscreenFramebuffer;
@@ -1844,7 +1853,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
// Set the framebuffer where the pixel operation shall be carried out.
if (pixfb != currentFramebuffer) {
if (pixfb != getCurrentFB()) {
pushFramebuffer();
setFramebuffer(pixfb);
pixOpChangedFB = true;
@@ -1852,9 +1861,9 @@ public class PGraphicsOpenGL extends PGraphics {
// We read from/write to the draw buffer.
if (op == OP_READ) {
pgl.readBuffer(currentFramebuffer.getDefaultDrawBuffer());
pgl.readBuffer(getCurrentFB().getDefaultDrawBuffer());
} else if (op == OP_WRITE) {
pgl.drawBuffer(currentFramebuffer.getDefaultDrawBuffer());
pgl.drawBuffer(getCurrentFB().getDefaultDrawBuffer());
}
pixelsOp = op;
@@ -1869,8 +1878,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
// Restoring default read/draw buffer configuration.
pgl.readBuffer(currentFramebuffer.getDefaultReadBuffer());
pgl.drawBuffer(currentFramebuffer.getDefaultDrawBuffer());
pgl.readBuffer(getCurrentFB().getDefaultReadBuffer());
pgl.drawBuffer(getCurrentFB().getDefaultDrawBuffer());
pixelsOp = OP_NONE;
}
@@ -5609,7 +5618,7 @@ public class PGraphicsOpenGL extends PGraphics {
} else if (offscreenMultisample) {
// We need to copy the contents of the multisampled buffer to the color
// buffer, so the later is up-to-date with the last drawing.
multisampleFramebuffer.copy(offscreenFramebuffer, currentFramebuffer);
multisampleFramebuffer.copy(offscreenFramebuffer, getCurrentFB());
}
if (needEndDraw) {
@@ -6353,7 +6362,7 @@ public class PGraphicsOpenGL extends PGraphics {
// pgl.colorMask(true, true, true, true);
if (offscreenMultisample) {
multisampleFramebuffer.copy(offscreenFramebuffer, currentFramebuffer);
multisampleFramebuffer.copy(offscreenFramebuffer, getCurrentFB());
}
popFramebuffer();
+61 -73
View File
@@ -79,6 +79,41 @@ public class PJOGL extends PGL {
/** Selected GL profile */
public static GLProfile profile;
static {
System.out.println("Animation thread: " + Thread.currentThread());
if (PROFILE == 2) {
try {
profile = GLProfile.getGL2ES1();
} catch (GLException ex) {
profile = GLProfile.getMaxFixedFunc(true);
}
} else if (PROFILE == 3) {
try {
profile = GLProfile.getGL2GL3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL3()) {
PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile);
}
} else if (PROFILE == 4) {
try {
profile = GLProfile.getGL4ES3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL4()) {
PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile);
}
} else throw new RuntimeException(UNSUPPORTED_GLPROF_ERROR);
System.out.println("Done, got this profile: " + profile);
if (2 < PROFILE) {
texVertShaderSource = convertVertexSource(texVertShaderSource, 120, 150);
tex2DFragShaderSource = convertFragmentSource(tex2DFragShaderSource, 120, 150);
texRectFragShaderSource = convertFragmentSource(texRectFragShaderSource, 120, 150);
}
}
// ........................................................
@@ -173,13 +208,13 @@ public class PJOGL extends PGL {
// JOGL's FBO-layer
/** Back (== draw, current frame) buffer */
protected static FBObject backFBO;
protected FBObject backFBO;
/** Sink buffer, used in the multisampled case */
protected static FBObject sinkFBO;
protected FBObject sinkFBO;
/** Front (== read, previous frame) buffer */
protected static FBObject frontFBO;
protected static FBObject.TextureAttachment backTexAttach;
protected static FBObject.TextureAttachment frontTexAttach;
protected FBObject frontFBO;
protected FBObject.TextureAttachment backTexAttach;
protected FBObject.TextureAttachment frontTexAttach;
protected boolean changedFrontTex = false;
protected boolean changedBackTex = false;
@@ -221,6 +256,7 @@ public class PJOGL extends PGL {
@Override
protected void setFps(float fps) {
checkPrimary();
if (!setFps || targetFps != fps) {
if (60 < fps) {
// Disables v-sync
@@ -238,39 +274,11 @@ public class PJOGL extends PGL {
@Override
protected void initSurface(int antialias) {
if (profile == null) {
if (PROFILE == 2) {
try {
profile = GLProfile.getGL2ES1();
} catch (GLException ex) {
profile = GLProfile.getMaxFixedFunc(true);
}
} else if (PROFILE == 3) {
try {
profile = GLProfile.getGL2GL3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL3()) {
PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile);
}
} else if (PROFILE == 4) {
try {
profile = GLProfile.getGL4ES3();
} catch (GLException ex) {
profile = GLProfile.getMaxProgrammable(true);
}
if (!profile.isGL4()) {
PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile);
}
} else throw new RuntimeException(UNSUPPORTED_GLPROF_ERROR);
checkPrimary();
if (2 < PROFILE) {
texVertShaderSource = convertVertexSource(texVertShaderSource, 120, 150);
tex2DFragShaderSource = convertFragmentSource(tex2DFragShaderSource, 120, 150);
texRectFragShaderSource = convertFragmentSource(texRectFragShaderSource, 120, 150);
}
} else {
System.out.println("initializing surface");
if (canvasAWT != null && canvasNEWT != null) {
// Restarting...
if (canvasAWT != null) {
canvasAWT.removeGLEventListener(listener);
@@ -355,11 +363,14 @@ public class PJOGL extends PGL {
fboLayerInUse = false;
firstFrame = true;
setFps = false;
System.out.println("done");
}
@Override
protected void reinitSurface() {
checkPrimary();
sinkFBO = backFBO = frontFBO = null;
fboLayerCreated = false;
fboLayerInUse = false;
@@ -409,11 +420,13 @@ public class PJOGL extends PGL {
window.removeGLEventListener(listener);
}
GLProfile.shutdown();
System.out.println("bye bye");
}
@Override
protected int getReadFramebuffer() {
checkPrimary();
if (fboLayerInUse) {
return glColorFbo.get(0);
} else if (capabilities.isFBO()) {
@@ -426,6 +439,7 @@ public class PJOGL extends PGL {
@Override
protected int getDrawFramebuffer() {
checkPrimary();
if (fboLayerInUse) {
if (1 < numSamples) {
return glMultiFbo.get(0);
@@ -442,6 +456,7 @@ public class PJOGL extends PGL {
@Override
protected int getDefaultDrawBuffer() {
checkPrimary();
if (fboLayerInUse) {
return COLOR_ATTACHMENT0;
} else if (capabilities.isFBO()) {
@@ -456,6 +471,7 @@ public class PJOGL extends PGL {
@Override
protected int getDefaultReadBuffer() {
checkPrimary();
if (fboLayerInUse) {
return COLOR_ATTACHMENT0;
} else if (capabilities.isFBO()) {
@@ -470,6 +486,7 @@ public class PJOGL extends PGL {
@Override
protected boolean isFBOBacked() {
checkPrimary();
return super.isFBOBacked() || capabilities.isFBO();
}
@@ -488,6 +505,7 @@ public class PJOGL extends PGL {
@Override
protected Texture wrapBackTexture(Texture texture) {
checkPrimary();
if (texture == null || changedBackTex) {
if (USE_JOGL_FBOLAYER) {
texture = new Texture(pg);
@@ -515,6 +533,7 @@ public class PJOGL extends PGL {
@Override
protected Texture wrapFrontTexture(Texture texture) {
checkPrimary();
if (texture == null || changedFrontTex) {
if (USE_JOGL_FBOLAYER) {
texture = new Texture(pg);
@@ -542,6 +561,7 @@ public class PJOGL extends PGL {
@Override
protected void bindFrontTexture() {
if (USE_JOGL_FBOLAYER) {
checkPrimary();
usingFrontTex = true;
if (!texturingIsEnabled(TEXTURE_2D)) {
enableTexturing(TEXTURE_2D);
@@ -554,6 +574,7 @@ public class PJOGL extends PGL {
@Override
protected void unbindFrontTexture() {
if (USE_JOGL_FBOLAYER) {
checkPrimary();
if (textureIsBound(TEXTURE_2D, frontTexAttach.getName())) {
// We don't want to unbind another texture
// that might be bound instead of this one.
@@ -572,6 +593,7 @@ public class PJOGL extends PGL {
@Override
protected void syncBackTexture() {
if (USE_JOGL_FBOLAYER) {
checkPrimary();
if (usingFrontTex) needSepFrontTex = true;
if (1 < numSamples) {
backFBO.syncSamplingSink(gl);
@@ -628,7 +650,6 @@ public class PJOGL extends PGL {
}
@Override
protected boolean canDraw() {
return pg.initialized && pg.parent.isDisplayable();
@@ -641,6 +662,7 @@ public class PJOGL extends PGL {
@Override
protected void requestDraw() {
checkPrimary();
boolean canDraw = pg.parent.canDraw();
if (pg.initialized && (canDraw || prevCanDraw)) {
try {
@@ -673,6 +695,7 @@ public class PJOGL extends PGL {
@Override
protected void swapBuffers() {
checkPrimary();
if (WINDOW_TOOLKIT == AWT) {
canvasAWT.swapBuffers();
} else if (WINDOW_TOOLKIT == NEWT) {
@@ -1129,41 +1152,6 @@ public class PJOGL extends PGL {
}
@Override
protected String[] convertFragmentSource(String[] fragSrc0,
int version0, int version1) {
String[] fragSrc = new String[fragSrc0.length + 2];
fragSrc[0] = "#version 150";
fragSrc[1] = "out vec4 fragColor;";
for (int i = 0; i < fragSrc0.length; i++) {
String line = fragSrc0[i];
line = line.replace("varying", "in");
line = line.replace("attribute", "in");
line = line.replace("gl_FragColor", "fragColor");
line = line.replace("texture", "texMap");
line = line.replace("texMap2D(", "texture(");
line = line.replace("texMap2DRect(", "texture(");
fragSrc[i + 2] = line;
}
return fragSrc;
}
@Override
protected String[] convertVertexSource(String[] vertSrc0,
int version0, int version1) {
String[] vertSrc = new String[vertSrc0.length + 1];
vertSrc[0] = "#version 150";
for (int i = 0; i < vertSrc0.length; i++) {
String line = vertSrc0[i];
line = line.replace("attribute", "in");
line = line.replace("varying", "out");
vertSrc[i + 1] = line;
}
return vertSrc;
}
///////////////////////////////////////////////////////////
// Tessellator
+9 -9
View File
@@ -521,10 +521,10 @@ public class Texture implements PConstants {
// reading the pixels from the current draw buffer (which is the color
// buffer of the FBO).
tempFbo.setColorBuffer(this);
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(tempFbo);
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
tempFbo.readPixels();
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
tempFbo.getPixels(pixels);
convertToARGB(pixels);
@@ -1248,8 +1248,8 @@ public class Texture implements PConstants {
tempFbo.disableDepthTest();
// FBO copy:
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(tempFbo);
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
// Clear the color buffer to make sure that the alpha channel is set to
// full transparency
pgl.clearColor(0, 0, 0, 0);
@@ -1269,7 +1269,7 @@ public class Texture implements PConstants {
tex.glWidth, tex.glHeight, tempFbo.width, tempFbo.height,
x, y, w, h, x, y, w, h);
}
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
updateTexels(x, y, w, h);
}
@@ -1288,8 +1288,8 @@ public class Texture implements PConstants {
tempFbo.disableDepthTest();
// FBO copy:
PGraphicsOpenGL.pushFramebuffer();
PGraphicsOpenGL.setFramebuffer(tempFbo);
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
if (scale) {
// Rendering tex into "this", and scaling the source rectangle
// to cover the entire destination region.
@@ -1305,7 +1305,7 @@ public class Texture implements PConstants {
texWidth, texHeight, tempFbo.width, tempFbo.height,
x, y, w, h, x, y, w, h);
}
PGraphicsOpenGL.popFramebuffer();
pg.popFramebuffer();
updateTexels(x, y, w, h);
}