diff --git a/app/libEGL.dll b/app/libEGL.dll new file mode 100644 index 0000000000..d3f183f20a Binary files /dev/null and b/app/libEGL.dll differ diff --git a/app/libGLESv2.dll b/app/libGLESv2.dll new file mode 100644 index 0000000000..7f2b28c44e Binary files /dev/null and b/app/libGLESv2.dll differ diff --git a/app/vulkan-1.dll b/app/vulkan-1.dll new file mode 100644 index 0000000000..7268a22d69 Binary files /dev/null and b/app/vulkan-1.dll differ diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8f7211b131..31c0834c42 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,4 +1,5 @@ import com.vanniktech.maven.publish.SonatypeHost +import org.gradle.internal.os.OperatingSystem plugins { id("java") @@ -28,13 +29,53 @@ sourceSets{ } } +val lwjglVersion = "3.3.6" + +val lwjglNatives = Pair( + System.getProperty("os.name")!!, + System.getProperty("os.arch")!! +).let { (name, arch) -> + when { + arrayOf("Linux", "SunOS", "Unit").any { name.startsWith(it) } -> + if (arrayOf("arm", "aarch64").any { arch.startsWith(it) }) + "natives-linux${if (arch.contains("64") || arch.startsWith("armv8")) "-arm64" else "-arm32"}" + else if (arch.startsWith("ppc")) + "natives-linux-ppc64le" + else if (arch.startsWith("riscv")) + "natives-linux-riscv64" + else + "natives-linux" + arrayOf("Mac OS X", "Darwin").any { name.startsWith(it) } -> + "natives-macos${if (arch.startsWith("aarch64")) "-arm64" else ""}" + arrayOf("Windows").any { name.startsWith(it) } -> + "natives-windows" + else -> + throw Error("Unrecognized or unsupported platform. Please set \"lwjglNatives\" manually") + } +} + dependencies { implementation(libs.jogl) implementation(libs.gluegen) + // TODO: Improve this + implementation(files("library/JavaANGLE.jar")) testImplementation(libs.junit) + + // LWJGL + implementation(platform("org.lwjgl:lwjgl-bom:$lwjglVersion")) + implementation("org.lwjgl", "lwjgl") + implementation("org.lwjgl", "lwjgl-egl") + implementation("org.lwjgl", "lwjgl-glfw") + implementation("org.lwjgl", "lwjgl-opengles") + implementation ("org.lwjgl", "lwjgl", classifier = lwjglNatives) + implementation ("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) + implementation ("org.lwjgl", "lwjgl-opengles", classifier = lwjglNatives) + } + + mavenPublishing{ publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) signAllPublications() diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index d21a1fa49d..a12d274d96 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -61,6 +61,8 @@ public interface PConstants { String P2D = "processing.opengl.PGraphics2D"; String P3D = "processing.opengl.PGraphics3D"; + String P2DANGLE = "processing.opengl.PGraphicsANGLE2D"; + String P3DANGLE = "processing.opengl.PGraphicsANGLE3D"; // When will it be time to remove this? @Deprecated diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 0b9f0d2ed4..235984c9a2 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -27,15 +27,12 @@ // Used for color conversion functions import java.awt.Color; - -// Used for the 'image' object that's been here forever import java.awt.Font; import java.awt.Image; - import java.io.File; import java.io.InputStream; -import java.util.Map; import java.util.HashMap; +import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; @@ -7589,6 +7586,7 @@ public void colorMode(int mode, colorModeDefault = (colorMode == RGB) && (colorModeA == 255) && (colorModeX == 255) && (colorModeY == 255) && (colorModeZ == 255); + } diff --git a/core/src/processing/opengl/FrameBuffer.java b/core/src/processing/opengl/FrameBuffer.java index a5426c52d1..2340d1e025 100644 --- a/core/src/processing/opengl/FrameBuffer.java +++ b/core/src/processing/opengl/FrameBuffer.java @@ -445,7 +445,7 @@ protected void initDepthBuffer() { } else if (depthBits == 24) { glConst = PGL.DEPTH_COMPONENT24; } else if (depthBits == 32) { - glConst = PGL.DEPTH_COMPONENT32; + glConst = PGL.DEPTH_COMPONENT32(); } if (multisample) { @@ -474,11 +474,11 @@ protected void initStencilBuffer() { pgl.bindRenderbuffer(PGL.RENDERBUFFER, glStencil); - int glConst = PGL.STENCIL_INDEX1; + int glConst = PGL.STENCIL_INDEX1(); if (stencilBits == 1) { - glConst = PGL.STENCIL_INDEX1; + glConst = PGL.STENCIL_INDEX1(); } else if (stencilBits == 4) { - glConst = PGL.STENCIL_INDEX4; + glConst = PGL.STENCIL_INDEX4(); } else if (stencilBits == 8) { glConst = PGL.STENCIL_INDEX8; } diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 8f8418e16b..310049f95d 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -1119,7 +1119,7 @@ private void createDepthAndStencilBuffer(boolean multisample, int depthBits, if (0 < depthBits) { int depthComponent = DEPTH_COMPONENT16; if (depthBits == 32) { - depthComponent = DEPTH_COMPONENT32; + depthComponent = DEPTH_COMPONENT32(); } else if (depthBits == 24) { depthComponent = DEPTH_COMPONENT24; //} else if (depthBits == 16) { @@ -1141,11 +1141,11 @@ private void createDepthAndStencilBuffer(boolean multisample, int depthBits, } if (0 < stencilBits) { - int stencilIndex = STENCIL_INDEX1; + int stencilIndex = STENCIL_INDEX1(); if (stencilBits == 8) { stencilIndex = STENCIL_INDEX8; } else if (stencilBits == 4) { - stencilIndex = STENCIL_INDEX4; + stencilIndex = STENCIL_INDEX4(); //} else if (stencilBits == 1) { //stencilIndex = STENCIL_INDEX1; } @@ -1195,7 +1195,7 @@ protected boolean contextIsCurrent(int other) { protected void enableTexturing(int target) { if (target == TEXTURE_2D) { texturingTargets[0] = true; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { texturingTargets[1] = true; } } @@ -1204,7 +1204,7 @@ protected void enableTexturing(int target) { protected void disableTexturing(int target) { if (target == TEXTURE_2D) { texturingTargets[0] = false; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { texturingTargets[1] = false; } } @@ -1213,7 +1213,7 @@ protected void disableTexturing(int target) { protected boolean texturingIsEnabled(int target) { if (target == TEXTURE_2D) { return texturingTargets[0]; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { return texturingTargets[1]; } else { return false; @@ -1226,7 +1226,7 @@ protected boolean textureIsBound(int target, int id) { if (target == TEXTURE_2D) { return boundTextures[activeTexUnit][0] == id; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { return boundTextures[activeTexUnit][1] == id; } else { return false; @@ -1317,7 +1317,7 @@ public void drawTexture(int target, int id,int texW, int texH, viewX, viewY, viewW, viewH, viewF, texX0, texY0, texX1, texY1, scrX0, scrY0, scrX1, scrY1); - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { drawTextureRect(id, texW, texH, viewX, viewY, viewW, viewH, viewF, texX0, texY0, texX1, texY1, @@ -1550,11 +1550,11 @@ protected void drawTextureRect(int id, int texW, int texH, activeTexture(TEXTURE0); boolean enabledTex = false; - if (!texturingIsEnabled(TEXTURE_RECTANGLE)) { - enableTexturing(TEXTURE_RECTANGLE); + if (!texturingIsEnabled(TEXTURE_RECTANGLE())) { + enableTexturing(TEXTURE_RECTANGLE()); enabledTex = true; } - bindTexture(TEXTURE_RECTANGLE, id); + bindTexture(TEXTURE_RECTANGLE(), id); uniform1i(ppgl.texRectSamplerLoc, 0); texData.position(0); @@ -1568,9 +1568,9 @@ protected void drawTextureRect(int id, int texW, int texH, bindBuffer(ARRAY_BUFFER, 0); // Making sure that no VBO is bound at this point. - bindTexture(TEXTURE_RECTANGLE, 0); + bindTexture(TEXTURE_RECTANGLE(), 0); if (enabledTex) { - disableTexturing(TEXTURE_RECTANGLE); + disableTexturing(TEXTURE_RECTANGLE()); } disableVertexAttribArray(ppgl.texRectVertLoc); @@ -2122,11 +2122,11 @@ protected int validateFramebuffer() { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "incomplete missing attachment"); } else if (status == FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "incomplete dimensions"); - } else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS) { + } else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS()) { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "incomplete formats"); - } else if (status == FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) { + } else if (status == FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER()) { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "incomplete draw buffer"); - } else if (status == FRAMEBUFFER_INCOMPLETE_READ_BUFFER) { + } else if (status == FRAMEBUFFER_INCOMPLETE_READ_BUFFER()) { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "incomplete read buffer"); } else if (status == FRAMEBUFFER_UNSUPPORTED) { System.err.printf((FRAMEBUFFER_ERROR) + "%n", "framebuffer unsupported"); @@ -2789,6 +2789,74 @@ protected interface FontOutline { void next(); } + public static int ALPHA8() { + System.out.println("UNAVAILABLE ENUM ALPHA8"); + return 0; + } + public static int GENERATE_MIPMAP_HINT() { + System.out.println("UNAVAILABLE ENUM GENERATE_MIPMAP_HINT"); + return 0; + } + public static int TEXTURE_RECTANGLE() { + System.out.println("UNAVAILABLE ENUM TEXTURE_RECTANGLE"); + return 0; + } + public static int TEXTURE_MAX_ANISOTROPY() { + System.out.println("UNAVAILABLE ENUM TEXTURE_MAX_ANISOTROPY"); + return 0; + } + public static int MAX_TEXTURE_MAX_ANISOTROPY() { + System.out.println("UNAVAILABLE ENUM MAX_TEXTURE_MAX_ANISOTROPY"); + return 0; + } + + public static int DEPTH_COMPONENT32() { + System.out.println("UNAVAILABLE ENUM DEPTH_COMPONENT32"); + return 0; + } + + public static int STENCIL_INDEX1() { + System.out.println("UNAVAILABLE ENUM STENCIL_INDEX1"); + return 0; + } + + public static int STENCIL_INDEX4() { + System.out.println("UNAVAILABLE ENUM STENCIL_INDEX4"); + return 0; + } + public static int FRAMEBUFFER_INCOMPLETE_FORMATS() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_FORMATS"); + return 0; + } + + public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"); + return 0; + } + + public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_READ_BUFFER"); + return 0; + } + + + public static int MULTISAMPLE() { + System.out.println("UNAVAILABLE ENUM MULTISAMPLE"); + return 0; + } + + public static int LINE_SMOOTH() { + System.out.println("UNAVAILABLE ENUM LINE_SMOOTH"); + return 0; + } + + public static int POLYGON_SMOOTH() { + System.out.println("UNAVAILABLE ENUM POLYGON_SMOOTH"); + return 0; + } + + + ////////////////////////////////////////////////////////////////////////////// // @@ -2852,7 +2920,7 @@ protected interface FontOutline { public static int RGB565; public static int RGB8; public static int RGBA8; - public static int ALPHA8; + // public static int ALPHA8; public static int READ_ONLY; public static int WRITE_ONLY; @@ -2862,7 +2930,7 @@ protected interface FontOutline { public static int TESS_WINDING_ODD; public static int TESS_EDGE_FLAG; - public static int GENERATE_MIPMAP_HINT; + // public static int GENERATE_MIPMAP_HINT; public static int FASTEST; public static int NICEST; public static int DONT_CARE; @@ -2920,14 +2988,14 @@ protected interface FontOutline { public static int PACK_ALIGNMENT; public static int TEXTURE_2D; - public static int TEXTURE_RECTANGLE; + // public static int TEXTURE_RECTANGLE; public static int TEXTURE_BINDING_2D; public static int TEXTURE_BINDING_RECTANGLE; public static int MAX_TEXTURE_SIZE; - public static int TEXTURE_MAX_ANISOTROPY; - public static int MAX_TEXTURE_MAX_ANISOTROPY; + // public static int TEXTURE_MAX_ANISOTROPY; + // public static int MAX_TEXTURE_MAX_ANISOTROPY; public static int MAX_VERTEX_TEXTURE_IMAGE_UNITS; public static int MAX_TEXTURE_IMAGE_UNITS; @@ -3074,11 +3142,11 @@ protected interface FontOutline { public static int DEPTH_COMPONENT; public static int DEPTH_COMPONENT16; public static int DEPTH_COMPONENT24; - public static int DEPTH_COMPONENT32; + // public static int DEPTH_COMPONENT32; public static int STENCIL_INDEX; - public static int STENCIL_INDEX1; - public static int STENCIL_INDEX4; + // public static int STENCIL_INDEX1; + // public static int STENCIL_INDEX4; public static int STENCIL_INDEX8; public static int DEPTH_STENCIL; @@ -3088,9 +3156,9 @@ protected interface FontOutline { public static int FRAMEBUFFER_INCOMPLETE_ATTACHMENT; public static int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; public static int FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - public static int FRAMEBUFFER_INCOMPLETE_FORMATS; - public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; - public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER; + // public static int FRAMEBUFFER_INCOMPLETE_FORMATS; + // public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; + // public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER; public static int FRAMEBUFFER_UNSUPPORTED; public static int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; public static int FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; @@ -3110,9 +3178,9 @@ protected interface FontOutline { public static int RENDERBUFFER_STENCIL_SIZE; public static int RENDERBUFFER_INTERNAL_FORMAT; - public static int MULTISAMPLE; - public static int LINE_SMOOTH; - public static int POLYGON_SMOOTH; + // public static int MULTISAMPLE; + // public static int LINE_SMOOTH; + // public static int POLYGON_SMOOTH; public static int SYNC_GPU_COMMANDS_COMPLETE; public static int ALREADY_SIGNALED; @@ -3307,7 +3375,7 @@ public void bindTexture(int target, int texture) { if (target == TEXTURE_2D) { boundTextures[activeTexUnit][0] = texture; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { boundTextures[activeTexUnit][1] = texture; } } diff --git a/core/src/processing/opengl/PGLANGLE.java b/core/src/processing/opengl/PGLANGLE.java new file mode 100644 index 0000000000..50c40b9136 --- /dev/null +++ b/core/src/processing/opengl/PGLANGLE.java @@ -0,0 +1,1980 @@ +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.ByteOrder; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.util.HashMap; + +import com.jogamp.opengl.glu.GLU; +import com.jogamp.opengl.glu.GLUtessellator; +import com.jogamp.opengl.glu.GLUtessellatorCallbackAdapter; + +// import org.lwjgl.opengles.GLES.*; +import static org.lwjgl.opengles.GLES20.*; +import static org.lwjgl.opengles.GLES30.*; +import static org.lwjgl.opengles.GLES31.*; +import static org.lwjgl.opengles.GLES32.*; + +import processing.core.PApplet; +import processing.core.PGraphics; +import processing.core.PMatrix3D; +import processing.core.PSurface; + +public class PGLANGLE extends PGL { + + + /////////////////////////////////////////////////////////// + + // Constants + + static { + FALSE = GL_FALSE; + TRUE = GL_TRUE; + + INT = GL_INT; + BYTE = GL_BYTE; + SHORT = GL_SHORT; + FLOAT = GL_FLOAT; + BOOL = GL_BOOL; + UNSIGNED_INT = GL_UNSIGNED_INT; + UNSIGNED_BYTE = GL_UNSIGNED_BYTE; + UNSIGNED_SHORT = GL_UNSIGNED_SHORT; + + RGB = GL_RGB; + RGBA = GL_RGBA; + ALPHA = GL_ALPHA; + LUMINANCE = GL_LUMINANCE; + LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA; + + UNSIGNED_SHORT_5_6_5 = GL_UNSIGNED_SHORT_5_6_5; + UNSIGNED_SHORT_4_4_4_4 = GL_UNSIGNED_SHORT_4_4_4_4; + UNSIGNED_SHORT_5_5_5_1 = GL_UNSIGNED_SHORT_5_5_5_1; + + RGBA4 = GL_RGBA4; + RGB5_A1 = GL_RGB5_A1; + RGB565 = GL_RGB565; + RGB8 = GL_RGB8; + RGBA8 = GL_RGBA8; + // ALPHA8 = 0; // TODO + + READ_ONLY = GL_READ_ONLY; + WRITE_ONLY = GL_WRITE_ONLY; + READ_WRITE = 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_GENERATE_MIPMAP_HINT; // TODO + FASTEST = GL_FASTEST; + NICEST = GL_NICEST; + DONT_CARE = GL_DONT_CARE; + + VENDOR = GL_VENDOR; + RENDERER = GL_RENDERER; + VERSION = GL_VERSION; + EXTENSIONS = GL_EXTENSIONS; + SHADING_LANGUAGE_VERSION = GL_SHADING_LANGUAGE_VERSION; + + MAX_SAMPLES = GL_MAX_SAMPLES; + SAMPLES = GL_SAMPLES; + + ALIASED_LINE_WIDTH_RANGE = GL_ALIASED_LINE_WIDTH_RANGE; + ALIASED_POINT_SIZE_RANGE = GL_ALIASED_POINT_SIZE_RANGE; + + DEPTH_BITS = GL_DEPTH_BITS; + STENCIL_BITS = GL_STENCIL_BITS; + + CCW = GL_CCW; + CW = GL_CW; + + VIEWPORT = GL_VIEWPORT; + + ARRAY_BUFFER = GL_ARRAY_BUFFER; + ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER; + PIXEL_PACK_BUFFER = GL_PIXEL_PACK_BUFFER; + + MAX_VERTEX_ATTRIBS = GL_MAX_VERTEX_ATTRIBS; + + STATIC_DRAW = GL_STATIC_DRAW; + DYNAMIC_DRAW = GL_DYNAMIC_DRAW; + STREAM_DRAW = GL_STREAM_DRAW; + STREAM_READ = GL_STREAM_READ; + + BUFFER_SIZE = GL_BUFFER_SIZE; + BUFFER_USAGE = GL_BUFFER_USAGE; + + POINTS = GL_POINTS; + LINE_STRIP = GL_LINE_STRIP; + LINE_LOOP = GL_LINE_LOOP; + LINES = GL_LINES; + TRIANGLE_FAN = GL_TRIANGLE_FAN; + TRIANGLE_STRIP = GL_TRIANGLE_STRIP; + TRIANGLES = GL_TRIANGLES; + + CULL_FACE = GL_CULL_FACE; + FRONT = GL_FRONT; + BACK = GL_BACK; + FRONT_AND_BACK = GL_FRONT_AND_BACK; + + POLYGON_OFFSET_FILL = GL_POLYGON_OFFSET_FILL; + + UNPACK_ALIGNMENT = GL_UNPACK_ALIGNMENT; + PACK_ALIGNMENT = GL_PACK_ALIGNMENT; + + TEXTURE_2D = GL_TEXTURE_2D; + // TEXTURE_RECTANGLE = 0; // TODO + + TEXTURE_BINDING_2D = GL_TEXTURE_BINDING_2D; + // TEXTURE_BINDING_RECTANGLE = 0; // TODO + + MAX_TEXTURE_SIZE = GL_MAX_TEXTURE_SIZE; + // TEXTURE_MAX_ANISOTROPY = 0; // TODO + // MAX_TEXTURE_MAX_ANISOTROPY = 0; // TODO + + MAX_VERTEX_TEXTURE_IMAGE_UNITS = GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS; + MAX_TEXTURE_IMAGE_UNITS = GL_MAX_TEXTURE_IMAGE_UNITS; + MAX_COMBINED_TEXTURE_IMAGE_UNITS = GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS; + + NUM_COMPRESSED_TEXTURE_FORMATS = GL_NUM_COMPRESSED_TEXTURE_FORMATS; + COMPRESSED_TEXTURE_FORMATS = GL_COMPRESSED_TEXTURE_FORMATS; + + NEAREST = GL_NEAREST; + LINEAR = GL_LINEAR; + LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST; + LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR; + + CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE; + REPEAT = GL_REPEAT; + + TEXTURE0 = GL_TEXTURE0; + TEXTURE1 = GL_TEXTURE1; + TEXTURE2 = GL_TEXTURE2; + TEXTURE3 = GL_TEXTURE3; + TEXTURE_MIN_FILTER = GL_TEXTURE_MIN_FILTER; + TEXTURE_MAG_FILTER = GL_TEXTURE_MAG_FILTER; + TEXTURE_WRAP_S = GL_TEXTURE_WRAP_S; + TEXTURE_WRAP_T = GL_TEXTURE_WRAP_T; + TEXTURE_WRAP_R = GL_TEXTURE_WRAP_R; + + TEXTURE_CUBE_MAP = GL_TEXTURE_CUBE_MAP; + TEXTURE_CUBE_MAP_POSITIVE_X = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + TEXTURE_CUBE_MAP_POSITIVE_Y = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + TEXTURE_CUBE_MAP_POSITIVE_Z = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + TEXTURE_CUBE_MAP_NEGATIVE_X = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + TEXTURE_CUBE_MAP_NEGATIVE_Y = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + TEXTURE_CUBE_MAP_NEGATIVE_Z = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + + VERTEX_SHADER = GL_VERTEX_SHADER; + FRAGMENT_SHADER = GL_FRAGMENT_SHADER; + INFO_LOG_LENGTH = GL_INFO_LOG_LENGTH; + SHADER_SOURCE_LENGTH = GL_SHADER_SOURCE_LENGTH; + COMPILE_STATUS = GL_COMPILE_STATUS; + LINK_STATUS = GL_LINK_STATUS; + VALIDATE_STATUS = GL_VALIDATE_STATUS; + SHADER_TYPE = GL_SHADER_TYPE; + DELETE_STATUS = GL_DELETE_STATUS; + + FLOAT_VEC2 = GL_FLOAT_VEC2; + FLOAT_VEC3 = GL_FLOAT_VEC3; + FLOAT_VEC4 = GL_FLOAT_VEC4; + FLOAT_MAT2 = GL_FLOAT_MAT2; + FLOAT_MAT3 = GL_FLOAT_MAT3; + FLOAT_MAT4 = GL_FLOAT_MAT4; + INT_VEC2 = GL_INT_VEC2; + INT_VEC3 = GL_INT_VEC3; + INT_VEC4 = GL_INT_VEC4; + BOOL_VEC2 = GL_BOOL_VEC2; + BOOL_VEC3 = GL_BOOL_VEC3; + BOOL_VEC4 = GL_BOOL_VEC4; + SAMPLER_2D = GL_SAMPLER_2D; + SAMPLER_CUBE = GL_SAMPLER_CUBE; + + LOW_FLOAT = GL_LOW_FLOAT; + MEDIUM_FLOAT = GL_MEDIUM_FLOAT; + HIGH_FLOAT = GL_HIGH_FLOAT; + LOW_INT = GL_LOW_INT; + MEDIUM_INT = GL_MEDIUM_INT; + HIGH_INT = GL_HIGH_INT; + + CURRENT_VERTEX_ATTRIB = GL_CURRENT_VERTEX_ATTRIB; + + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING; + VERTEX_ATTRIB_ARRAY_ENABLED = GL_VERTEX_ATTRIB_ARRAY_ENABLED; + VERTEX_ATTRIB_ARRAY_SIZE = GL_VERTEX_ATTRIB_ARRAY_SIZE; + VERTEX_ATTRIB_ARRAY_STRIDE = GL_VERTEX_ATTRIB_ARRAY_STRIDE; + VERTEX_ATTRIB_ARRAY_TYPE = GL_VERTEX_ATTRIB_ARRAY_TYPE; + VERTEX_ATTRIB_ARRAY_NORMALIZED = GL_VERTEX_ATTRIB_ARRAY_NORMALIZED; + VERTEX_ATTRIB_ARRAY_POINTER = GL_VERTEX_ATTRIB_ARRAY_POINTER; + + BLEND = GL_BLEND; + ONE = GL_ONE; + ZERO = GL_ZERO; + SRC_ALPHA = GL_SRC_ALPHA; + DST_ALPHA = GL_DST_ALPHA; + ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA; + ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR; + ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR; + DST_COLOR = GL_DST_COLOR; + SRC_COLOR = GL_SRC_COLOR; + + SAMPLE_ALPHA_TO_COVERAGE = GL_SAMPLE_ALPHA_TO_COVERAGE; + SAMPLE_COVERAGE = GL_SAMPLE_COVERAGE; + + KEEP = GL_KEEP; + REPLACE = GL_REPLACE; + INCR = GL_INCR; + DECR = GL_DECR; + INVERT = GL_INVERT; + INCR_WRAP = GL_INCR_WRAP; + DECR_WRAP = GL_DECR_WRAP; + NEVER = GL_NEVER; + ALWAYS = GL_ALWAYS; + + EQUAL = GL_EQUAL; + LESS = GL_LESS; + LEQUAL = GL_LEQUAL; + GREATER = GL_GREATER; + GEQUAL = GL_GEQUAL; + NOTEQUAL = GL_NOTEQUAL; + + FUNC_ADD = GL_FUNC_ADD; + FUNC_MIN = GL_MIN; + FUNC_MAX = GL_MAX; + FUNC_REVERSE_SUBTRACT = GL_FUNC_REVERSE_SUBTRACT; + FUNC_SUBTRACT = GL_FUNC_SUBTRACT; + + DITHER = GL_DITHER; + + CONSTANT_COLOR = GL_CONSTANT_COLOR; + CONSTANT_ALPHA = GL_CONSTANT_ALPHA; + ONE_MINUS_CONSTANT_COLOR = GL_ONE_MINUS_CONSTANT_COLOR; + ONE_MINUS_CONSTANT_ALPHA = GL_ONE_MINUS_CONSTANT_ALPHA; + SRC_ALPHA_SATURATE = GL_SRC_ALPHA_SATURATE; + + SCISSOR_TEST = GL_SCISSOR_TEST; + STENCIL_TEST = GL_STENCIL_TEST; + DEPTH_TEST = GL_DEPTH_TEST; + DEPTH_WRITEMASK = GL_DEPTH_WRITEMASK; + + COLOR_BUFFER_BIT = GL_COLOR_BUFFER_BIT; + DEPTH_BUFFER_BIT = GL_DEPTH_BUFFER_BIT; + STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT; + + FRAMEBUFFER = GL_FRAMEBUFFER; + COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0; + COLOR_ATTACHMENT1 = GL_COLOR_ATTACHMENT1; + COLOR_ATTACHMENT2 = GL_COLOR_ATTACHMENT2; + COLOR_ATTACHMENT3 = GL_COLOR_ATTACHMENT3; + RENDERBUFFER = GL_RENDERBUFFER; + DEPTH_ATTACHMENT = GL_DEPTH_ATTACHMENT; + STENCIL_ATTACHMENT = GL_STENCIL_ATTACHMENT; + READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER; + DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER; + + DEPTH24_STENCIL8 = GL_DEPTH24_STENCIL8; + + DEPTH_COMPONENT = GL_DEPTH_COMPONENT; + DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16; + DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24; + // DEPTH_COMPONENT32 = 0; // TODO + STENCIL_INDEX = GL_STENCIL_INDEX; + // STENCIL_INDEX1 = 0; // TODO + // STENCIL_INDEX4 = 0; // TODO + STENCIL_INDEX8 = GL_STENCIL_INDEX8; + + DEPTH_STENCIL = GL_DEPTH_STENCIL; + + FRAMEBUFFER_COMPLETE = GL_FRAMEBUFFER_COMPLETE; + FRAMEBUFFER_UNDEFINED = GL_FRAMEBUFFER_UNDEFINED; + FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + // FRAMEBUFFER_INCOMPLETE_FORMATS = 0; // TODO + // FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0; // TODO + // FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0; // TODO + FRAMEBUFFER_UNSUPPORTED = GL_FRAMEBUFFER_UNSUPPORTED; + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; + + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE; + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME; + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL; + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE; + + RENDERBUFFER_WIDTH = GL_RENDERBUFFER_WIDTH; + RENDERBUFFER_HEIGHT = GL_RENDERBUFFER_HEIGHT; + RENDERBUFFER_RED_SIZE = GL_RENDERBUFFER_RED_SIZE; + RENDERBUFFER_GREEN_SIZE = GL_RENDERBUFFER_GREEN_SIZE; + RENDERBUFFER_BLUE_SIZE = GL_RENDERBUFFER_BLUE_SIZE; + RENDERBUFFER_ALPHA_SIZE = GL_RENDERBUFFER_ALPHA_SIZE; + RENDERBUFFER_DEPTH_SIZE = GL_RENDERBUFFER_DEPTH_SIZE; + RENDERBUFFER_STENCIL_SIZE = GL_RENDERBUFFER_STENCIL_SIZE; + RENDERBUFFER_INTERNAL_FORMAT = GL_RENDERBUFFER_INTERNAL_FORMAT; + + // MULTISAMPLE = 0; // TODO + // LINE_SMOOTH = 0; + // POLYGON_SMOOTH = 0; + + SYNC_GPU_COMMANDS_COMPLETE = GL_SYNC_GPU_COMMANDS_COMPLETE; + ALREADY_SIGNALED = GL_ALREADY_SIGNALED; + CONDITION_SATISFIED = GL_CONDITION_SATISFIED; + } + + protected float[] projMatrix; + protected FloatBuffer projMatrixBuffer; + protected float[] mvMatrix; + + private HashMap buffers = new HashMap(); + private int boundBuffer = -1; + + private ByteBuffer getBoundBuffer(int offset) { + ByteBuffer buff = buffers.get(boundBuffer); + + if (buff == null) { + System.err.println("unbound buffer"); + return null; + } + + if (offset > 0) { + return buff.slice(offset, buff.capacity()-offset); + } + + return buff; + } + + private void report(String m) { + System.out.println(m); + } + + public static ByteBuffer convertToByteBuffer(Buffer outputBuffer) { + if (outputBuffer == null) return null; + + ByteBuffer byteBuffer = null; + if (outputBuffer instanceof ByteBuffer) { + // System.out.println("ByteBuffer"); + byteBuffer = (ByteBuffer) outputBuffer; + } else if (outputBuffer instanceof CharBuffer) { + // System.out.println("CharBuffer"); + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Character.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Character.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asCharBuffer().put((CharBuffer) outputBuffer); + } else if (outputBuffer instanceof ShortBuffer) { + // System.out.println("ShortBuffer"); + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Short.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Short.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asShortBuffer().put((ShortBuffer) outputBuffer); + } else if (outputBuffer instanceof IntBuffer) { + // System.out.println("IntBuffer"); + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Integer.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Integer.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asIntBuffer().put((IntBuffer) outputBuffer); + } else if (outputBuffer instanceof LongBuffer) { + // System.out.println("LongBuffer"); + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Long.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Long.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asLongBuffer().put((LongBuffer) outputBuffer); + } else if (outputBuffer instanceof FloatBuffer) { + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Float.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Float.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asFloatBuffer().put((FloatBuffer) outputBuffer); + } else if (outputBuffer instanceof DoubleBuffer) { + // System.out.println("DoubleBuffer"); + if (outputBuffer.isDirect()) byteBuffer = ByteBuffer.allocateDirect(outputBuffer.capacity() * Double.BYTES); + else byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * Double.BYTES); + + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asDoubleBuffer().put((DoubleBuffer) outputBuffer); + } + else { + System.err.println("Unknown buffer "+outputBuffer.getClass().toString()); + } + return byteBuffer; + } + + public PGLANGLE(PGraphicsOpenGL pg) { + super(pg); + } + + @Override + public Object getNative() { + report("Object getNative"); + return null; + } + + @Override + protected void initFBOLayer() { + if (0 < sketch.frameCount) { + // if (isES()) initFBOLayerES(); + initFBOLayerES(); + // else + // initFBOLayerGL(); + } + } + + @Override + protected boolean isES() { + return true; + } + + + + 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); + } + + + 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); + } + + @Override + public boolean threadIsCurrent() { + return true; // TODO: actual check instead of always true. + } + + @Override + protected void setFrameRate(float fps) { + report("void setFrameRate"); + + } + + @Override + protected void initSurface(int antialias) { + report("void initSurface"); + + } + + @Override + protected void reinitSurface() { + report("void reinitSurface"); + + } + + @Override + protected void registerListeners() { + report("void registerListeners"); + + } + + @Override + protected int getDepthBits() { + report("int getDepthBits"); + return GL_DEPTH_BITS; + } + + @Override + protected int getStencilBits() { + report("int getStencilBits"); + return GL_STENCIL_BITS; + } + + @Override + protected float getPixelScale() { + report("float getPixelScale"); + PSurface surf = sketch.getSurface(); + if (surf == null) { + return graphics.pixelDensity; + } else if (surf instanceof PSurfaceJOGL) { + return ((PSurfaceJOGL)surf).getPixelScale(); + } else if (surf instanceof PSurfaceANGLE) { + return ((PSurfaceANGLE)surf).getPixelScale(); + }else { + throw new RuntimeException("Renderer cannot find a JOGL surface"); + } + + } + + @Override + protected void getGL(PGL pgl) { + report("void getGL"); + + } + + @Override + protected boolean canDraw() { + report("boolean canDraw"); + return true; + } + + @Override + protected void requestFocus() { + report("void requestFocus"); + + } + + @Override + protected void requestDraw() { + report("void requestDraw"); + + } + + @Override + protected void swapBuffers() { + report("void swapBuffers"); + PSurfaceANGLE surf = (PSurfaceANGLE)sketch.getSurface(); + surf.swapBuffers(); + System.out.println("SWAP!!"); + } + + @Override + protected void beginGL() { + report("void beginGL"); + PMatrix3D proj = graphics.projection; + PMatrix3D mdl = graphics.modelview; + if (projMatrix == null) { + projMatrix = new float[16]; + + ByteBuffer buffer = ByteBuffer.allocateDirect(Float.BYTES*16); + buffer.order(ByteOrder.LITTLE_ENDIAN); + projMatrixBuffer = buffer.asFloatBuffer(); + } + + + // glMatrixMode(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; + // projMatrixBuffer.rewind(); + // projMatrixBuffer.put(projMatrix); + // glLoadMatrixf(projMatrixBuffer); + + // if (mvMatrix == null) { + // mvMatrix = new float[16]; + // } + // glMatrixMode(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; + + // projMatrixBuffer.rewind(); + // projMatrixBuffer.put(projMatrix); + // glLoadMatrixf(projMatrixBuffer); + } + + @Override + protected boolean hasFBOs() { + report("boolean hasFBOs"); + // if (context.hasBasicFBOSupport()) return true; + // else + return super.hasFBOs(); + } + + + @Override + protected boolean hasShaders() { + report("boolean hasShaders"); + // if (context.hasGLSL()) return true; + // else + return super.hasShaders(); + } + + + @Override + protected void enableTexturing(int target) { + report("void enableTexturing"); + if (target == TEXTURE_2D) { + texturingTargets[0] = true; + } else if (target == TEXTURE_RECTANGLE()) { + texturingTargets[1] = true; + } + } + + + @Override + protected void disableTexturing(int target) { + report("void disableTexturing"); + if (target == TEXTURE_2D) { + texturingTargets[0] = false; + } else if (target == TEXTURE_RECTANGLE()) { + texturingTargets[1] = false; + } + } + + @Override + protected String[] loadVertexShader(String filename) { + report("String[] loadVertexShader"); + return loadVertexShader(filename, getGLSLVersion(), getGLSLVersionSuffix()); + } + + + @Override + protected String[] loadFragmentShader(String filename) { + report("String[] loadFragmentShader"); + return loadFragmentShader(filename, getGLSLVersion(), getGLSLVersionSuffix()); + } + + + @Override + protected String[] loadVertexShader(URL url) { + report("String[] loadVertexShader"); + return loadVertexShader(url, getGLSLVersion(), getGLSLVersionSuffix()); + } + + + @Override + protected String[] loadFragmentShader(URL url) { + report("String[] loadFragmentShader"); + return loadFragmentShader(url, getGLSLVersion(), getGLSLVersionSuffix()); + } + + + @Override + protected String[] loadFragmentShader(String filename, int version, String versionSuffix) { + report("String[] loadFragmentShader"); + String[] fragSrc0 = sketch.loadStrings(filename); + return preprocessFragmentSource(fragSrc0, version, versionSuffix); + } + + + @Override + protected String[] loadVertexShader(String filename, int version, String versionSuffix) { + report("String[] loadVertexShader"); + String[] vertSrc0 = sketch.loadStrings(filename); + return preprocessVertexSource(vertSrc0, version, versionSuffix); + } + + + @Override + protected String[] loadFragmentShader(URL url, int version, String versionSuffix) { + report("String[] loadFragmentShader"); + 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) { + report("String[] loadVertexShader"); + 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; + } + + + + @Override + protected int getGLSLVersion() { + report("int getGLSLVersion"); + return 30020; + // return 0; + } + + @Override + protected String getGLSLVersionSuffix() { + report("String getGLSLVersionSuffix"); + return " es"; + } + + @SuppressWarnings("deprecation") + private FontMetrics getFontMetrics(Font font) { // ignore + report("FontMetrics getFontMetrics"); + return Toolkit.getDefaultToolkit().getFontMetrics(font); + } + + @Override + protected int getTextWidth(Object font, char[] buffer, int start, int stop) { + report("int getTextWidth"); + int length = stop - start; + FontMetrics metrics = getFontMetrics((Font) font); + return metrics.charsWidth(buffer, start, length); + } + + @Override + protected Object getDerivedFont(Object font, float size) { + report("Object getDerivedFont"); + return ((Font) font).deriveFont(size); + + } + + + @Override + protected Tessellator createTessellator(TessellatorCallback callback) { + report("Tessellator createTessellator"); + + 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); + } + + @Override + 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); + } + } + } + + private FontRenderContext getFontRenderContext(Font font) { // ignore + report("FontRenderContext getFontRenderContext"); + return getFontMetrics(font).getFontRenderContext(); + } + + protected class FontOutline implements PGL.FontOutline { + PathIterator iter; + + public FontOutline(char ch, Font font) { + report("FontOutline"); + 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() { + report("boolean isDone"); + return iter.isDone(); + } + + public int currentSegment(float[] coords) { + report("int currentSegment"); + return iter.currentSegment(coords); + } + + public void next() { + report("void next"); + iter.next(); + } + } + + + @Override + protected FontOutline createFontOutline(char ch, Object font) { + report("FontOutline createFontOutline"); + return new FontOutline(ch, (Font) font); + } + + @Override + public void flush() { + report("void flush"); + glFlush(); + } + + @Override + public void finish() { + report("void finish"); + glFinish(); + } + + @Override + public void hint(int target, int hint) { + report("void hint"); + glHint(target, hint); + } + + @Override + public void enable(int value) { + report("void enable"); + if (-1 < value) { + glEnable(value); + } + } + + @Override + public void disable(int value) { + report("void disable"); + if (-1 < value) { + glDisable(value); + } + } + + @Override + public void getBooleanv(int value, IntBuffer data) { + report("void getBooleanv"); + if (data == null) return; + if (-1 < value) { + if (byteBuffer.capacity() < data.capacity()) { + byteBuffer = allocateDirectByteBuffer(data.capacity()); + } + 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) { + report("void getIntegerv"); + if (data == null) return; + if (-1 < value) { + glGetIntegerv(value, data); + } else { + fillIntBuffer(data, 0, data.capacity() - 1, 0); + } + } + + @Override + public void getFloatv(int value, FloatBuffer data) { + report("void getFloatv"); + if (data == null) return; + if (-1 < value) { + glGetFloatv(value, data); + } else { + fillFloatBuffer(data, 0, data.capacity() - 1, 0); + } + } + + @Override + public boolean isEnabled(int value) { + report("boolean isEnabled"); + return glIsEnabled(value); + } + + @Override + public String getString(int name) { + report("String getString"); + return glGetString(name); + } + + @Override + public int getError() { + report("int getError"); + return glGetError(); + } + + @Override + public String errorString(int err) { + report("String errorString"); + return ""; + } + + @Override + public void genBuffers(int n, IntBuffer buffers) { + report("void genBuffers"); + if (buffers == null) return; + glGenBuffers(buffers); + } + + @Override + public void deleteBuffers(int n, IntBuffer buffers) { + report("void deleteBuffers"); + if (buffers == null) return; + glDeleteBuffers(buffers); + } + + @Override + public void bindBuffer(int target, int buffer) { + report("void bindBuffer"); + boundBuffer = buffer; + glBindBuffer(target, buffer); + } + + @Override + public void bufferData(int target, int size, Buffer data, int usage) { + report("void bufferData"); + + if (data == null) { + long sizel = (long)size; + glBufferData(target, sizel, usage); + return; + } + buffers.put(boundBuffer, convertToByteBuffer(data)); + + // Thread.dumpStack(); + + // System.out.println(data.getClass().getName()); + + glBufferData(target, convertToByteBuffer(data), usage); + } + + @Override + public void bufferSubData(int target, int offset, int size, Buffer data) { + report("void bufferSubData"); + // buffers.put(boundBuffer, data); + + // TODO: Oh god we got to write our own buffersubdata for the + // buffers hashmap oh god. + + glBufferSubData(target, offset, convertToByteBuffer(data)); + } + + @Override + public void isBuffer(int buffer) { + report("void isBuffer"); + glIsBuffer(buffer); + } + + @Override + public void getBufferParameteriv(int target, int value, IntBuffer data) { + report("void getBufferParameteriv"); + if (data == null) return; + glGetBufferParameteriv(target, value, data); + } + + @Override + public ByteBuffer mapBuffer(int target, int access) { + report("ByteBuffer mapBuffer"); + return null; + } + + @Override + public ByteBuffer mapBufferRange(int target, int offset, int length, int access) { + report("ByteBuffer mapBufferRange"); + // TODO: wow. + // return glMapBufferRange(target, offset, length, access); + return null; + } + + @Override + public void unmapBuffer(int target) { + report("void unmapBuffer"); + glUnmapBuffer(target); + + } + + @Override + public long fenceSync(int condition, int flags) { + report("long fenceSync"); + return glFenceSync(condition, flags); + } + + @Override + public void deleteSync(long sync) { + report("void deleteSync"); + glDeleteSync(sync); + } + + @Override + public int clientWaitSync(long sync, int flags, long timeout) { + report("int clientWaitSync"); + return glClientWaitSync(sync, flags, timeout); + } + + @Override + public void depthRangef(float n, float f) { + report("void depthRangef"); + // TODO: Oops. + // glDepthRange(n, f); + } + + @Override + public void viewport(int x, int y, int w, int h) { + report("void viewport"); + 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) { + report("void viewportImpl"); + glViewport(x, y, w, h); + } + + @Override + protected void readPixelsImpl(int x, int y, int width, int height, int format, int type, Buffer buffer) { + report("void readPixelsImpl"); + if (buffer == null) return; + glReadPixels(x, y, width, height, format, type, convertToByteBuffer(buffer)); + } + + @Override + protected void readPixelsImpl(int x, int y, int width, int height, int format, int type, long offset) { + report("void readPixelsImpl"); + // TODO + // glReadPixels(x, y, width, height, format, type, 0); + } + + @Override + public void vertexAttrib1f(int index, float value) { + report("void vertexAttrib1f"); + glVertexAttrib1f(index, value); + } + + @Override + public void vertexAttrib2f(int index, float value0, float value1) { + report("void vertexAttrib2f"); + glVertexAttrib2f(index, value0, value1); + } + + @Override + public void vertexAttrib3f(int index, float value0, float value1, float value2) { + report("void vertexAttrib3f"); + glVertexAttrib3f(index, value0, value1, value2); + } + + @Override + public void vertexAttrib4f(int index, float value0, float value1, float value2, float value3) { + report("void vertexAttrib4f"); + glVertexAttrib4f(index, value0, value1, value2, value3); + } + + @Override + public void vertexAttrib1fv(int index, FloatBuffer values) { + report("void vertexAttrib1fv"); + if (values == null) return; + glVertexAttrib1fv(index, values); + } + + @Override + public void vertexAttrib2fv(int index, FloatBuffer values) { + report("void vertexAttrib2fv"); + if (values == null) return; + glVertexAttrib2fv(index, values); + } + + @Override + public void vertexAttrib3fv(int index, FloatBuffer values) { + report("void vertexAttrib3fv"); + if (values == null) return; + glVertexAttrib3fv(index, values); + } + + @Override + public void vertexAttrib4fv(int index, FloatBuffer values) { + report("void vertexAttrib4fv"); + if (values == null) return; + glVertexAttrib4fv(index, values); + } + + @Override + public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, int offset) { + report("void vertexAttribPointer"); + + System.out.println("Stride: "+stride); + + // ByteBuffer buff = getBoundBuffer(offset); + // if (buff == null) return; + glVertexAttribPointer(index, size, type, normalized, stride, offset); + } + + @Override + public void enableVertexAttribArray(int index) { + report("void enableVertexAttribArray"); + glEnableVertexAttribArray(index); + } + + @Override + public void disableVertexAttribArray(int index) { + report("void disableVertexAttribArray"); + glDisableVertexAttribArray(index); + } + + @Override + public void drawArraysImpl(int mode, int first, int count) { + report("void drawArraysImpl"); + glDrawArrays(mode, first, count); + } + + @Override + public void drawElementsImpl(int mode, int count, int type, int offset) { + report("void drawElementsImpl"); + // ByteBuffer buff = getBoundBuffer(offset); + // if (buff == null) return; + + // // System.out.println("drawElements buffer "+boundBuffer); + // System.out.println("Requested count: "+count+" Expected count: 256 Capacity count: "+(buff.capacity()/2)+" Limit count: "+(buff.limit()/2)); + + glDrawElements(mode, count, type, offset); + } + + @Override + public void lineWidth(float width) { + report("void lineWidth"); + glLineWidth(width); + } + + @Override + public void frontFace(int dir) { + report("void frontFace"); + glFrontFace(dir); + } + + @Override + public void cullFace(int mode) { + report("void cullFace"); + glCullFace(mode); + } + + @Override + public void polygonOffset(float factor, float units) { + report("void polygonOffset"); + glPolygonOffset(factor, units); + } + + @Override + public void pixelStorei(int pname, int param) { + report("void pixelStorei"); + glPixelStorei(pname, param); + + } + + @Override + public void texImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer data) { + report("void texImage2D"); + if (data == null) return; + glTexImage2D(target, level, internalFormat, width, height, border, format, type, convertToByteBuffer(data)); + } + + @Override + public void copyTexImage2D(int target, int level, int internalFormat, int x, int y, int width, int height, int border) { + report("void copyTexImage2D"); + 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) { + report("void texSubImage2D"); + if (data == null) return; + // glTextSubImage2D(target, level, xOffset, yOffset, width, height, format, type, convertToByteBuffer(data)); + } + + @Override + public void copyTexSubImage2D(int target, int level, int xOffset, int yOffset, int x, int y, int width, int height) { + report("void copyTexSubImage2D"); + glCopyTexSubImage2D(target, level, xOffset, yOffset, x, y, width, height); + } + + @Override + public void compressedTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int imageSize, Buffer data) { + report("void compressedTexImage2D"); + if (data == null) return; + // glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, convertToByteBuffer(data)); + } + + @Override + public void compressedTexSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int imageSize, Buffer data) { + report("void compressedTexSubImage2D"); + if (data == null) return; + + } + + @Override + public void texParameteri(int target, int pname, int param) { + report("void texParameteri"); + glTexParameteri(target, pname, param); + } + + @Override + public void texParameterf(int target, int pname, float param) { + report("void texParameterf"); + glTexParameterf(target, pname, param); + } + + @Override + public void texParameteriv(int target, int pname, IntBuffer params) { + report("void texParameteriv"); + if (params == null) return; + glTexParameteriv(target, pname, params); + } + + @Override + public void texParameterfv(int target, int pname, FloatBuffer params) { + report("void texParameterfv"); + if (params == null) return; + glTexParameterfv(target, pname, params); + } + + @Override + public void generateMipmap(int target) { + report("void generateMipmap"); + glGenerateMipmap(target); + } + + @Override + public void genTextures(int n, IntBuffer textures) { + report("void genTextures"); + if (textures == null) return; + glGenTextures(textures); + } + + @Override + public void deleteTextures(int n, IntBuffer textures) { + report("void deleteTextures"); + if (textures == null) return; + glDeleteTextures(textures); + } + + @Override + public void getTexParameteriv(int target, int pname, IntBuffer params) { + report("void getTexParameteriv"); + if (params == null) return; + glGetTexParameteriv(target, pname, params); + } + + @Override + public void getTexParameterfv(int target, int pname, FloatBuffer params) { + report("void getTexParameterfv"); + if (params == null) return; + glGetTexParameterfv(target, pname, params); + } + + @Override + public boolean isTexture(int texture) { + report("boolean isTexture"); + return glIsTexture(texture); + } + + @Override + protected void activeTextureImpl(int texture) { + report("void activeTextureImpl"); + glActiveTexture(texture); + } + + @Override + protected void bindTextureImpl(int target, int texture) { + report("void bindTextureImpl"); + glBindTexture(target, texture); + } + + @Override + public int createShader(int type) { + report("int createShader"); + return glCreateShader(type); + } + + @Override + public void shaderSource(int shader, String source) { + // System.out.println(source); + report("void shaderSource"); + + glShaderSource(shader, source); + } + + @Override + public void compileShader(int shader) { + report("void compileShader"); + glCompileShader(shader); + } + + @Override + public void releaseShaderCompiler() { + report("void releaseShaderCompiler"); + glReleaseShaderCompiler(); + } + + @Override + public void deleteShader(int shader) { + report("void deleteShader"); + glDeleteShader(shader); + } + + @Override + public void shaderBinary(int count, IntBuffer shaders, int binaryFormat, Buffer binary, int length) { + report("void shaderBinary"); + if (shaders == null || binary == null) return; + // glShaderBinary(count, shaders, binaryFormat, binary, length); + } + + @Override + public int createProgram() { + report("int createProgram"); + return glCreateProgram(); + } + + @Override + public void attachShader(int program, int shader) { + report("void attachShader"); + glAttachShader(program, shader); + } + + @Override + public void detachShader(int program, int shader) { + report("void detachShader"); + glDetachShader(program, shader); + } + + @Override + public void linkProgram(int program) { + report("void linkProgram"); + glLinkProgram(program); + } + + @Override + public void useProgram(int program) { + report("void useProgram"); + glUseProgram(program); + } + + @Override + public void deleteProgram(int program) { + report("void deleteProgram"); + glDeleteProgram(program); + } + + @Override + public String getActiveAttrib(int program, int index, IntBuffer size, IntBuffer type) { + report("String getActiveAttrib"); + if (size == null || type == null) return null; + return glGetActiveAttrib(program, index, size, type); + } + + @Override + public int getAttribLocation(int program, String name) { + report("int getAttribLocation"); + return glGetAttribLocation(program, name); + } + + @Override + public void bindAttribLocation(int program, int index, String name) { + report("void bindAttribLocation"); + glBindAttribLocation(program, index, name); + } + + @Override + public int getUniformLocation(int program, String name) { + report("int getUniformLocation"); + return glGetUniformLocation(program, name); + } + + @Override + public String getActiveUniform(int program, int index, IntBuffer size, IntBuffer type) { + report("String getActiveUniform"); + if (size == null || type == null) return null; + return glGetActiveUniform(program, index, size, type); + } + + @Override + public void uniform1i(int location, int value) { + report("void uniform1i"); + glUniform1i(location, value); + } + + @Override + public void uniform2i(int location, int value0, int value1) { + report("void uniform2i"); + glUniform2i(location, value0, value1); + } + + @Override + public void uniform3i(int location, int value0, int value1, int value2) { + report("void uniform3i"); + glUniform3i(location, value0, value1, value2); + } + + @Override + public void uniform4i(int location, int value0, int value1, int value2, int value3) { + report("void uniform4i"); + glUniform4i(location, value0, value1, value2, value3); + } + + @Override + public void uniform1f(int location, float value) { + report("void uniform1f"); + glUniform1f(location, value); + } + + @Override + public void uniform2f(int location, float value0, float value1) { + report("void uniform2f"); + glUniform2f(location, value0, value1); + } + + @Override + public void uniform3f(int location, float value0, float value1, float value2) { + report("void uniform3f"); + glUniform3f(location, value0, value1, value2); + } + + @Override + public void uniform4f(int location, float value0, float value1, float value2, float value3) { + report("void uniform4f"); + glUniform4f(location, value0, value1, value2, value3); + } + + @Override + public void uniform1iv(int location, int count, IntBuffer v) { + report("void uniform1iv"); + if (v == null) return; + glUniform1iv(location, v); + } + + @Override + public void uniform2iv(int location, int count, IntBuffer v) { + report("void uniform2iv"); + if (v == null) return; + glUniform2iv(location, v); + } + + @Override + public void uniform3iv(int location, int count, IntBuffer v) { + report("void uniform3iv"); + if (v == null) return; + glUniform3iv(location, v); + } + + @Override + public void uniform4iv(int location, int count, IntBuffer v) { + report("void uniform4iv"); + if (v == null) return; + glUniform4iv(location, v); + } + + @Override + public void uniform1fv(int location, int count, FloatBuffer v) { + report("void uniform1fv"); + if (v == null) return; + glUniform1fv(location, v); + } + + @Override + public void uniform2fv(int location, int count, FloatBuffer v) { + report("void uniform2fv"); + if (v == null) return; + glUniform2fv(location, v); + } + + @Override + public void uniform3fv(int location, int count, FloatBuffer v) { + report("void uniform3fv"); + if (v == null) return; + glUniform3fv(location, v); + } + + @Override + public void uniform4fv(int location, int count, FloatBuffer v) { + report("void uniform4fv"); + if (v == null) return; + glUniform4fv(location, v); + } + + @Override + public void uniformMatrix2fv(int location, int count, boolean transpose, FloatBuffer mat) { + report("void uniformMatrix2fv"); + if (mat == null) return; + glUniformMatrix2fv(location, transpose, mat); + } + + @Override + public void uniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer mat) { + report("void uniformMatrix3fv"); + if (mat == null) return; + glUniformMatrix3fv(location, transpose, mat); + } + + @Override + public void uniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer mat) { + report("void uniformMatrix4fv"); + if (mat == null) return; + glUniformMatrix4fv(location, transpose, mat); + } + + @Override + public void validateProgram(int program) { + report("void validateProgram"); + glValidateProgram(program); + } + + @Override + public boolean isShader(int shader) { + report("boolean isShader"); + return glIsShader(shader); + } + + @Override + public void getShaderiv(int shader, int pname, IntBuffer params) { + report("void getShaderiv"); + if (params == null) return; + glGetShaderiv(shader, pname, params); + } + + @Override + public void getAttachedShaders(int program, int maxCount, IntBuffer count, IntBuffer shaders) { + report("void getAttachedShaders"); + if (count == null || shaders == null) return; + glGetAttachedShaders(program, count, shaders); + } + + @Override + public String getShaderInfoLog(int shader) { + report("String getShaderInfoLog"); + String log = glGetShaderInfoLog(shader); + System.out.println(log); + return log; + } + + @Override + public String getShaderSource(int shader) { + report("String getShaderSource"); + return glGetShaderSource(shader); + } + + @Override + public void getShaderPrecisionFormat(int shaderType, int precisionType, IntBuffer range, IntBuffer precision) { + report("void getShaderPrecisionFormat"); + if (range == null || precision == null) return; + glGetShaderPrecisionFormat(shaderType, precisionType, range, precision); + } + + @Override + public void getVertexAttribfv(int index, int pname, FloatBuffer params) { + report("void getVertexAttribfv"); + if (params == null) return; + glGetVertexAttribfv(index, pname, params); + } + + @Override + public void getVertexAttribiv(int index, int pname, IntBuffer params) { + report("void getVertexAttribiv"); + if (params == null) return; + glGetVertexAttribiv(index, pname, params); + } + + @Override + public void getVertexAttribPointerv(int index, int pname, ByteBuffer data) { + report("void getVertexAttribPointerv"); + if (data == null) return; + // glGetVertexAttribPointerv(index, pname, data); + } + + @Override + public void getUniformfv(int program, int location, FloatBuffer params) { + report("void getUniformfv"); + if (params == null) return; + glGetUniformfv(program, location, params); + } + + @Override + public void getUniformiv(int program, int location, IntBuffer params) { + report("void getUniformiv"); + if (params == null) return; + glGetUniformiv(program, location, params); + } + + @Override + public boolean isProgram(int program) { + report("boolean isProgram"); + return glIsProgram(program); + } + + @Override + public void getProgramiv(int program, int pname, IntBuffer params) { + report("void getProgramiv"); + if (params == null) return; + glGetProgramiv(program, pname, params); + } + + @Override + public String getProgramInfoLog(int program) { + report("String getProgramInfoLog"); + return glGetProgramInfoLog(program); + } + + @Override + public void scissor(int x, int y, int w, int h) { + report("void scissor"); + glScissor(x,y,w,h); + } + + @Override + public void sampleCoverage(float value, boolean invert) { + report("void sampleCoverage"); + glSampleCoverage(value, invert); + } + + @Override + public void stencilFunc(int func, int ref, int mask) { + report("void stencilFunc"); + glStencilFunc(func, ref, mask); + } + + @Override + public void stencilFuncSeparate(int face, int func, int ref, int mask) { + report("void stencilFuncSeparate"); + glStencilFuncSeparate(face, func, ref, mask); + } + + @Override + public void stencilOp(int sfail, int dpfail, int dppass) { + report("void stencilOp"); + glStencilOp(sfail, dpfail, dppass); + } + + @Override + public void stencilOpSeparate(int face, int sfail, int dpfail, int dppass) { + report("void stencilOpSeparate"); + glStencilOpSeparate(face, sfail, dpfail, dppass); + } + + @Override + public void depthFunc(int func) { + report("void depthFunc"); + glDepthFunc(func); + } + + @Override + public void blendEquation(int mode) { + report("void blendEquation"); + glBlendEquation(mode); + } + + @Override + public void blendEquationSeparate(int modeRGB, int modeAlpha) { + report("void blendEquationSeparate"); + glBlendEquationSeparate(modeRGB, modeAlpha); + } + + @Override + public void blendFunc(int src, int dst) { + report("void blendFunc"); + glBlendFunc(src, dst); + } + + @Override + public void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) { + report("void blendFuncSeparate"); + glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + } + + @Override + public void blendColor(float red, float green, float blue, float alpha) { + report("void blendColor"); + glBlendColor(red, green, blue, alpha); + } + + @Override + public void colorMask(boolean r, boolean g, boolean b, boolean a) { + report("void colorMask"); + glColorMask(r, g, b, a); + } + + @Override + public void depthMask(boolean mask) { + report("void depthMask"); + glDepthMask(mask); + } + + @Override + public void stencilMask(int mask) { + report("void stencilMask"); + glStencilMask(mask); + } + + @Override + public void stencilMaskSeparate(int face, int mask) { + report("void stencilMaskSeparate"); + glStencilMaskSeparate(face, mask); + } + + @Override + public void clearColor(float r, float g, float b, float a) { + report("void clearColor"); + glClearColor(r,g,b,a); + } + + @Override + public void clearDepth(float d) { + report("void clearDepth"); + glClearDepthf(d); + } + + @Override + public void clearStencil(int s) { + report("void clearStencil"); + glClearStencil(s); + } + + @Override + public void clear(int buf) { + report("void clear"); + glClear(buf); + } + + @Override + protected void bindFramebufferImpl(int target, int framebuffer) { + report("void bindFramebufferImpl"); + glBindFramebuffer(target, framebuffer); + } + + @Override + public void deleteFramebuffers(int n, IntBuffer framebuffers) { + report("void deleteFramebuffers"); + if (framebuffers == null) return; + glDeleteFramebuffers(framebuffers); + } + + @Override + public void genFramebuffers(int n, IntBuffer framebuffers) { + report("void genFramebuffers"); + if (framebuffers == null) return; + glGenFramebuffers(framebuffers); + } + + @Override + public void bindRenderbuffer(int target, int renderbuffer) { + report("void bindRenderbuffer"); + glBindFramebuffer(target, renderbuffer); + } + + @Override + public void deleteRenderbuffers(int n, IntBuffer renderbuffers) { + report("void deleteRenderbuffers"); + if (renderbuffers == null) return; + glDeleteRenderbuffers(renderbuffers); + } + + @Override + public void genRenderbuffers(int n, IntBuffer renderbuffers) { + report("void genRenderbuffers"); + if (renderbuffers == null) return; + glGenRenderbuffers(renderbuffers); + } + + @Override + public void renderbufferStorage(int target, int internalFormat, int width, int height) { + report("void renderbufferStorage"); + glRenderbufferStorage(target, internalFormat, width, height); + } + + @Override + public void framebufferRenderbuffer(int target, int attachment, int rendbufferTarget, int renderbuffer) { + report("void framebufferRenderbuffer"); + glFramebufferRenderbuffer(target, attachment, rendbufferTarget, renderbuffer); + } + + @Override + public void framebufferTexture2D(int target, int attachment, int texTarget, int texture, int level) { + report("void framebufferTexture2D"); + glFramebufferTexture2D(target, attachment, texTarget, texture, level); + } + + @Override + public int checkFramebufferStatus(int target) { + report("int checkFramebufferStatus"); + return glCheckFramebufferStatus(target); + } + + @Override + public boolean isFramebuffer(int framebuffer) { + report("boolean isFramebuffer"); + return glIsFramebuffer(framebuffer); + } + + @Override + public void getFramebufferAttachmentParameteriv(int target, int attachment, int pname, IntBuffer params) { + report("void getFramebufferAttachmentParameteriv"); + if (params == null) return; + glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); + } + + @Override + public boolean isRenderbuffer(int renderbuffer) { + report("boolean isRenderbuffer"); + return glIsRenderbuffer(renderbuffer); + } + + @Override + public void getRenderbufferParameteriv(int target, int pname, IntBuffer params) { + report("void getRenderbufferParameteriv"); + if (params == null) return; + glGetRenderbufferParameteriv(INT, INT, 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) { + report("void blitFramebuffer"); + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } + + @Override + public void renderbufferStorageMultisample(int target, int samples, int format, int width, int height) { + report("void renderbufferStorageMultisample"); + glRenderbufferStorageMultisample(target, samples, format, width, height); + } + + @Override + public void readBuffer(int buf) { + report("void readBuffer"); + glReadBuffer(buf); + } + + @Override + public void drawBuffer(int buf) { + report("void drawBuffer"); + // glDrawBuffer(buf); + } + +} diff --git a/core/src/processing/opengl/PGraphicsANGLE2D.java b/core/src/processing/opengl/PGraphicsANGLE2D.java new file mode 100644 index 0000000000..6eff38b20d --- /dev/null +++ b/core/src/processing/opengl/PGraphicsANGLE2D.java @@ -0,0 +1,463 @@ +package processing.opengl; + +import processing.core.PGraphics; +import processing.core.PMatrix3D; +import processing.core.PShape; +import processing.core.PShapeSVG; + + +public class PGraphicsANGLE2D extends PGraphicsOpenGLANGLE { + + public PGraphicsANGLE2D() { + super(); + } + + + ////////////////////////////////////////////////////////////// + + // RENDERER SUPPORT QUERIES + + + @Override + public boolean is2D() { + return true; + } + + + @Override + public boolean is3D() { + return false; + } + + + ////////////////////////////////////////////////////////////// + + // HINTS + + + @Override + public void hint(int which) { + if (which == ENABLE_STROKE_PERSPECTIVE) { + showWarning("Strokes cannot be perspective-corrected in 2D."); + return; + } + super.hint(which); + } + + + ////////////////////////////////////////////////////////////// + + // PROJECTION + + + @Override + public void ortho() { + showMethodWarning("ortho"); + } + + + @Override + public void ortho(float left, float right, + float bottom, float top) { + showMethodWarning("ortho"); + } + + + @Override + public void ortho(float left, float right, + float bottom, float top, + float near, float far) { + showMethodWarning("ortho"); + } + + + @Override + public void perspective() { + showMethodWarning("perspective"); + } + + + @Override + public void perspective(float fov, float aspect, float zNear, float zFar) { + showMethodWarning("perspective"); + } + + + @Override + public void frustum(float left, float right, float bottom, float top, + float znear, float zfar) { + showMethodWarning("frustum"); + } + + + @Override + protected void defaultPerspective() { + super.ortho(0, width, -height, 0, -1, +1); + } + + + ////////////////////////////////////////////////////////////// + + // CAMERA + + + @Override + public void beginCamera() { + showMethodWarning("beginCamera"); + } + + + @Override + public void endCamera() { + showMethodWarning("endCamera"); + } + + + @Override + public void camera() { + showMethodWarning("camera"); + } + + + @Override + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + showMethodWarning("camera"); + } + + + @Override + protected void defaultCamera() { + eyeDist = 1; + resetMatrix(); + } + + + ////////////////////////////////////////////////////////////// + + // MATRIX MORE! + + + @Override + protected void begin2D() { + pushProjection(); + defaultPerspective(); + pushMatrix(); + defaultCamera(); + } + + + @Override + protected void end2D() { + popMatrix(); + popProjection(); + } + + + ////////////////////////////////////////////////////////////// + + // SHAPE + + + @Override + public void shape(PShape shape) { + if (shape.is2D()) { + super.shape(shape); + } else { + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); + } + } + + + @Override + public void shape(PShape shape, float x, float y) { + if (shape.is2D()) { + super.shape(shape, x, y); + } else { + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); + } + } + + + @Override + public void shape(PShape shape, float a, float b, float c, float d) { + if (shape.is2D()) { + super.shape(shape, a, b, c, d); + } else { + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); + } + } + + + @Override + public void shape(PShape shape, float x, float y, float z) { + showDepthWarningXYZ("shape"); + } + + + @Override + public void shape(PShape shape, float x, float y, float z, + float c, float d, float e) { + showDepthWarningXYZ("shape"); + } + + + + ////////////////////////////////////////////////////////////// + + // SHAPE I/O + + + static protected boolean isSupportedExtension(String extension) { + return extension.equals("svg") || extension.equals("svgz"); + } + + + static protected PShape loadShapeImpl(PGraphics pg, + String filename, String extension) { + if (extension.equals("svg") || extension.equals("svgz")) { + PShapeSVG svg = new PShapeSVG(pg.parent.loadXML(filename)); + return PShapeOpenGL.createShape((PGraphicsOpenGL) pg, svg); + } + return null; + } + + + ////////////////////////////////////////////////////////////// + + // SCREEN TRANSFORMS + + + @Override + public float modelX(float x, float y, float z) { + showDepthWarning("modelX"); + return 0; + } + + + @Override + public float modelY(float x, float y, float z) { + showDepthWarning("modelY"); + return 0; + } + + + @Override + public float modelZ(float x, float y, float z) { + showDepthWarning("modelZ"); + return 0; + } + + + ////////////////////////////////////////////////////////////// + + // BEZIER VERTICES + + + @Override + public void bezierVertex(float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + showDepthWarningXYZ("bezierVertex"); + } + + + ////////////////////////////////////////////////////////////// + + // QUADRATIC BEZIER VERTICES + + + @Override + public void quadraticVertex(float x2, float y2, float z2, + float x4, float y4, float z4) { + showDepthWarningXYZ("quadVertex"); + } + + + ////////////////////////////////////////////////////////////// + + // CURVE VERTICES + + + @Override + public void curveVertex(float x, float y, float z) { + showDepthWarningXYZ("curveVertex"); + } + + + ////////////////////////////////////////////////////////////// + + // BOX + + + @Override + public void box(float w, float h, float d) { + showMethodWarning("box"); + } + + + ////////////////////////////////////////////////////////////// + + // SPHERE + + + @Override + public void sphere(float r) { + showMethodWarning("sphere"); + } + + + ////////////////////////////////////////////////////////////// + + // VERTEX SHAPES + + + @Override + public void vertex(float x, float y, float z) { + showDepthWarningXYZ("vertex"); + } + + @Override + public void vertex(float x, float y, float z, float u, float v) { + showDepthWarningXYZ("vertex"); + } + + ////////////////////////////////////////////////////////////// + + // MATRIX TRANSFORMATIONS + + @Override + public void translate(float tx, float ty, float tz) { + showDepthWarningXYZ("translate"); + } + + @Override + public void rotateX(float angle) { + showDepthWarning("rotateX"); + } + + @Override + public void rotateY(float angle) { + showDepthWarning("rotateY"); + } + + @Override + public void rotateZ(float angle) { + showDepthWarning("rotateZ"); + } + + @Override + public void rotate(float angle, float vx, float vy, float vz) { + showVariationWarning("rotate"); + } + + @Override + public void applyMatrix(PMatrix3D source) { + showVariationWarning("applyMatrix"); + } + + @Override + public void applyMatrix(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + showVariationWarning("applyMatrix"); + } + + @Override + public void scale(float sx, float sy, float sz) { + showDepthWarningXYZ("scale"); + } + + ////////////////////////////////////////////////////////////// + + // SCREEN AND MODEL COORDS + + @Override + public float screenX(float x, float y, float z) { + showDepthWarningXYZ("screenX"); + return 0; + } + + @Override + public float screenY(float x, float y, float z) { + showDepthWarningXYZ("screenY"); + return 0; + } + + @Override + public float screenZ(float x, float y, float z) { + showDepthWarningXYZ("screenZ"); + return 0; + } + + @Override + public PMatrix3D getMatrix(PMatrix3D target) { + showVariationWarning("getMatrix"); + return target; + } + + @Override + public void setMatrix(PMatrix3D source) { + showVariationWarning("setMatrix"); + } + + ////////////////////////////////////////////////////////////// + + // LIGHTS + + @Override + public void lights() { + showMethodWarning("lights"); + } + + @Override + public void noLights() { + showMethodWarning("noLights"); + } + + @Override + public void ambientLight(float red, float green, float blue) { + showMethodWarning("ambientLight"); + } + + @Override + public void ambientLight(float red, float green, float blue, + float x, float y, float z) { + showMethodWarning("ambientLight"); + } + + @Override + public void directionalLight(float red, float green, float blue, + float nx, float ny, float nz) { + showMethodWarning("directionalLight"); + } + + @Override + public void pointLight(float red, float green, float blue, + float x, float y, float z) { + showMethodWarning("pointLight"); + } + + @Override + public void spotLight(float red, float green, float blue, + float x, float y, float z, + float nx, float ny, float nz, + float angle, float concentration) { + showMethodWarning("spotLight"); + } + + @Override + public void lightFalloff(float constant, float linear, float quadratic) { + showMethodWarning("lightFalloff"); + } + + @Override + public void lightSpecular(float v1, float v2, float v3) { + showMethodWarning("lightSpecular"); + } +} \ No newline at end of file diff --git a/core/src/processing/opengl/PGraphicsANGLE3D.java b/core/src/processing/opengl/PGraphicsANGLE3D.java new file mode 100644 index 0000000000..3210fdc5b0 --- /dev/null +++ b/core/src/processing/opengl/PGraphicsANGLE3D.java @@ -0,0 +1,116 @@ +package processing.opengl; + +import processing.core.PGraphics; +import processing.core.PShape; +import processing.core.PShapeOBJ; + + + +public class PGraphicsANGLE3D extends PGraphicsOpenGLANGLE { + + public PGraphicsANGLE3D() { + super(); + } + + + + ////////////////////////////////////////////////////////////// + + // RENDERER SUPPORT QUERIES + + + @Override + public boolean is2D() { + return false; + } + + + @Override + public boolean is3D() { + return true; + } + + + ////////////////////////////////////////////////////////////// + + // PROJECTION + + + @Override + protected void defaultPerspective() { + perspective(); + } + + + ////////////////////////////////////////////////////////////// + + // CAMERA + + + @Override + protected void defaultCamera() { + camera(); + } + + + ////////////////////////////////////////////////////////////// + + // MATRIX MORE! + + + @Override + protected void begin2D() { + pushProjection(); + ortho(-width/2f, width/2f, -height/2f, height/2f); + pushMatrix(); + + // Set camera for 2D rendering, it simply centers at (width/2, height/2) + float centerX = width/2f; + float centerY = height/2f; + modelview.reset(); + modelview.translate(-centerX, -centerY); + + modelviewInv.set(modelview); + modelviewInv.invert(); + + camera.set(modelview); + cameraInv.set(modelviewInv); + + updateProjmodelview(); + } + + + @Override + protected void end2D() { + popMatrix(); + popProjection(); + } + + + + ////////////////////////////////////////////////////////////// + + // SHAPE I/O + + + static protected boolean isSupportedExtension(String extension) { + return extension.equals("obj"); + } + + + static protected PShape loadShapeImpl(PGraphics pg, String filename, + String extension) { + PShapeOBJ obj = null; + + if (extension.equals("obj")) { + obj = new PShapeOBJ(pg.parent, filename); + int prevTextureMode = pg.textureMode; + pg.textureMode = NORMAL; + PShapeOpenGL p3d = PShapeOpenGL.createShape((PGraphicsOpenGL)pg, obj); + pg.textureMode = prevTextureMode; + return p3d; + } + return null; + } + +} \ No newline at end of file diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 88164f43e1..def4717653 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -24,14 +24,36 @@ package processing.opengl; -import processing.core.*; - import java.io.File; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.net.URL; -import java.nio.*; -import java.util.*; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.WeakHashMap; + +import processing.core.PApplet; +import processing.core.PConstants; +import processing.core.PFont; +import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PMatrix; +import processing.core.PMatrix2D; +import processing.core.PMatrix3D; +import processing.core.PShape; +import processing.core.PSurface; +import processing.core.PVector; /** @@ -1402,6 +1424,8 @@ public void beginDraw() { // surfaces will have a null gl object. report("top beginDraw()"); + System.out.println("TOP BEGINDRAW()"); + if (!checkGLThread()) { return; } @@ -1532,12 +1556,12 @@ protected void restoreGL() { if (pgl.isES()) { // neither GL_MULTISAMPLE nor GL_POLYGON_SMOOTH are part of GLES2 or GLES3 } else if (smooth < 1) { - pgl.disable(PGL.MULTISAMPLE); + pgl.disable(PGL.MULTISAMPLE()); } else { - pgl.enable(PGL.MULTISAMPLE); + pgl.enable(PGL.MULTISAMPLE()); } if (!pgl.isES()) { - pgl.disable(PGL.POLYGON_SMOOTH); + pgl.disable(PGL.POLYGON_SMOOTH()); } pgl.viewport(viewport.get(0), viewport.get(1), @@ -5259,6 +5283,7 @@ protected void backgroundImpl() { flush(); pgl.clearBackground(backgroundR, backgroundG, backgroundB, backgroundA, !hints[DISABLE_DEPTH_MASK], true); + // System.out.println(backgroundR+" "+backgroundG+" "+backgroundB+" "+backgroundA); loaded = false; } @@ -6764,12 +6789,12 @@ protected void setGLSettings() { if (pgl.isES()) { // neither GL_MULTISAMPLE nor GL_POLYGON_SMOOTH are part of GLES2 or GLES3 } else if (smooth < 1) { - pgl.disable(PGL.MULTISAMPLE); + pgl.disable(PGL.MULTISAMPLE()); } else { - pgl.enable(PGL.MULTISAMPLE); + pgl.enable(PGL.MULTISAMPLE()); } if (!pgl.isES()) { - pgl.disable(PGL.POLYGON_SMOOTH); + pgl.disable(PGL.POLYGON_SMOOTH()); } if (sized) { @@ -6875,8 +6900,9 @@ protected void getGLParameters() { maxSamples = intBuffer.get(0); } + anisoSamplingSupported = false; // TODO: temporary if (anisoSamplingSupported) { - pgl.getFloatv(PGL.MAX_TEXTURE_MAX_ANISOTROPY, floatBuffer); + pgl.getFloatv(PGL.MAX_TEXTURE_MAX_ANISOTROPY(), floatBuffer); maxAnisoAmount = floatBuffer.get(0); } diff --git a/core/src/processing/opengl/PGraphicsOpenGLANGLE.java b/core/src/processing/opengl/PGraphicsOpenGLANGLE.java new file mode 100644 index 0000000000..7544197b46 --- /dev/null +++ b/core/src/processing/opengl/PGraphicsOpenGLANGLE.java @@ -0,0 +1,21 @@ +package processing.opengl; + +import processing.core.PSurface; + +public class PGraphicsOpenGLANGLE extends PGraphicsOpenGL { + public PGraphicsOpenGLANGLE() { + super(); + } + + @Override + protected PGL createPGL(PGraphicsOpenGL pg) { + return new PGLANGLE(pg); + } + + @Override + // Java only + public PSurface createSurface() { // ignore + return surface = new PSurfaceANGLE(this); + } + +} diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 849e211939..62fa2b967f 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -50,8 +50,8 @@ 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.GLRendererQuirks; +import com.jogamp.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.opengl.glu.GLU; import com.jogamp.opengl.glu.GLUtessellator; import com.jogamp.opengl.glu.GLUtessellatorCallbackAdapter; @@ -440,7 +440,7 @@ public void init(GLAutoDrawable glDrawable) { protected void enableTexturing(int target) { if (target == TEXTURE_2D) { texturingTargets[0] = true; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { texturingTargets[1] = true; } } @@ -450,7 +450,7 @@ protected void enableTexturing(int target) { protected void disableTexturing(int target) { if (target == TEXTURE_2D) { texturingTargets[0] = false; - } else if (target == TEXTURE_RECTANGLE) { + } else if (target == TEXTURE_RECTANGLE()) { texturingTargets[1] = false; } } @@ -507,6 +507,7 @@ protected Object getDerivedFont(Object font, float size) { @Override protected int getGLSLVersion() { VersionNumber vn = context.getGLSLVersionNumber(); + System.out.println("GLSL version: "+vn.getMajor() * 100 + vn.getMinor()); return vn.getMajor() * 100 + vn.getMinor(); } @@ -742,6 +743,69 @@ public void next() { } } + public static int ALPHA8() { + System.out.println("UNAVAILABLE ENUM ALPHA8"); + return GL.GL_ALPHA8; + } + public static int GENERATE_MIPMAP_HINT() { + System.out.println("UNAVAILABLE ENUM GENERATE_MIPMAP_HINT"); + return GL.GL_GENERATE_MIPMAP_HINT; + } + public static int TEXTURE_RECTANGLE() { + System.out.println("UNAVAILABLE ENUM TEXTURE_RECTANGLE"); + return GL2GL3.GL_TEXTURE_RECTANGLE; + } + public static int TEXTURE_MAX_ANISOTROPY() { + System.out.println("UNAVAILABLE ENUM TEXTURE_MAX_ANISOTROPY"); + return GL2GL3.GL_TEXTURE_RECTANGLE; + } + public static int MAX_TEXTURE_MAX_ANISOTROPY() { + System.out.println("UNAVAILABLE ENUM MAX_TEXTURE_MAX_ANISOTROPY"); + return GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT; + } + + public static int DEPTH_COMPONENT32() { + System.out.println("UNAVAILABLE ENUM DEPTH_COMPONENT32"); + return GL.GL_DEPTH_COMPONENT32; + } + + public static int STENCIL_INDEX1() { + System.out.println("UNAVAILABLE ENUM STENCIL_INDEX1"); + return GL.GL_STENCIL_INDEX1; + } + + public static int STENCIL_INDEX4() { + System.out.println("UNAVAILABLE ENUM STENCIL_INDEX4"); + return GL.GL_STENCIL_INDEX4; + } + public static int FRAMEBUFFER_INCOMPLETE_FORMATS() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_FORMATS"); + return GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; + } + + public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"); + return GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; + } + + public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER() { + System.out.println("UNAVAILABLE ENUM FRAMEBUFFER_INCOMPLETE_READ_BUFFER"); + return GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; + } + + public static int MULTISAMPLE() { + + return GL.GL_MULTISAMPLE; + } + + public static int LINE_SMOOTH() { + return GL.GL_LINE_SMOOTH; + } + + public static int POLYGON_SMOOTH() { + return GL2GL3.GL_POLYGON_SMOOTH; + } + /////////////////////////////////////////////////////////// @@ -775,7 +839,7 @@ public void next() { RGB565 = GL.GL_RGB565; RGB8 = GL.GL_RGB8; RGBA8 = GL.GL_RGBA8; - ALPHA8 = GL.GL_ALPHA8; + // ALPHA8 = GL.GL_ALPHA8; READ_ONLY = GL2ES3.GL_READ_ONLY; WRITE_ONLY = GL.GL_WRITE_ONLY; @@ -785,7 +849,7 @@ public void next() { TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; TESS_EDGE_FLAG = GLU.GLU_TESS_EDGE_FLAG; - GENERATE_MIPMAP_HINT = GL.GL_GENERATE_MIPMAP_HINT; + // GENERATE_MIPMAP_HINT = GL.GL_GENERATE_MIPMAP_HINT; FASTEST = GL.GL_FASTEST; NICEST = GL.GL_NICEST; DONT_CARE = GL.GL_DONT_CARE; @@ -843,14 +907,14 @@ public void next() { PACK_ALIGNMENT = GL.GL_PACK_ALIGNMENT; TEXTURE_2D = GL.GL_TEXTURE_2D; - TEXTURE_RECTANGLE = GL2GL3.GL_TEXTURE_RECTANGLE; + // 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; + // 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; @@ -997,11 +1061,11 @@ public void next() { DEPTH_COMPONENT = GL2ES2.GL_DEPTH_COMPONENT; DEPTH_COMPONENT16 = GL.GL_DEPTH_COMPONENT16; DEPTH_COMPONENT24 = GL.GL_DEPTH_COMPONENT24; - DEPTH_COMPONENT32 = GL.GL_DEPTH_COMPONENT32; + // 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_INDEX1 = GL.GL_STENCIL_INDEX1; + // STENCIL_INDEX4 = GL.GL_STENCIL_INDEX4; STENCIL_INDEX8 = GL.GL_STENCIL_INDEX8; DEPTH_STENCIL = GL.GL_DEPTH_STENCIL; @@ -1011,9 +1075,9 @@ public void next() { 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_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; @@ -1033,9 +1097,9 @@ public void next() { 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; + // 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; @@ -1307,6 +1371,7 @@ public void vertexAttrib4fv(int index, FloatBuffer values) { @Override public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, int offset) { + // System.out.println("Stride: "+stride); gl2.glVertexAttribPointer(index, size, type, normalized, stride, offset); } diff --git a/core/src/processing/opengl/PSurfaceANGLE.java b/core/src/processing/opengl/PSurfaceANGLE.java new file mode 100644 index 0000000000..aefb4e240b --- /dev/null +++ b/core/src/processing/opengl/PSurfaceANGLE.java @@ -0,0 +1,672 @@ +package processing.opengl; + +import java.awt.DisplayMode; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.lwjgl.glfw.GLFW.GLFW_ANGLE_PLATFORM_TYPE; +import static org.lwjgl.glfw.GLFW.GLFW_ANGLE_PLATFORM_TYPE_VULKAN; +import static org.lwjgl.glfw.GLFW.GLFW_CLIENT_API; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_CREATION_API; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; +import static org.lwjgl.glfw.GLFW.GLFW_EGL_CONTEXT_API; +import static org.lwjgl.glfw.GLFW.GLFW_MOD_SHIFT; +import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LEFT; +import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_MIDDLE; +import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_RIGHT; +import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_ES_API; +import static org.lwjgl.glfw.GLFW.GLFW_PRESS; +import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; +import static org.lwjgl.glfw.GLFW.glfwCreateWindow; +import static org.lwjgl.glfw.GLFW.glfwInit; +import static org.lwjgl.glfw.GLFW.glfwInitHint; +import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; +import static org.lwjgl.glfw.GLFW.glfwPollEvents; +import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; +import static org.lwjgl.glfw.GLFW.glfwWindowHint; +import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; +import org.lwjgl.opengles.GLES; +import static org.lwjgl.system.MemoryUtil.NULL; + +import processing.awt.ShimAWT; +import processing.core.PApplet; +import processing.core.PConstants; +import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PSurface; +import processing.event.KeyEvent; +import processing.event.MouseEvent; + +// NEXT TODO: +// Create a function which creates a surface with a specified width and height, puts it into +// animation thread. + +public class PSurfaceANGLE implements PSurface { + + protected PGraphics graphics; + protected PGLANGLE pgl; + + protected PApplet sketch; + protected int sketchWidth = 0; + protected int sketchHeight = 0; + private boolean windowCreated = false; + + private Thread drawExceptionHandler; + private Object drawExceptionMutex = new Object(); + protected Throwable drawException; + + private AnimatorTask animationThread; + private boolean isStopped = true; + + ///////////////////////////////// + // GLFW window variables + public long glfwwindow; + public int glfwwidth = 1200; + public int glfwheight = 800; + public long glfwsurface; + public boolean glfwframebufferResize = false; + + private int glfwMouseX = 0, glfwMouseY = 0; + private int glfwButton = 0, glfwAction = 0; + + private static int GLFW_SHIFT = 340; + private static int GLFW_ENTER = 257; + private static int GLFW_BACKSPACE = 259; + private static int GLFW_CTRL = 341; + private static int GLFW_ALT = 342; + + // TODO: Make framerate dynamic. + class AnimatorTask extends TimerTask { + Timer timer; + float fps = 60.0f; + + public AnimatorTask(float fps) { + super(); + this.fps = fps; + } + + public void start() { + final long period = 0 < fps ? (long) (1000.0f / fps) : 1; // 0 -> 1: IllegalArgumentException: Non-positive period + timer = new Timer(); + timer.scheduleAtFixedRate(this, 0, period); + } + + long then = 0; + + @Override + public void run() { +// System.out.println("INTERVAL "+(System.nanoTime()-then)); +// Util.beginTmr(); + + // We create the window here because glfw window needs to be created in the same + // thread as it is run in. + if (!windowCreated) { + initWindow(); + } + + if (glfwWindowShouldClose(glfwwindow)) { + sketch.exit(); + } +// + if (!sketch.finished) { + // pvk.getGL(pvk); + + sketch.handleDraw(); + + PGraphicsOpenGL.completeFinishedPixelTransfers(); +// Util.endTmr("completeFinishedPixelTransfers"); + } + swapBuffers(); + + + glfwPollEvents(); + + if (sketch.exitCalled()) { + sketch.dispose(); + sketch.exitActual(); + } +// Util.endTmr("end entire cycle"); +// then = System.nanoTime(); + } + } + + public PSurfaceANGLE(PGraphics graphics) { + this.graphics = graphics; + this.pgl = (PGLANGLE)((PGraphicsOpenGLANGLE) graphics).pgl; + } + + @Override + public void initOffscreen(PApplet sketch) { + this.sketch = sketch; + + sketchWidth = sketch.sketchWidth(); + sketchHeight = sketch.sketchHeight(); + } + + @Override + public void initFrame(PApplet sketch) { + this.sketch = sketch; + sketchWidth = sketch.sketchWidth(); + sketchHeight = sketch.sketchHeight(); + + initIcons(); + initAnimator(); + } + + private void initIcons() { +// IOUtil.ClassResources res; +// if (PJOGL.icons == null || PJOGL.icons.length == 0) { +// // Default Processing icons +// final int[] sizes = { 16, 32, 48, 64, 128, 256, 512 }; +// String[] iconImages = new String[sizes.length]; +// for (int i = 0; i < sizes.length; i++) { +// iconImages[i] = "/icon/icon-" + sizes[i] + ".png"; +// } +// res = new ClassResources(iconImages, +// PApplet.class.getClassLoader(), +// PApplet.class); +// } else { +// // Loading custom icons from user-provided files. +// String[] iconImages = new String[PJOGL.icons.length]; +// for (int i = 0; i < PJOGL.icons.length; i++) { +// iconImages[i] = resourceFilename(PJOGL.icons[i]); +// } +// +// res = new ClassResources(iconImages, +// sketch.getClass().getClassLoader(), +// sketch.getClass()); +// } +// NewtFactory.setWindowIcons(res); + // TODO: make work for vulkan + } + + + + private static boolean isPCodedKey(int code) { + return +// code == com.jogamp.newt.event.KeyEvent.VK_UP || +// code == com.jogamp.newt.event.KeyEvent.VK_DOWN || +// code == com.jogamp.newt.event.KeyEvent.VK_LEFT || +// code == com.jogamp.newt.event.KeyEvent.VK_RIGHT || + code == GLFW_ALT || + code == GLFW_CTRL || + code == GLFW_SHIFT; +// code == GLFW_WINDOWS || +// (!isHackyKey(code)); + } + + + // Why do we need this mapping? + // Relevant discussion and links here: + // http://forum.jogamp.org/Newt-wrong-keycode-for-key-td4033690.html#a4033697 + // (I don't think this is a complete solution). + private static int mapToPConst(int code) { + return switch (code) { + case com.jogamp.newt.event.KeyEvent.VK_UP -> PConstants.UP; + case com.jogamp.newt.event.KeyEvent.VK_DOWN -> PConstants.DOWN; + case com.jogamp.newt.event.KeyEvent.VK_LEFT -> PConstants.LEFT; + case com.jogamp.newt.event.KeyEvent.VK_RIGHT -> PConstants.RIGHT; + case com.jogamp.newt.event.KeyEvent.VK_ALT -> PConstants.ALT; + case com.jogamp.newt.event.KeyEvent.VK_CONTROL -> PConstants.CONTROL; + case com.jogamp.newt.event.KeyEvent.VK_SHIFT -> PConstants.SHIFT; + case com.jogamp.newt.event.KeyEvent.VK_WINDOWS -> java.awt.event.KeyEvent.VK_META; + default -> code; + }; + } + + + private static boolean isHackyKey(int code) { + return (code == GLFW_BACKSPACE || +// code == com.jogamp.newt.event.KeyEvent.VK_TAB || + code == GLFW_ENTER +// code == com.jogamp.newt.event.KeyEvent.VK_ESCAPE || +// code == com.jogamp.newt.event.KeyEvent.VK_DELETE + ); + } + + + private static char hackToChar(int code, char def) { + return switch (code) { + case com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE -> PConstants.BACKSPACE; + case com.jogamp.newt.event.KeyEvent.VK_TAB -> PConstants.TAB; + case com.jogamp.newt.event.KeyEvent.VK_ENTER -> PConstants.ENTER; + case com.jogamp.newt.event.KeyEvent.VK_ESCAPE -> PConstants.ESC; + case com.jogamp.newt.event.KeyEvent.VK_DELETE -> PConstants.DELETE; + default -> def; + }; + } + + + protected void nativeKeyEvent(long millis, int action, int modifiers, + int key, int keyCode, boolean isAutoRepeat) { + // SHIFT, CTRL, META, and ALT are identical to processing.event.Event +// int modifiers = nativeEvent.getModifiers(); +// int peModifiers = nativeEvent.getModifiers() & +// (InputEvent.SHIFT_MASK | +// InputEvent.CTRL_MASK | +// InputEvent.META_MASK | +// InputEvent.ALT_MASK); + + + + + // From http://jogamp.org/deployment/v2.1.0/javadoc/jogl/javadoc/com/jogamp/newt/event/KeyEvent.html + // public final short getKeySymbol() + // Returns the virtual key symbol reflecting the current keyboard layout. + // public final short getKeyCode() + // Returns the virtual key code using a fixed mapping to the US keyboard layout. + // In contrast to key symbol, key code uses a fixed US keyboard layout and therefore is keyboard layout independent. + // E.g. virtual key code VK_Y denotes the same physical key regardless whether keyboard layout QWERTY or QWERTZ is active. The key symbol of the former is VK_Y, where the latter produces VK_Y. + + + if (!isPCodedKey(key)) { + key = Character.toLowerCase(key); + + if (modifiers == GLFW_MOD_SHIFT) { + key = Character.toUpperCase(key); + } + + KeyEvent ke = new KeyEvent(new Object(), millis, + action, modifiers, + (char)key, + keyCode, + isAutoRepeat); + sketch.postEvent(ke); + } + +// if (!isPCodedKey(code, nativeEvent.isPrintableKey()) && !isHackyKey(code)) { +// if (peAction == KeyEvent.PRESS) { +// // Create key typed event +// // TODO: combine dead keys with the following key +// KeyEvent tke = new KeyEvent(nativeEvent, nativeEvent.getWhen(), +// KeyEvent.TYPE, modifiers, +// keyChar, +// 0, +// nativeEvent.isAutoRepeat()); +// +// sketch.postEvent(tke); +// } +// } + } + + + private void nativeMouseEvent(long millis, int action, int modifiers, + int x, int y, int button, int count) { + + + + int peButton = switch (button) { + case GLFW_MOUSE_BUTTON_LEFT -> PConstants.LEFT; + case GLFW_MOUSE_BUTTON_MIDDLE -> PConstants.CENTER; + case GLFW_MOUSE_BUTTON_RIGHT -> PConstants.RIGHT; + default -> 0; + }; + + int peaction = switch (action) { + case GLFW_PRESS -> MouseEvent.PRESS; + case GLFW_RELEASE -> MouseEvent.RELEASE; + case 99 -> MouseEvent.MOVE; + default -> 0; + }; + + int scale = 1; +// if (PApplet.platform == PConstants.MACOS) { +// scale = (int) getCurrentPixelScale(); +// } else { +// scale = (int) getPixelScale(); +// } + int sx = x / scale; + int sy = y / scale; + int mx = sx; + int my = sy; + +// if (pvk.presentMode()) { +// mx -= (int)pvk.presentX; +// my -= (int)pvk.presentY; +// //noinspection IntegerDivisionInFloatingPointContext +// if (peAction == KeyEvent.RELEASE && +// pvk.insideStopButton(sx, sy - screenRect.height / windowScaleFactor)) { +// sketch.exit(); +// } +// if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) { +// return; +// } +// } + + MouseEvent me = new MouseEvent(new Object(), millis, + peaction, modifiers, + mx, my, + peButton, + count); + + sketch.postEvent(me); + } + + + + + + protected void initListeners() { + } + + private void initWindow() { + glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE, GLFW_ANGLE_PLATFORM_TYPE_VULKAN); + if(!glfwInit()) { + throw new RuntimeException("Cannot initialize GLFW"); + } + + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + + // TODO: Update this. + String title = "Sketch"; + + glfwwidth = graphics.width; + glfwheight = graphics.height; + + glfwwindow = glfwCreateWindow(glfwwidth, glfwheight, title, NULL, NULL); + + glfwMakeContextCurrent(glfwwindow); + + if(glfwwindow == 0) { + throw new RuntimeException("Cannot create window"); + } + + GLES.createCapabilities(); + + // glfwSetFramebufferSizeCallback(glfwwindow, this::framebufferResizeCallback); + // glfwSetCursorPosCallback(glfwwindow, this::cursorMoveCallback); + // glfwSetMouseButtonCallback(glfwwindow, this::mouseButtonCallback); + // glfwSetKeyCallback(glfwwindow, this::keyActionCallback); + // glfwSetInputMode(glfwwindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + + windowCreated = true; + } + + private void framebufferResizeCallback(long window, int width, int height) { + glfwframebufferResize = true; + } + + private void cursorMoveCallback(long window, double xpos, double ypos) { + glfwMouseX = (int)xpos; + glfwMouseY = (int)ypos; + glfwAction = 99; + nativeMouseEvent(0, glfwAction, 0, + glfwMouseX, glfwMouseY, glfwButton, 0); + } + + private void mouseButtonCallback(long window, int button, int action, int mod) { + glfwButton = button; + glfwAction = action; + nativeMouseEvent(0, glfwAction, mod, + glfwMouseX, glfwMouseY, glfwButton, 0); + } + + private void keyActionCallback(long window, int key, int scancode, int action, int mods) { +// System.out.println((char)scancode) +// System.out.println(key); + nativeKeyEvent(0L, action, mods, + (char)key, 0, false); + } + + + private void initAnimator() { + if (PApplet.platform == PConstants.WINDOWS) { + // Force Windows to keep timer resolution high by creating a dummy + // thread that sleeps for a time that is not a multiple of 10 ms. + // See section titled "Clocks and Timers on Windows" in this post: + // https://web.archive.org/web/20160308031939/https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks + Thread highResTimerThread = new Thread(() -> { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException ignore) { } + }, "HighResTimerThread"); + highResTimerThread.setDaemon(true); + highResTimerThread.start(); + } + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + DisplayMode dm = gd.getDisplayMode(); + + // Get the refresh rate + int refreshRate = dm.getRefreshRate(); + + if (refreshRate == DisplayMode.REFRESH_RATE_UNKNOWN) { + refreshRate = 60; + } + + animationThread = new AnimatorTask(refreshRate); + + + drawExceptionHandler = new Thread(() -> { + synchronized (drawExceptionMutex) { + try { + while (drawException == null) { + drawExceptionMutex.wait(); + } + Throwable cause = drawException.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof UnsatisfiedLinkError) { + throw new UnsatisfiedLinkError(cause.getMessage()); + } else if (cause == null) { + throw new RuntimeException(drawException.getMessage()); + } else { + throw new RuntimeException(cause); + } + } catch (InterruptedException ignored) { } + } + }); + drawExceptionHandler.start(); + + } + + public void swapBuffers() { + glfwSwapBuffers(glfwwindow); + } + + public float getPixelScale() { + return 1; + } + + @Override + public Object getNative() { + // TODO Auto-generated method stub + System.out.println("WARNING getNative() not implemented."); + return null; + } + + @Override + public void setTitle(String title) { + // TODO Auto-generated method stub + + } + + @Override + public void setVisible(boolean visible) { + // TODO Auto-generated method stub + + } + + @Override + public void setResizable(boolean resizable) { + // TODO Auto-generated method stub + + } + + @Override + public void setAlwaysOnTop(boolean always) { + // TODO Auto-generated method stub + + } + + @Override + public void setIcon(PImage icon) { + // TODO Auto-generated method stub + + } + + @Override + public void placeWindow(int[] location, int[] editorLocation) { + // TODO Auto-generated method stub + + } + + @Override + public void placePresent(int stopColor) { + // TODO Auto-generated method stub + + } + + @Override + public void setLocation(int x, int y) { + // TODO Auto-generated method stub + + } + + @Override + public void setSize(int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void setFrameRate(float fps) { +// System.out.println("SET FRAMERATE "+fps); +// animationThread.cancel(); +// animationThread = new AnimatorTask(fps); +// animationThread.start(); + } + + @Override + public void setCursor(int kind) { + // TODO Auto-generated method stub + + } + + @Override + public void setCursor(PImage image, int hotspotX, int hotspotY) { + // TODO Auto-generated method stub + + } + + @Override + public void showCursor() { + // TODO Auto-generated method stub + + } + + @Override + public void hideCursor() { + // TODO Auto-generated method stub + + } + + @Override + public PImage loadImage(String path, Object... args) { + // TODO Auto-generated method stub + return ShimAWT.loadImage(sketch, path, args); + } + + @Override + public boolean openLink(String url) { + // TODO Auto-generated method stub + return ShimAWT.openLink(url); + } + + @Override + public void selectInput(String prompt, String callbackMethod, + File file, Object callbackObject) { + EventQueue.invokeLater(() -> { + // https://github.com/processing/processing/issues/3831 + boolean hide = (sketch != null) && + (PApplet.platform == PConstants.WINDOWS); + if (hide) setVisible(false); + + ShimAWT.selectImpl(prompt, callbackMethod, file, + callbackObject, null, FileDialog.LOAD); + + if (hide) setVisible(true); + }); + } + + @Override + public void selectOutput(String prompt, String callbackMethod, + File file, Object callbackObject) { + EventQueue.invokeLater(() -> { + // https://github.com/processing/processing/issues/3831 + boolean hide = (sketch != null) && + (PApplet.platform == PConstants.WINDOWS); + if (hide) setVisible(false); + + ShimAWT.selectImpl(prompt, callbackMethod, file, + callbackObject, null, FileDialog.SAVE); + + if (hide) setVisible(true); + }); + } + + @Override + public void selectFolder(String prompt, String callbackMethod, + File file, Object callbackObject) { + EventQueue.invokeLater(() -> { + // https://github.com/processing/processing/issues/3831 + boolean hide = (sketch != null) && + (PApplet.platform == PConstants.WINDOWS); + if (hide) setVisible(false); + + ShimAWT.selectFolderImpl(prompt, callbackMethod, file, + callbackObject, null); + + if (hide) setVisible(true); + }); + } + + private AtomicBoolean paused = new AtomicBoolean(false); + + + @Override + public void startThread() { + + // OpenGL compatibility: + // Window gets resized upon initialisation +// pvk.resetFBOLayer(); + + // Our animation thread here. + animationThread.start(); + isStopped = false; + } + + @Override + public void pauseThread() { + paused.set(true); + } + + @Override + public void resumeThread() { + paused.set(false); + } + + @Override + public boolean stopThread() { + if (animationThread != null) animationThread.cancel(); + isStopped = true; + return true; + } + + @Override + public boolean isStopped() { + return isStopped; + } + +} \ No newline at end of file diff --git a/core/src/processing/opengl/Texture.java b/core/src/processing/opengl/Texture.java index 5624aa7725..d15f80dd64 100644 --- a/core/src/processing/opengl/Texture.java +++ b/core/src/processing/opengl/Texture.java @@ -1149,7 +1149,7 @@ protected void allocate() { pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS); pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT); if (PGraphicsOpenGL.anisoSamplingSupported) { - pgl.texParameterf(glTarget, PGL.TEXTURE_MAX_ANISOTROPY, + pgl.texParameterf(glTarget, PGL.TEXTURE_MAX_ANISOTROPY(), PGraphicsOpenGL.maxAnisoAmount); } diff --git a/core/src/processing/opengl/shaders/ColorFrag.glsl b/core/src/processing/opengl/shaders/ColorFrag.glsl index 1a9c1f6f3d..803348e323 100644 --- a/core/src/processing/opengl/shaders/ColorFrag.glsl +++ b/core/src/processing/opengl/shaders/ColorFrag.glsl @@ -1,32 +1,13 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es #ifdef GL_ES precision mediump float; precision mediump int; #endif -varying vec4 vertColor; +in vec4 vertColor; +out vec4 colorOut; void main() { - gl_FragColor = vertColor; + colorOut = vertColor; } \ No newline at end of file diff --git a/core/src/processing/opengl/shaders/ColorVert.glsl b/core/src/processing/opengl/shaders/ColorVert.glsl index aaab987c0b..4c57b3f744 100644 --- a/core/src/processing/opengl/shaders/ColorVert.glsl +++ b/core/src/processing/opengl/shaders/ColorVert.glsl @@ -1,31 +1,11 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 transformMatrix; -attribute vec4 position; -attribute vec4 color; +in vec4 position; +in vec4 color; -varying vec4 vertColor; +out vec4 vertColor; void main() { gl_Position = transformMatrix * position; diff --git a/core/src/processing/opengl/shaders/LightFrag.glsl b/core/src/processing/opengl/shaders/LightFrag.glsl index 4f775befa5..2cf9ec8e03 100644 --- a/core/src/processing/opengl/shaders/LightFrag.glsl +++ b/core/src/processing/opengl/shaders/LightFrag.glsl @@ -1,33 +1,15 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es #ifdef GL_ES precision mediump float; precision mediump int; #endif -varying vec4 vertColor; -varying vec4 backVertColor; +in vec4 vertColor; +in vec4 backVertColor; + +out colorOut; void main() { - gl_FragColor = gl_FrontFacing ? vertColor : backVertColor; + colorOut = gl_FrontFacing ? vertColor : backVertColor; } diff --git a/core/src/processing/opengl/shaders/LightVert-brcm.glsl b/core/src/processing/opengl/shaders/LightVert-brcm.glsl index f518ef90a2..6f933dce49 100644 --- a/core/src/processing/opengl/shaders/LightVert-brcm.glsl +++ b/core/src/processing/opengl/shaders/LightVert-brcm.glsl @@ -1,24 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 modelviewMatrix; uniform mat4 transformMatrix; @@ -33,14 +13,14 @@ uniform vec3 lightSpecular[8]; uniform vec3 lightFalloff[8]; uniform vec2 lightSpot[8]; -attribute vec4 position; -attribute vec4 color; -attribute vec3 normal; +in vec4 position; +in vec4 color; +in vec3 normal; -attribute vec4 ambient; -attribute vec4 specular; -attribute vec4 emissive; -attribute float shininess; +in vec4 ambient; +in vec4 specular; +in vec4 emissive; +in float shininess; varying vec4 vertColor; varying vec4 backVertColor; diff --git a/core/src/processing/opengl/shaders/LightVert-vc4.glsl b/core/src/processing/opengl/shaders/LightVert-vc4.glsl index b3dee92c98..c7a94aede8 100644 --- a/core/src/processing/opengl/shaders/LightVert-vc4.glsl +++ b/core/src/processing/opengl/shaders/LightVert-vc4.glsl @@ -1,24 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 modelviewMatrix; uniform mat4 transformMatrix; @@ -33,14 +13,14 @@ uniform vec3 lightSpecular[8]; uniform vec3 lightFalloff[8]; uniform vec2 lightSpot[8]; -attribute vec4 position; -attribute vec4 color; -attribute vec3 normal; +in vec4 position; +in vec4 color; +in vec3 normal; -attribute vec4 ambient; -attribute vec4 specular; -attribute vec4 emissive; -attribute float shininess; +in vec4 ambient; +in vec4 specular; +in vec4 emissive; +in float shininess; varying vec4 vertColor; varying vec4 backVertColor; diff --git a/core/src/processing/opengl/shaders/LightVert.glsl b/core/src/processing/opengl/shaders/LightVert.glsl index 409e481e67..90023c4ca3 100644 --- a/core/src/processing/opengl/shaders/LightVert.glsl +++ b/core/src/processing/opengl/shaders/LightVert.glsl @@ -1,24 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 modelviewMatrix; uniform mat4 transformMatrix; @@ -33,14 +13,14 @@ uniform vec3 lightSpecular[8]; uniform vec3 lightFalloff[8]; uniform vec2 lightSpot[8]; -attribute vec4 position; -attribute vec4 color; -attribute vec3 normal; +in vec4 position; +in vec4 color; +in vec3 normal; -attribute vec4 ambient; -attribute vec4 specular; -attribute vec4 emissive; -attribute float shininess; +in vec4 ambient; +in vec4 specular; +in vec4 emissive; +in float shininess; varying vec4 vertColor; varying vec4 backVertColor; diff --git a/core/src/processing/opengl/shaders/LineFrag.glsl b/core/src/processing/opengl/shaders/LineFrag.glsl index 7e49972510..fc83390f37 100644 --- a/core/src/processing/opengl/shaders/LineFrag.glsl +++ b/core/src/processing/opengl/shaders/LineFrag.glsl @@ -1,32 +1,14 @@ -/* - Part of the Processing project - http://processing.org +#version 320 es - Copyright (c) 2012-21 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 -*/ - #ifdef GL_ES precision mediump float; precision mediump int; #endif -varying vec4 vertColor; +in vec4 vertColor; + +out vec4 outColor; void main() { - gl_FragColor = vertColor; + outColor = vertColor; } diff --git a/core/src/processing/opengl/shaders/LineVert.glsl b/core/src/processing/opengl/shaders/LineVert.glsl index 3ae4e99235..5cd8e60a63 100644 --- a/core/src/processing/opengl/shaders/LineVert.glsl +++ b/core/src/processing/opengl/shaders/LineVert.glsl @@ -1,24 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es #define PROCESSING_LINE_SHADER @@ -29,11 +9,11 @@ uniform vec4 viewport; uniform int perspective; uniform vec3 scale; -attribute vec4 position; -attribute vec4 color; -attribute vec4 direction; +in vec4 position; +in vec4 color; +in vec4 direction; -varying vec4 vertColor; +out vec4 vertColor; void main() { vec4 posp = modelviewMatrix * position; diff --git a/core/src/processing/opengl/shaders/PointFrag.glsl b/core/src/processing/opengl/shaders/PointFrag.glsl index e00c49e7aa..d3312849db 100644 --- a/core/src/processing/opengl/shaders/PointFrag.glsl +++ b/core/src/processing/opengl/shaders/PointFrag.glsl @@ -1,32 +1,13 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es #ifdef GL_ES precision mediump float; precision mediump int; #endif -varying vec4 vertColor; +in vec4 vertColor; +out vec4 colorOut; void main() { - gl_FragColor = vertColor; + colorOut = vertColor; } diff --git a/core/src/processing/opengl/shaders/PointVert.glsl b/core/src/processing/opengl/shaders/PointVert.glsl index 32fc0122ce..8cf14e246f 100644 --- a/core/src/processing/opengl/shaders/PointVert.glsl +++ b/core/src/processing/opengl/shaders/PointVert.glsl @@ -1,24 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 projectionMatrix; uniform mat4 modelviewMatrix; @@ -26,11 +6,11 @@ uniform mat4 modelviewMatrix; uniform vec4 viewport; uniform int perspective; -attribute vec4 position; -attribute vec4 color; -attribute vec2 offset; +in vec4 position; +in vec4 color; +in vec2 offset; -varying vec4 vertColor; +out vec4 vertColor; void main() { vec4 pos = modelviewMatrix * position; diff --git a/core/src/processing/opengl/shaders/TexFrag.glsl b/core/src/processing/opengl/shaders/TexFrag.glsl index ef54c3641a..60ac02080c 100644 --- a/core/src/processing/opengl/shaders/TexFrag.glsl +++ b/core/src/processing/opengl/shaders/TexFrag.glsl @@ -1,25 +1,4 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ - +#version 320 es #ifdef GL_ES precision mediump float; precision mediump int; @@ -29,9 +8,11 @@ uniform sampler2D texture; uniform vec2 texOffset; -varying vec4 vertColor; -varying vec4 vertTexCoord; +in vec4 vertColor; +in vec4 vertTexCoord; + +out vec4 colorOut; void main() { - gl_FragColor = texture2D(texture, vertTexCoord.st) * vertColor; + colorOut = texture2D(texture, vertTexCoord.st) * vertColor; } diff --git a/core/src/processing/opengl/shaders/TexVert.glsl b/core/src/processing/opengl/shaders/TexVert.glsl index 6c5280fc11..90cf6e1fac 100644 --- a/core/src/processing/opengl/shaders/TexVert.glsl +++ b/core/src/processing/opengl/shaders/TexVert.glsl @@ -1,34 +1,14 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2012-21 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 -*/ +#version 320 es uniform mat4 transformMatrix; uniform mat4 texMatrix; -attribute vec4 position; -attribute vec4 color; -attribute vec2 texCoord; +in vec4 position; +in vec4 color; +in vec2 texCoord; -varying vec4 vertColor; -varying vec4 vertTexCoord; +out vec4 vertColor; +out vec4 vertTexCoord; void main() { gl_Position = transformMatrix * position;