package org.jzy3d.plot3d.primitives.textured;
import java.util.ArrayList;
import java.util.List;
// import org.apache.log4j.Logger;
import org.jzy3d.colors.Color;
import org.jzy3d.maths.BoundingBox2d;
import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Coord2d;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.maths.PlaneAxis;
import org.jzy3d.plot3d.primitives.AbstractDrawable;
import org.jzy3d.plot3d.rendering.compat.GLES2CompatUtils;
import org.jzy3d.plot3d.rendering.textures.SharedTexture;
import org.jzy3d.plot3d.rendering.view.Camera;
import org.jzy3d.plot3d.transform.Transform;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES1;
import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureCoords;
/**
* A {@link DrawableTexture} can only mount its texture while the GL2 thread is
* current, so the best is to let draw() automount texture file the first time
* the resource is required. When a texture is loaded for the first time, it
* updates the current view bounds since the texture bounds where up to now
* unknown and fixed to origin with no width.
*
* A {@link DrawableTexture} requires a color filter (default is white), and a
* set of coordinates defining the polygon on which the texture should be drawn.
*
* This texture implementation impose the texture to be perpendicular to a
* {@link PlaneAxis}. It is thus defined with 2d Coordinates in the plane
* defined by the {{@link PlaneAxis}, axisValue}
*
* @author Martin
*
*/
public class DrawableTexture extends AbstractDrawable implements ITranslucent {
// static Logger logger = Logger.getLogger(DrawableTexture.class);
public DrawableTexture(SharedTexture resource) {
this(resource, PlaneAxis.Z, 0, null, null);
}
public DrawableTexture(SharedTexture resource, PlaneAxis orientation) {
this(resource, orientation, 0, null, null);
}
public DrawableTexture(SharedTexture resource, PlaneAxis orientation, float axisValue) {
this(resource, orientation, axisValue, null, null);
}
public DrawableTexture(SharedTexture resource, PlaneAxis orientation, float axisValue, Color filter) {
this(resource, orientation, axisValue, null, filter);
}
public DrawableTexture(SharedTexture resource, PlaneAxis orientation, float axisValue, List coords) {
this(resource, orientation, axisValue, coords, null);
}
public DrawableTexture(SharedTexture resource, PlaneAxis orientation, float axisValue, List coords, Color filter) {
this.alpha = 1.0f;
this.resource = resource;
this.axisValue = axisValue;
this.orientation = orientation;
if (filter == null)
this.filter = Color.WHITE.clone();
else
this.filter = filter;
if (coords != null) {
mapping = coords;
initBoundsWithMapping();
} else {
mapping = getDefaultTextureMapping();
initBoundsWithMapping();
}
}
public Color getColorFilter() {
return filter;
}
public void setColorFilter(Color filter) {
this.filter = filter;
}
@Override
public void setAlphaFactor(float a) {
alpha = a;
}
protected void initBoundsWithMapping() {
BoundingBox2d box = new BoundingBox2d(mapping);
float enlarge = 1;
if (orientation == PlaneAxis.X)
bbox = new BoundingBox3d(axisValue - enlarge, axisValue + enlarge, box.xmin(), box.xmax(), box.ymin(), box.ymax());
else if (orientation == PlaneAxis.Y)
bbox = new BoundingBox3d(box.xmin(), box.xmax(), axisValue - enlarge, axisValue + enlarge, box.ymin(), box.ymax());
else if (orientation == PlaneAxis.Z)
bbox = new BoundingBox3d(box.xmin(), box.xmax(), box.ymin(), box.ymax(), axisValue - enlarge, axisValue + enlarge);
}
protected void initBoundsWithResources() {
float enlarge = 1;
if (orientation == PlaneAxis.X)
bbox = new BoundingBox3d(axisValue - enlarge, axisValue + enlarge, -resource.getHalfWidth(), resource.getHalfWidth(), -resource.getHalfHeight(), resource.getHalfHeight());
else if (orientation == PlaneAxis.Y)
bbox = new BoundingBox3d(-resource.getHalfWidth(), resource.getHalfWidth(), axisValue - enlarge, axisValue + enlarge, -resource.getHalfHeight(), resource.getHalfHeight());
else if (orientation == PlaneAxis.Z)
bbox = new BoundingBox3d(-resource.getHalfWidth(), resource.getHalfWidth(), -resource.getHalfHeight(), resource.getHalfHeight(), axisValue - enlarge, axisValue + enlarge);
}
protected List getDefaultTextureMapping() {
List mapping = new ArrayList(4);
mapping.add(new Coord2d(-resource.getHalfWidth(), -resource.getHalfHeight()));
mapping.add(new Coord2d(+resource.getHalfWidth(), -resource.getHalfHeight()));
mapping.add(new Coord2d(+resource.getHalfWidth(), +resource.getHalfHeight()));
mapping.add(new Coord2d(-resource.getHalfWidth(), +resource.getHalfHeight()));
return mapping;
}
/**
* Must supply the expected size of texture in 3d coordinates.
*
* @return
*/
public static List getManualTextureMapping(float width, float height, float xoffset, float yoffset) {
List mapping = new ArrayList(4);
mapping.add(new Coord2d(xoffset - width / 2, yoffset - height / 2));
mapping.add(new Coord2d(xoffset + width / 2, yoffset - height / 2));
mapping.add(new Coord2d(xoffset + width / 2, yoffset + height / 2));
mapping.add(new Coord2d(xoffset - width / 2, yoffset + height / 2));
return mapping;
}
public static List getManualTextureMapping(float width, float height) {
return getManualTextureMapping(width, height, 0, 0);
}
public void debugMapping() {
// logger.info("mapping");
for (Coord2d c : mapping) {
// logger.info(c);
}
}
@Override
public BoundingBox3d getBounds() {
return bbox.shift(new Coord3d(planePosition, 0));
}
public Coord2d getPlanePosition() {
return planePosition;
}
public void setPlanePosition(Coord2d planePosition) {
this.planePosition = planePosition;
}
public Transform getTextureScale() {
return textureScale;
}
public void setTextureScale(Transform textureScale) {
this.textureScale = textureScale;
}
protected Transform textureScale;
@Override
public void draw(GL gl, GLU glu, Camera cam) {
doTransform(gl, glu, cam);
if (textureScale != null)
textureScale.execute(gl, false);
// Retrieve resource content
Texture texture = resource.getTexture(gl);
TextureCoords coords = resource.getCoords();
// Bind texture & set color filter
texture.bind(gl);
callWithAlphaFactor(gl, filter, alpha);
// Draw
before(gl);
if (gl.isGL2()) {
gl.getGL2().glBegin(GL2GL3.GL_QUADS);
if (orientation == PlaneAxis.X) {
gl.getGL2().glTexCoord2f(coords.left(), coords.bottom());
gl.getGL2().glVertex3f(axisValue, mapping.get(0).x, mapping.get(0).y);
gl.getGL2().glTexCoord2f(coords.right(), coords.bottom());
gl.getGL2().glVertex3f(axisValue, mapping.get(1).x, mapping.get(1).y);
gl.getGL2().glTexCoord2f(coords.right(), coords.top());
gl.getGL2().glVertex3f(axisValue, mapping.get(2).x, mapping.get(2).y);
gl.getGL2().glTexCoord2f(coords.left(), coords.top());
gl.getGL2().glVertex3f(axisValue, mapping.get(3).x, mapping.get(3).y);
} else if (orientation == PlaneAxis.Y) {
gl.getGL2().glTexCoord2f(coords.left(), coords.bottom());
gl.getGL2().glVertex3f(mapping.get(0).x, axisValue, mapping.get(0).y);
gl.getGL2().glTexCoord2f(coords.right(), coords.bottom());
gl.getGL2().glVertex3f(mapping.get(1).x, axisValue, mapping.get(1).y);
gl.getGL2().glTexCoord2f(coords.right(), coords.top());
gl.getGL2().glVertex3f(mapping.get(2).x, axisValue, mapping.get(2).y);
gl.getGL2().glTexCoord2f(coords.left(), coords.top());
gl.getGL2().glVertex3f(mapping.get(3).x, axisValue, mapping.get(3).y);
} else if (orientation == PlaneAxis.Z) {
gl.getGL2().glTexCoord2f(coords.left(), coords.bottom());
gl.getGL2().glVertex3f(planePosition.x + mapping.get(0).x, planePosition.y + mapping.get(0).y, axisValue);
gl.getGL2().glTexCoord2f(coords.right(), coords.bottom());
gl.getGL2().glVertex3f(planePosition.x + mapping.get(1).x, planePosition.y + mapping.get(1).y, axisValue);
gl.getGL2().glTexCoord2f(coords.right(), coords.top());
gl.getGL2().glVertex3f(planePosition.x + mapping.get(2).x, planePosition.y + mapping.get(2).y, axisValue);
gl.getGL2().glTexCoord2f(coords.left(), coords.top());
gl.getGL2().glVertex3f(planePosition.x + mapping.get(3).x, planePosition.y + mapping.get(3).y, axisValue);
}
gl.getGL2().glEnd();
} else {
GLES2CompatUtils.glBegin(GL2GL3.GL_QUADS);
if (orientation == PlaneAxis.X) {
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.bottom());
GLES2CompatUtils.glVertex3f(axisValue, mapping.get(0).x, mapping.get(0).y);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.bottom());
GLES2CompatUtils.glVertex3f(axisValue, mapping.get(1).x, mapping.get(1).y);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.top());
GLES2CompatUtils.glVertex3f(axisValue, mapping.get(2).x, mapping.get(2).y);
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.top());
GLES2CompatUtils.glVertex3f(axisValue, mapping.get(3).x, mapping.get(3).y);
} else if (orientation == PlaneAxis.Y) {
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.bottom());
GLES2CompatUtils.glVertex3f(mapping.get(0).x, axisValue, mapping.get(0).y);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.bottom());
GLES2CompatUtils.glVertex3f(mapping.get(1).x, axisValue, mapping.get(1).y);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.top());
GLES2CompatUtils.glVertex3f(mapping.get(2).x, axisValue, mapping.get(2).y);
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.top());
GLES2CompatUtils.glVertex3f(mapping.get(3).x, axisValue, mapping.get(3).y);
} else if (orientation == PlaneAxis.Z) {
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.bottom());
GLES2CompatUtils.glVertex3f(planePosition.x + mapping.get(0).x, planePosition.y + mapping.get(0).y, axisValue);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.bottom());
GLES2CompatUtils.glVertex3f(planePosition.x + mapping.get(1).x, planePosition.y + mapping.get(1).y, axisValue);
GLES2CompatUtils.glTexCoord2f(coords.right(), coords.top());
GLES2CompatUtils.glVertex3f(planePosition.x + mapping.get(2).x, planePosition.y + mapping.get(2).y, axisValue);
GLES2CompatUtils.glTexCoord2f(coords.left(), coords.top());
GLES2CompatUtils.glVertex3f(planePosition.x + mapping.get(3).x, planePosition.y + mapping.get(3).y, axisValue);
}
gl.getGL2().glEnd();
}
after(gl);
}
protected void before(GL gl) {
if (gl.isGL2()) {
gl.getGL2().glPushMatrix();
// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT,GL2.GL_NICEST);
gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
// gl.glEnable(GL2.GL_POLYGON_OFFSET_FILL);
// gl.glPolygonOffset(1.0f, 1.0f);
// gl.glEnable(GL2.GL_BLEND);
// gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
// gl.glEnable(GL2.GL_ALPHA_TEST);
// gl.glAlphaFunc(GL2.GL_GREATER, 0);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.getGL2().glTexEnvf(GL.GL_TEXTURE_2D, GL2ES1.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
} else {
GLES2CompatUtils.glPushMatrix();
GLES2CompatUtils.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
gl.glEnable(GL.GL_TEXTURE_2D);
GLES2CompatUtils.glTexEnvf(GL.GL_TEXTURE_2D, GL2ES1.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
}
}
protected void after(GL gl) {
gl.glDisable(GL.GL_TEXTURE_2D);
gl.getGL2().glTexEnvi(GL2ES1.GL_TEXTURE_ENV, GL2ES1.GL_TEXTURE_ENV_MODE, GL2ES1.GL_MODULATE);
// gl.glDisable(GL2.GL_ALPHA);
// gl.glDisable(GL2.GL_BLEND);
gl.getGL2().glPopMatrix();
}
public SharedTexture getResource() {
return resource;
}
public void setResource(SharedTexture resource) {
this.resource = resource;
}
@Override
public void applyGeometryTransform(Transform transform) {
// Logger.getLogger(DrawableTexture.class).warn("not implemented");
}
@Override
public void updateBounds() {
// Logger.getLogger(DrawableTexture.class).warn("not implemented");
}
protected SharedTexture resource;
protected PlaneAxis orientation;
protected float texMatMix[] = { 1.0f, 1.0f, 1.0f, 1.0f };
protected Color filter;
protected float axisValue;
protected List mapping;
protected float alpha;
protected Coord2d planePosition = new Coord2d();
}
Ads help maintain this website.