mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Added drawRectangle() to PGL, reimplemented set(x, y, color) method.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user