From edf64a99fb1f341a22796c3f8892fb1cb8bce865 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 27 Mar 2012 20:52:13 +0000 Subject: [PATCH] Added drawRectangle() to PGL, reimplemented set(x, y, color) method. --- android/core/src/processing/opengl/PGL.java | 100 +++++++++++++++++- .../processing/opengl/PGraphicsOpenGL.java | 52 ++------- .../opengl/src/processing/opengl/PGL.java | 100 +++++++++++++++++- .../processing/opengl/PGraphicsOpenGL.java | 52 ++------- 4 files changed, 210 insertions(+), 94 deletions(-) diff --git a/android/core/src/processing/opengl/PGL.java b/android/core/src/processing/opengl/PGL.java index 112fa7a74..70b59a24b 100644 --- a/android/core/src/processing/opengl/PGL.java +++ b/android/core/src/processing/opengl/PGL.java @@ -281,7 +281,7 @@ public class PGL { protected int texTCoordLoc; protected float[] texCoords = { - // X, Y, U, V + // X, Y, U, V -1.0f, -1.0f, 0.0f, 0.0f, +1.0f, -1.0f, 1.0f, 0.0f, -1.0f, +1.0f, 0.0f, 1.0f, @@ -306,6 +306,37 @@ public class PGL { /////////////////////////////////////////////////////////////////////////////////// + // Rectangle rendering + + protected boolean loadedRectShader = false; + protected int rectShaderProgram; + protected int rectVertShader; + protected int rectFragShader; + + protected int rectVertLoc; + protected int rectColorLoc; + + protected float[] rectCoords = { + // X, Y + -1.0f, -1.0f, + +1.0f, -1.0f, + -1.0f, +1.0f, + +1.0f, +1.0f, + }; + protected FloatBuffer rectData; + + protected String rectVertShaderSource = "attribute vec2 inVertex;" + + "void main() {" + + " gl_Position = vec4(inVertex, 0, 1);" + + "}"; + + protected String rectFragShaderSource = "uniform vec4 rectColor;" + + "void main() {" + + " gl_FragColor = rectColor;" + + "}"; + + /////////////////////////////////////////////////////////////////////////////////// + // Intialization, finalization @@ -1234,6 +1265,73 @@ public class PGL { } + public void drawRectangle(float r, float g, float b, float a, + int scrX0, int scrY0, int scrX1, int scrY1) { + if (!loadedRectShader) { + rectVertShader = createShader(GL_VERTEX_SHADER, rectVertShaderSource); + rectFragShader = createShader(GL_FRAGMENT_SHADER, rectFragShaderSource); + if (0 < rectVertShader && 0 < rectFragShader) { + rectShaderProgram = createProgram(rectVertShader, rectFragShader); + } + if (0 < rectShaderProgram) { + rectVertLoc = glGetAttribLocation(rectShaderProgram, "inVertex"); + rectColorLoc = glGetUniformLocation(rectShaderProgram, "rectColor"); + } + rectData = ByteBuffer.allocateDirect(rectCoords.length * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); + loadedRectShader = true; + } + + if (0 < rectShaderProgram) { + // When drawing the rectangle we don't write to the + // depth mask, so the rectangle remains in the background + // and can be occluded by anything drawn later, even if + // if it is behind it. + boolean[] val = new boolean[1]; + glGetBooleanv(GL_DEPTH_WRITEMASK, val, 0); + boolean writeMask = val[0]; + glDepthMask(false); + + glUseProgram(rectShaderProgram); + + glEnableVertexAttribArray(rectVertLoc); + glUniform4f(rectColorLoc, r, g, b, a); + + // Vertex coordinates of the rectangle are specified + // in normalized screen space (-1, 1): + + // Corner 1 + rectCoords[0] = 2 * (float)scrX0 / pg.width - 1; + rectCoords[1] = 2 * (float)scrY0 / pg.height - 1; + + // Corner 2 + rectCoords[2] = 2 * (float)scrX1 / pg.width - 1; + rectCoords[3] = 2 * (float)scrY0 / pg.height - 1; + + // Corner 3 + rectCoords[4] = 2 * (float)scrX0 / pg.width - 1; + rectCoords[5] = 2 * (float)scrY1 / pg.height - 1; + + // Corner 4 + rectCoords[6] = 2 * (float)scrX1 / pg.width - 1; + rectCoords[7] = 2 * (float)scrY1 / pg.height - 1; + + rectData.rewind(); + rectData.put(rectCoords); + + rectData.position(0); + glVertexAttribPointer(rectVertLoc, 2, GL_FLOAT, false, 2 * SIZEOF_FLOAT, rectData); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(rectVertLoc); + + glUseProgram(0); + + glDepthMask(writeMask); + } + } + + // bit shifting this might be more efficient static public int nextPowerOfTwo(int val) { int ret = 1; diff --git a/android/core/src/processing/opengl/PGraphicsOpenGL.java b/android/core/src/processing/opengl/PGraphicsOpenGL.java index 0337d1aba..84da76704 100644 --- a/android/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/android/core/src/processing/opengl/PGraphicsOpenGL.java @@ -5058,55 +5058,15 @@ public class PGraphicsOpenGL extends PGraphics { } - // TODO: doesn't appear to work public void set(int x, int y, int argb) { flush(); + + float a = ((argb >> 24) & 0xFF) / 255.0f; + float r = ((argb >> 16) & 0xFF) / 255.0f; + float g = ((argb >> 8) & 0xFF) / 255.0f; + float b = ((argb >> 0) & 0xFF) / 255.0f; - int getset = 0; - - if (BIG_ENDIAN) { - // convert ARGB to RGBA - getset = (argb << 8) | 0xff; - } else { - // convert ARGB to ABGR - getset = (argb & 0xff00ff00) | ((argb << 16) & 0xff0000) - | ((argb >> 16) & 0xff); - } - - if (getsetBuffer == null) { - getsetBuffer = IntBuffer.allocate(1); - getsetBuffer.rewind(); - } - - getsetBuffer.put(0, getset); - getsetBuffer.rewind(); - - if (getsetTexture == null) { - getsetTexture = new PTexture(parent, 1, 1, new PTexture.Parameters(ARGB, POINT)); - } - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - copyToTexture(getsetTexture, getsetBuffer, 0, 0, 1, 1); - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - drawTexture(getsetTexture, 0, 0, 1, 1, x, height - y, 1, 1); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } + pgl.drawRectangle(r, g, b, a, x, y, x + 1, y + 1); } diff --git a/java/libraries/opengl/src/processing/opengl/PGL.java b/java/libraries/opengl/src/processing/opengl/PGL.java index 0fb7f63b6..07b5ed3a8 100644 --- a/java/libraries/opengl/src/processing/opengl/PGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGL.java @@ -309,7 +309,7 @@ public class PGL { protected int texTCoordLoc; protected float[] texCoords = { - // X, Y, U, V + // X, Y, U, V -1.0f, -1.0f, 0.0f, 0.0f, +1.0f, -1.0f, 1.0f, 0.0f, -1.0f, +1.0f, 0.0f, 1.0f, @@ -333,6 +333,37 @@ public class PGL { /////////////////////////////////////////////////////////////////////////////////// + // Rectangle rendering + + protected boolean loadedRectShader = false; + protected int rectShaderProgram; + protected int rectVertShader; + protected int rectFragShader; + + protected int rectVertLoc; + protected int rectColorLoc; + + protected float[] rectCoords = { + // X, Y + -1.0f, -1.0f, + +1.0f, -1.0f, + -1.0f, +1.0f, + +1.0f, +1.0f, + }; + protected FloatBuffer rectData; + + protected String rectVertShaderSource = "attribute vec2 inVertex;" + + "void main() {" + + " gl_Position = vec4(inVertex, 0, 1);" + + "}"; + + protected String rectFragShaderSource = "uniform vec4 rectColor;" + + "void main() {" + + " gl_FragColor = rectColor;" + + "}"; + + /////////////////////////////////////////////////////////////////////////////////// + // Intialization, finalization @@ -1256,6 +1287,73 @@ public class PGL { } + public void drawRectangle(float r, float g, float b, float a, + int scrX0, int scrY0, int scrX1, int scrY1) { + if (!loadedRectShader) { + rectVertShader = createShader(GL_VERTEX_SHADER, rectVertShaderSource); + rectFragShader = createShader(GL_FRAGMENT_SHADER, rectFragShaderSource); + if (0 < rectVertShader && 0 < rectFragShader) { + rectShaderProgram = createProgram(rectVertShader, rectFragShader); + } + if (0 < rectShaderProgram) { + rectVertLoc = glGetAttribLocation(rectShaderProgram, "inVertex"); + rectColorLoc = glGetUniformLocation(rectShaderProgram, "rectColor"); + } + rectData = ByteBuffer.allocateDirect(rectCoords.length * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); + loadedRectShader = true; + } + + if (0 < rectShaderProgram) { + // When drawing the rectangle we don't write to the + // depth mask, so the rectangle remains in the background + // and can be occluded by anything drawn later, even if + // if it is behind it. + boolean[] val = new boolean[1]; + glGetBooleanv(GL_DEPTH_WRITEMASK, val, 0); + boolean writeMask = val[0]; + glDepthMask(false); + + glUseProgram(rectShaderProgram); + + glEnableVertexAttribArray(rectVertLoc); + glUniform4f(rectColorLoc, r, g, b, a); + + // Vertex coordinates of the rectangle are specified + // in normalized screen space (-1, 1): + + // Corner 1 + rectCoords[0] = 2 * (float)scrX0 / pg.width - 1; + rectCoords[1] = 2 * (float)scrY0 / pg.height - 1; + + // Corner 2 + rectCoords[2] = 2 * (float)scrX1 / pg.width - 1; + rectCoords[3] = 2 * (float)scrY0 / pg.height - 1; + + // Corner 3 + rectCoords[4] = 2 * (float)scrX0 / pg.width - 1; + rectCoords[5] = 2 * (float)scrY1 / pg.height - 1; + + // Corner 4 + rectCoords[6] = 2 * (float)scrX1 / pg.width - 1; + rectCoords[7] = 2 * (float)scrY1 / pg.height - 1; + + rectData.rewind(); + rectData.put(rectCoords); + + rectData.position(0); + glVertexAttribPointer(rectVertLoc, 2, GL_FLOAT, false, 2 * SIZEOF_FLOAT, rectData); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(rectVertLoc); + + glUseProgram(0); + + glDepthMask(writeMask); + } + } + + // bit shifting this might be more efficient static public int nextPowerOfTwo(int val) { int ret = 1; diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 4d8001cd1..89d5fdaa9 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -5034,55 +5034,15 @@ public class PGraphicsOpenGL extends PGraphics { } - // TODO: doesn't appear to work public void set(int x, int y, int argb) { flush(); + + float a = ((argb >> 24) & 0xFF) / 255.0f; + float r = ((argb >> 16) & 0xFF) / 255.0f; + float g = ((argb >> 8) & 0xFF) / 255.0f; + float b = ((argb >> 0) & 0xFF) / 255.0f; - int getset = 0; - - if (BIG_ENDIAN) { - // convert ARGB to RGBA - getset = (argb << 8) | 0xff; - } else { - // convert ARGB to ABGR - getset = (argb & 0xff00ff00) | ((argb << 16) & 0xff0000) - | ((argb >> 16) & 0xff); - } - - if (getsetBuffer == null) { - getsetBuffer = IntBuffer.allocate(1); - getsetBuffer.rewind(); - } - - getsetBuffer.put(0, getset); - getsetBuffer.rewind(); - - if (getsetTexture == null) { - getsetTexture = new PTexture(parent, 1, 1, new PTexture.Parameters(ARGB, POINT)); - } - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - copyToTexture(getsetTexture, getsetBuffer, 0, 0, 1, 1); - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - drawTexture(getsetTexture, 0, 0, 1, 1, x, height - y, 1, 1); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } + pgl.drawRectangle(r, g, b, a, x, y, x + 1, y + 1); }