mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
Improved handling of OpenGL states
This commit is contained in:
@@ -367,12 +367,12 @@ public interface PConstants {
|
||||
|
||||
|
||||
// text alignment modes
|
||||
// are inherited from LEFT, CENTER, RIGHT
|
||||
// are inherited from LEFT, CENTER, RIGHT
|
||||
|
||||
// PTexture
|
||||
|
||||
/** This constant identifies the texture target GL_TEXTURE_2D, that is, textures with normalized coordinates */
|
||||
public static final int NORMAL_TEXTURE = 0;
|
||||
public static final int TEXTURE2D = 0;
|
||||
|
||||
/** This constant identifies the nearest texture filter */
|
||||
public static final int NEAREST = 0;
|
||||
|
||||
@@ -698,7 +698,7 @@ public class PFont implements PConstants {
|
||||
public int addTexture(GL10 gl) {
|
||||
int[] textures = new int[1];
|
||||
|
||||
// We assume GL10.GL_TEXTURE_2D is enabled at this point.
|
||||
// We assume GL10.GL_TEXTURE_2D is enabled at this point (shoud be called by PGraphicsAndroid3D.textLineImpl()).
|
||||
gl.glGenTextures(1, textures, 0);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
|
||||
|
||||
@@ -714,7 +714,7 @@ public class PFont implements PConstants {
|
||||
|
||||
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, texWidth, texHeight, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
|
||||
currentTexID = -1; // No texture is bound.
|
||||
currentTexID = -1; // No texture is currently bound.
|
||||
|
||||
if (texIDList == null) {
|
||||
texIDList = new int[1];
|
||||
|
||||
@@ -38,7 +38,6 @@ import android.opengl.GLSurfaceView.EGLConfigChooser;
|
||||
import android.opengl.GLSurfaceView.Renderer;
|
||||
|
||||
import javax.microedition.khronos.opengles.*;
|
||||
import javax.microedition.khronos.egl.EGL11;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
@@ -117,6 +116,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
*/
|
||||
public static final int MAX_LIGHTS = 8;
|
||||
|
||||
public boolean lights;
|
||||
public int lightCount = 0;
|
||||
|
||||
/** Light types */
|
||||
@@ -291,13 +291,14 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
|
||||
// .......................................................
|
||||
|
||||
protected Stack<PFramebuffer> fbStack;
|
||||
protected PFramebuffer screenFramebuffer;
|
||||
static protected Stack<PFramebuffer> fbStack;
|
||||
static protected PFramebuffer screenFramebuffer;
|
||||
static protected PFramebuffer currentFramebuffer;
|
||||
|
||||
protected PFramebuffer drawFramebuffer;
|
||||
protected PImage[] drawImages;
|
||||
protected PTexture[] drawTextures;
|
||||
protected int drawIndex;
|
||||
protected PFramebuffer currentFramebuffer;
|
||||
protected int[] drawTexCrop;
|
||||
|
||||
// ........................................................
|
||||
@@ -313,7 +314,12 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
boolean clear = true;
|
||||
|
||||
// ........................................................
|
||||
|
||||
boolean blend;
|
||||
int blendMode;
|
||||
|
||||
// ........................................................
|
||||
|
||||
public String OPENGL_VENDOR;
|
||||
public String OPENGL_RENDERER;
|
||||
public String OPENGL_VERSION;
|
||||
@@ -552,16 +558,16 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
public void renderDrawTexture(int idx) {
|
||||
PTexture tex = drawTextures[idx];
|
||||
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex.getGLTextureID());
|
||||
gl.glEnable(tex.getGLTarget());
|
||||
gl.glBindTexture(tex.getGLTarget(), tex.getGLTextureID());
|
||||
gl.glDepthMask(false);
|
||||
gl.glDisable(GL10.GL_BLEND);
|
||||
|
||||
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
|
||||
gl11.glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, drawTexCrop, 0);
|
||||
gl11.glTexParameteriv(tex.getGLTarget(), GL11Ext.GL_TEXTURE_CROP_RECT_OES, drawTexCrop, 0);
|
||||
gl11x.glDrawTexiOES(0, 0, 0, width, height);
|
||||
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
gl.glDisable(tex.getGLTarget());
|
||||
gl.glDepthMask(true);
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
}
|
||||
@@ -570,10 +576,92 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
drawIndex = (drawIndex + 1) % 2;
|
||||
}
|
||||
|
||||
public PImage getBackground() {
|
||||
public PImage getLastFrame() {
|
||||
return drawImages[(drawIndex + 1) % 2];
|
||||
}
|
||||
|
||||
protected void saveGLState() {
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glPushMatrix();
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glPushMatrix();
|
||||
}
|
||||
|
||||
protected void restoreGLState() {
|
||||
// Restoring blending.
|
||||
if (blend) {
|
||||
blend(blendMode);
|
||||
} else {
|
||||
noBlend();
|
||||
}
|
||||
|
||||
// Restoring viewport.
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
// Restoring hints.
|
||||
if (hints[DISABLE_DEPTH_TEST]) {
|
||||
gl.glDisable(GL10.GL_DEPTH_TEST);
|
||||
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
|
||||
} else {
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
// Restoring fill
|
||||
if (fill) {
|
||||
fillFromCalc();
|
||||
}
|
||||
|
||||
// Restoring material properties.
|
||||
ambientFromCalc();
|
||||
specularFromCalc();
|
||||
shininess(shininess);
|
||||
emissiveFromCalc();
|
||||
|
||||
// Restoring lights.
|
||||
if (lights) {
|
||||
for (int i = 0; i < lightCount; i++) {
|
||||
glLightEnable(i);
|
||||
if (lightType[i] == AMBIENT) {
|
||||
glLightAmbient(i);
|
||||
glLightPosition(i);
|
||||
glLightFalloff(i);
|
||||
glLightNoSpot(i);
|
||||
} else if (lightType[i] == DIRECTIONAL) {
|
||||
glLightNoAmbient(i);
|
||||
glLightDirection(i);
|
||||
glLightDiffuse(i);
|
||||
glLightSpecular(i);
|
||||
glLightFalloff(i);
|
||||
glLightNoSpot(i);
|
||||
} else if (lightType[i] == POINT) {
|
||||
glLightNoAmbient(i);
|
||||
glLightPosition(i);
|
||||
glLightDiffuse(i);
|
||||
glLightSpecular(i);
|
||||
glLightFalloff(i);
|
||||
glLightNoSpot(i);
|
||||
} else if (lightType[i] == SPOT) {
|
||||
glLightNoAmbient(i);
|
||||
glLightPosition(i);
|
||||
glLightDirection(i);
|
||||
glLightDiffuse(i);
|
||||
glLightSpecular(i);
|
||||
glLightFalloff(i);
|
||||
glLightSpotAngle(i);
|
||||
glLightSpotConcentration(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
noLights();
|
||||
}
|
||||
|
||||
// Restoring matrices.
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glPopMatrix();
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
// FRAME
|
||||
@@ -599,6 +687,18 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
TRIANGLECOUNT = 0;
|
||||
FACECOUNT = 0;
|
||||
|
||||
if (!primarySurface) {
|
||||
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)parent.g;
|
||||
a3d.saveGLState();
|
||||
|
||||
// Disabling all lights, so the offscreen renderer can set completely
|
||||
// new light configuration (otherwise some light config from the
|
||||
// primary renderer might stay).
|
||||
for (int i = 0; i < a3d.lightCount; i++) {
|
||||
a3d.glLightDisable(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!settingsInited)
|
||||
defaultSettings();
|
||||
|
||||
@@ -614,9 +714,8 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
textureImage = null;
|
||||
textureImagePrev = null;
|
||||
|
||||
// these are necessary for alpha (i.e. fonts) to work
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||
// Blend is needed for alpha (i.e. fonts) to work.
|
||||
blend(BLEND);
|
||||
|
||||
// this is necessary for 3D drawing
|
||||
if (hints[DISABLE_DEPTH_TEST]) {
|
||||
@@ -667,6 +766,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
setFramebuffer(screenFramebuffer);
|
||||
}
|
||||
|
||||
// TODO: rework logic depending on whether this renderer is primarySurface, etc.
|
||||
if (clear) {
|
||||
gl.glClearColor(0, 0, 0, 0);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
@@ -700,7 +800,6 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
pushFramebuffer();
|
||||
setFramebuffer(drawFramebuffer);
|
||||
drawFramebuffer.addColorBuffer(drawTextures[drawIndex]);
|
||||
drawFramebuffer.validFbo();
|
||||
|
||||
gl.glClearColor(0, 0, 0, 0);
|
||||
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
|
||||
@@ -742,6 +841,10 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
|
||||
gl.glFlush();
|
||||
|
||||
if (!primarySurface) {
|
||||
((PGraphicsAndroid3D)parent.g).restoreGLState();
|
||||
}
|
||||
|
||||
report("top endDraw()");
|
||||
/*
|
||||
* if (hints[ENABLE_DEPTH_SORT]) { flush(); }
|
||||
@@ -2282,11 +2385,15 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
/**
|
||||
* Implementation of actual drawing for a line of text.
|
||||
*/
|
||||
protected void textLineImpl(char buffer[], int start, int stop, float x,
|
||||
float y) {
|
||||
protected void textLineImpl(char buffer[], int start, int stop, float x, float y) {
|
||||
// Init opengl state for text rendering...
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
|
||||
if (!blend || blendMode != BLEND) {
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (textFont.texIDList == null) {
|
||||
textFont.initTexture(gl, maxTextureSize, maxTextureSize);
|
||||
// Add all the current glyphs to the texture.
|
||||
@@ -2300,6 +2407,13 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
gl.glColor4f(colorFloats[0], colorFloats[1], colorFloats[2], colorFloats[3]);
|
||||
|
||||
super.textLineImpl(buffer, start, stop, x, y);
|
||||
|
||||
// Restoring current blend mode.
|
||||
if (blend) {
|
||||
blend(blendMode);
|
||||
} else {
|
||||
noBlend();
|
||||
}
|
||||
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
}
|
||||
@@ -3562,6 +3676,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
* </PRE>
|
||||
*/
|
||||
public void lights() {
|
||||
lights = true;
|
||||
gl.glEnable(GL10.GL_LIGHTING);
|
||||
|
||||
// need to make sure colorMode is RGB 255 here
|
||||
@@ -3572,8 +3687,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
lightSpecular(0, 0, 0);
|
||||
|
||||
ambientLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f);
|
||||
directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f,
|
||||
0, 0, -1);
|
||||
directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f, 0, 0, -1);
|
||||
|
||||
colorMode = colorModeSaved;
|
||||
}
|
||||
@@ -3583,8 +3697,9 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
* method is needed.
|
||||
*/
|
||||
public void resetLights() {
|
||||
for (int i = 0; i < lightCount; i++)
|
||||
for (int i = 0; i < lightCount; i++) {
|
||||
glLightDisable(i);
|
||||
}
|
||||
lightCount = 0;
|
||||
}
|
||||
|
||||
@@ -3592,6 +3707,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
* Disables lighting.
|
||||
*/
|
||||
public void noLights() {
|
||||
lights = false;
|
||||
gl.glDisable(GL10.GL_LIGHTING);
|
||||
lightCount = 0;
|
||||
}
|
||||
@@ -4482,15 +4598,18 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
/**
|
||||
* Allows to set custom blend modes for the entire scene, using openGL.
|
||||
*/
|
||||
public void setBlend(int mode) {
|
||||
public void blend(int mode) {
|
||||
blend = true;
|
||||
blendMode = mode;
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
if (mode == BLEND)
|
||||
gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||
else if (mode == ADD)
|
||||
gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
|
||||
else if (mode == MULTIPLY)
|
||||
gl.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_SRC_COLOR);
|
||||
gl.glBlendFunc(GL10.GL_DST_COLOR, GL10.GL_SRC_COLOR);
|
||||
else if (mode == SUBTRACT)
|
||||
gl.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ZERO);
|
||||
gl.glBlendFunc(GL10.GL_ONE_MINUS_DST_COLOR, GL10.GL_ZERO);
|
||||
// TODO: implement all these other blending modes:
|
||||
// else if (blendMode == LIGHTEST)
|
||||
// else if (blendMode == DIFFERENCE)
|
||||
@@ -4503,13 +4622,11 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
// else if (blendMode == BURN)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Processing's default blending mode.
|
||||
*/
|
||||
public void defaultBlend() {
|
||||
gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
public void noBlend() {
|
||||
blend = false;
|
||||
gl.glDisable(GL10.GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
// SAVE
|
||||
|
||||
@@ -281,6 +281,7 @@ public class PTexture implements PConstants {
|
||||
|
||||
int[] convArray = convertToRGBA(intArray, arrayFormat);
|
||||
|
||||
gl.glEnable(glTarget);
|
||||
gl.glBindTexture(glTarget, glTextureID[0]);
|
||||
|
||||
if (usingMipmaps) {
|
||||
@@ -293,7 +294,7 @@ public class PTexture implements PConstants {
|
||||
}
|
||||
gl.glTexSubImage2D(glTarget, 0, 0, 0, glWidth, glHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(convArray));
|
||||
|
||||
gl.glBindTexture(glTarget, 0);
|
||||
gl.glDisable(glTarget);
|
||||
}
|
||||
|
||||
|
||||
@@ -719,7 +720,8 @@ public class PTexture implements PConstants {
|
||||
(glMinFilter == GL10.GL_LINEAR_MIPMAP_NEAREST) ||
|
||||
(glMinFilter == GL10.GL_NEAREST_MIPMAP_LINEAR) ||
|
||||
(glMinFilter == GL10.GL_LINEAR_MIPMAP_LINEAR));
|
||||
|
||||
|
||||
gl.glEnable(glTarget);
|
||||
gl.glGenTextures(1, glTextureID, 0);
|
||||
gl.glBindTexture(glTarget, glTextureID[0]);
|
||||
gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_MIN_FILTER, glMinFilter);
|
||||
@@ -727,13 +729,10 @@ public class PTexture implements PConstants {
|
||||
gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexImage2D(glTarget, 0, glInternalFormat, glWidth, glHeight, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
|
||||
|
||||
// TODO: check what is the correct way of unbind textures, the following or glDisable(glTarget);
|
||||
gl.glBindTexture(glTarget, 0);
|
||||
gl.glDisable(glTarget);
|
||||
|
||||
flippedX = false;
|
||||
flippedY = false;
|
||||
|
||||
flippedY = false;
|
||||
|
||||
// If non-power-of-two textures are not supported, and the specified width or height
|
||||
// is non-power-of-two, then glWidth (glHeight) will be greater than w (h) because it
|
||||
@@ -769,7 +768,7 @@ public class PTexture implements PConstants {
|
||||
Parameters res = new Parameters();
|
||||
|
||||
if ( glTarget == GL10.GL_TEXTURE_2D ) {
|
||||
res.target = NORMAL_TEXTURE;
|
||||
res.target = TEXTURE2D;
|
||||
}
|
||||
|
||||
if (glInternalFormat == GL10.GL_RGB) {
|
||||
@@ -810,7 +809,7 @@ public class PTexture implements PConstants {
|
||||
* @param params GLTextureParameters
|
||||
*/
|
||||
protected void setParameters(Parameters params) {
|
||||
if (params.target == NORMAL_TEXTURE) {
|
||||
if (params.target == TEXTURE2D) {
|
||||
glTarget = GL10.GL_TEXTURE_2D;
|
||||
} else {
|
||||
throw new RuntimeException("GTexture: Unknown texture target");
|
||||
@@ -901,21 +900,21 @@ public class PTexture implements PConstants {
|
||||
* Creates an instance of GLTextureParameters, setting all the parameters to default values.
|
||||
*/
|
||||
public Parameters() {
|
||||
target = PTexture.NORMAL_TEXTURE;
|
||||
target = PTexture.TEXTURE2D;
|
||||
format = PTexture.ARGB;
|
||||
minFilter = PTexture.LINEAR;
|
||||
magFilter = PTexture.LINEAR;
|
||||
}
|
||||
|
||||
public Parameters(int format) {
|
||||
target = PTexture.NORMAL_TEXTURE;
|
||||
target = PTexture.TEXTURE2D;
|
||||
this.format = format;
|
||||
minFilter = PTexture.LINEAR;
|
||||
magFilter = PTexture.LINEAR;
|
||||
}
|
||||
|
||||
public Parameters(int format, int filter) {
|
||||
target = PTexture.NORMAL_TEXTURE;
|
||||
target = PTexture.TEXTURE2D;
|
||||
this.format = format;
|
||||
minFilter = filter;
|
||||
magFilter = filter;
|
||||
|
||||
Reference in New Issue
Block a user