package org.geogebra.common.geogebra3D.euclidian3D.openGL;
import java.util.ArrayList;
import org.geogebra.common.awt.GPoint;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianController3D;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianController3D.IntersectionCurve;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D;
import org.geogebra.common.geogebra3D.euclidian3D.Hitting;
import org.geogebra.common.geogebra3D.euclidian3D.HittingSphere;
import org.geogebra.common.geogebra3D.euclidian3D.draw.DrawLabel3D;
import org.geogebra.common.geogebra3D.euclidian3D.draw.Drawable3D;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.Manager.Type;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.geos.GeoElement;
/**
* Renderer using "implementation" for java/web/android/etc.
*
* @author mathieu
*
*/
public abstract class RendererWithImpl extends Renderer
implements RendererShadersInterface {
private RendererImpl rendererImpl;
/**
* basic constructor
*
* @param view
* 3D view
* @param type
* GL2/SHADER
*/
public RendererWithImpl(EuclidianView3D view, RendererType type) {
super(view, type);
if (view3D.getCompanion().useInputDepthForHitting()) {
hitting = new HittingSphere(view3D);
} else {
hitting = new Hitting(view3D);
}
}
/**
* dummy renderer (when no GL available)
*/
public RendererWithImpl() {
super();
}
@Override
final public void setClipPlanes(double[][] minMax) {
if (rendererImpl != null) {
rendererImpl.setClipPlanes(minMax);
}
}
@Override
final protected void setMatrixView() {
rendererImpl.setMatrixView();
}
@Override
final protected void unsetMatrixView() {
rendererImpl.unsetMatrixView();
}
@Override
final public void setColor(float r, float g, float b, float a) {
rendererImpl.setColor(r, g, b, a);
}
@Override
final public void initMatrix() {
rendererImpl.initMatrix();
}
@Override
final public void initMatrixForFaceToScreen() {
rendererImpl.initMatrixForFaceToScreen();
}
@Override
final public void resetMatrix() {
rendererImpl.resetMatrix();
}
@Override
final protected void pushSceneMatrix() {
rendererImpl.pushSceneMatrix();
}
@Override
final protected void setLightPosition(float[] values) {
rendererImpl.setLightPosition(values);
}
@Override
final protected void setLightAmbiantDiffuse(float ambiant0, float diffuse0,
float ambiant1, float diffuse1) {
rendererImpl.setLightAmbiantDiffuse(ambiant0, diffuse0, ambiant1,
diffuse1);
}
@Override
final protected void setLight(int light) {
rendererImpl.setLight(light);
}
@Override
final protected void setColorMaterial() {
rendererImpl.setColorMaterial();
}
@Override
final protected void setLightModel() {
rendererImpl.setLightModel();
}
@Override
final protected void setAlphaFunc() {
rendererImpl.setAlphaFunc();
}
@Override
final protected void setView() {
rendererImpl.setView();
}
@Override
final protected void setStencilLines() {
rendererImpl.setStencilLines();
}
@Override
final protected void viewOrtho() {
rendererImpl.viewOrtho();
}
@Override
final protected void viewPersp() {
rendererImpl.viewPersp();
}
@Override
final protected void viewGlasses() {
rendererImpl.viewGlasses();
}
@Override
final protected void viewOblique() {
rendererImpl.viewOblique();
}
@Override
final protected Manager createManager() {
return rendererImpl.createManager();
}
@Override
final public void enableTextures() {
rendererImpl.enableTextures();
}
@Override
final public void disableTextures() {
rendererImpl.disableTextures();
}
@Override
final protected void useShaderProgram() {
rendererImpl.useShaderProgram();
}
@Override
final protected void draw() {
rendererImpl.draw();
super.draw();
}
@Override
final protected void updatePerspValues() {
super.updatePerspValues();
if (rendererImpl != null) {
rendererImpl.updatePerspValues();
}
}
@Override
final public void updateGlassesValues() {
super.updateGlassesValues();
if (rendererImpl != null) {
rendererImpl.updateGlassesValues();
}
}
@Override
public void updateProjectionObliqueValues() {
super.updateProjectionObliqueValues();
if (rendererImpl != null) {
rendererImpl.updateProjectionObliqueValues();
}
}
@Override
final public void updateOrthoValues() {
if (rendererImpl != null) {
rendererImpl.updateOrthoValues();
}
}
@Override
final public void enableTexturesForText() {
super.enableTexturesForText();
rendererImpl.enableTexturesForText();
}
@Override
final protected void initRenderingValues() {
super.initRenderingValues();
rendererImpl.initRenderingValues();
}
@Override
final protected void drawFaceToScreen() {
rendererImpl.drawFaceToScreenAbove();
super.drawFaceToScreen();
rendererImpl.drawFaceToScreenBelow();
}
@Override
final protected void drawFaceToScreenEnd() {
rendererImpl.drawFaceToScreenAbove();
super.drawFaceToScreenEnd();
rendererImpl.drawFaceToScreenBelow();
}
@Override
final protected void enableLightingOnInit() {
rendererImpl.enableLightingOnInit();
}
@Override
final protected void initCulling() {
rendererImpl.initCulling();
}
@Override
final protected void drawTranspNotCurved() {
rendererImpl.drawTranspNotCurved();
}
@Override
final public void disableCulling() {
rendererImpl.disableCulling();
}
@Override
final public void setCullFaceFront() {
rendererImpl.setCullFaceFront();
}
@Override
final public void setCullFaceBack() {
rendererImpl.setCullFaceBack();
}
@Override
final public void loadColorBuffer(GLBuffer fbColors, int length) {
rendererImpl.loadColorBuffer(fbColors, length);
}
@Override
final public void loadNormalBuffer(GLBuffer fbNormals, int length) {
rendererImpl.loadNormalBuffer(fbNormals, length);
}
@Override
final public void loadTextureBuffer(GLBuffer fbTextures, int length) {
rendererImpl.loadTextureBuffer(fbTextures, length);
}
@Override
final public void loadVertexBuffer(GLBuffer fbVertices, int length) {
rendererImpl.loadVertexBuffer(fbVertices, length);
}
@Override
final public void loadIndicesBuffer(GLBufferIndices arrayI, int length) {
rendererImpl.loadIndicesBuffer(arrayI, length);
}
@Override
final public void setCenter(Coords center) {
rendererImpl.setCenter(center);
}
@Override
final public void resetCenter() {
rendererImpl.resetCenter();
}
@Override
final public boolean areTexturesEnabled() {
return rendererImpl.areTexturesEnabled();
}
@Override
final public void draw(Type type, int length) {
rendererImpl.draw(type, length);
}
@Override
final public void storeBuffer(GLBuffer fb, int length, int size,
GPUBuffer buffers, int attrib) {
rendererImpl.storeBuffer(fb, length, size, buffers, attrib);
}
@Override
final public void storeElementBuffer(short[] fb, int length,
GPUBuffer buffers) {
rendererImpl.storeElementBuffer(fb, length, buffers);
}
@Override
final public void bindBufferForIndices(GPUBuffer buffer) {
rendererImpl.bindBufferForIndices(buffer);
}
@Override
final public void createArrayBuffer(GPUBuffer buffer) {
rendererImpl.createArrayBuffer(buffer);
}
@Override
final public void createElementBuffer(GPUBuffer buffer) {
rendererImpl.createElementBuffer(buffer);
}
@Override
final public void removeArrayBuffer(GPUBuffer buffer) {
rendererImpl.removeArrayBuffer(buffer);
}
@Override
final public void removeElementBuffer(GPUBuffer buffer) {
rendererImpl.removeElementBuffer(buffer);
}
@Override
final public void bindBufferForVertices(GPUBuffer buffer, int size) {
rendererImpl.bindBufferForVertices(buffer, size);
}
@Override
final public void bindBufferForColors(GPUBuffer buffer, int size,
GLBuffer fbColors) {
rendererImpl.bindBufferForColors(buffer, size, fbColors);
}
@Override
final public void bindBufferForNormals(GPUBuffer buffer, int size,
GLBuffer fbNormals) {
rendererImpl.bindBufferForNormals(buffer, size, fbNormals);
}
@Override
final public void bindBufferForTextures(GPUBuffer buffer, int size,
GLBuffer fbTextures) {
rendererImpl.bindBufferForTextures(buffer, size, fbTextures);
}
@Override
final protected void initShaders() {
rendererImpl.initShaders();
}
@Override
final public void disableShine() {
rendererImpl.disableShine();
}
@Override
final public void enableShine() {
rendererImpl.enableShine();
}
@Override
protected void setBufferLeft() {
rendererImpl.setBufferLeft();
}
@Override
protected void setBufferRight() {
rendererImpl.setBufferRight();
}
@Override
final protected void clearColorBuffer() {
rendererImpl.glClear(rendererImpl.getGL_COLOR_BUFFER_BIT());
}
@Override
final protected void clearDepthBuffer() {
rendererImpl.glClear(rendererImpl.getGL_DEPTH_BUFFER_BIT());
}
@Override
final protected void setStencilFunc(int value) {
rendererImpl.setStencilFunc(value);
}
@Override
final public void enableCulling() {
rendererImpl.glEnable(rendererImpl.getGL_CULL_FACE());
}
@Override
final public void disableBlending() {
rendererImpl.glDisable(rendererImpl.getGL_BLEND());
}
@Override
final public void enableBlending() {
rendererImpl.glEnable(rendererImpl.getGL_BLEND());
}
@Override
final public void enableMultisample() {
rendererImpl.enableMultisample();
}
@Override
public final void disableMultisample() {
rendererImpl.disableMultisample();
}
@Override
final public void enableAlphaTest() {
rendererImpl.enableAlphaTest();
}
@Override
final public void disableAlphaTest() {
rendererImpl.disableAlphaTest();
}
@Override
final public void enableDepthMask() {
rendererImpl.enableDepthMask();
}
@Override
final public void disableDepthMask() {
rendererImpl.disableDepthMask();
}
@Override
final public void enableDepthTest() {
rendererImpl.glEnable(rendererImpl.getGL_DEPTH_TEST());
}
@Override
final public void disableDepthTest() {
rendererImpl.glDisable(rendererImpl.getGL_DEPTH_TEST());
}
@Override
final public void setColorMask(boolean r, boolean g, boolean b, boolean a) {
rendererImpl.setColorMask(r, g, b, a);
}
@Override
final public void setClearColor(float r, float g, float b, float a) {
rendererImpl.setClearColor(r, g, b, a);
}
@Override
final public void setLayer(int l) {
rendererImpl.setLayer(l);
}
@Override
final public void genTextures2D(int number, int[] index) {
rendererImpl.genTextures2D(number, index);
}
@Override
final public void bindTexture(int index) {
rendererImpl.bindTexture(index);
}
@Override
final protected void enableClipPlanes() {
rendererImpl.enableClipPlanes();
}
@Override
final protected void disableClipPlanes() {
rendererImpl.disableClipPlanes();
}
@Override
final public void setLabelOrigin(float[] origin) {
rendererImpl.setLabelOrigin(origin);
}
@Override
final public void enableLighting() {
rendererImpl.enableLighting();
}
@Override
final public void disableLighting() {
rendererImpl.disableLighting();
}
@Override
final public void initLighting() {
rendererImpl.initLighting();
}
@Override
final public boolean useShaders() {
return rendererImpl.useShaders();
}
@Override
final public void enableFading() {
rendererImpl.enableFading();
}
@Override
final public void enableDash() {
rendererImpl.enableDash();
}
@Override
final protected float[] getLightPosition() {
return rendererImpl.getLightPosition();
}
@Override
final public void setDashTexture(int index) {
rendererImpl.setDashTexture(index);
}
@Override
final protected void drawSurfacesOutline() {
rendererImpl.drawSurfacesOutline();
}
@Override
final public void setHits(GPoint mouseLoc, int threshold) {
if (mouseLoc == null) {
return;
}
hitting.setHits(mouseLoc, threshold);
}
private Hitting hitting;
@Override
final public Hitting getHitting() {
return hitting;
}
@Override
final public GeoElement getLabelHit(GPoint mouseLoc) {
if (mouseLoc == null) {
return null;
}
return hitting.getLabelHit(mouseLoc);
}
@Override
final public void pickIntersectionCurves() {
ArrayList<IntersectionCurve> curves = ((EuclidianController3D) view3D
.getEuclidianController()).getIntersectionCurves();
// picking objects
for (IntersectionCurve intersectionCurve : curves) {
Drawable3D d = intersectionCurve.drawable;
d.updateForHitting(); // we may need an update
if (!d.hit(hitting)
|| d.getPickingType() != PickingType.POINT_OR_CURVE) { // we
// assume
// that
// hitting
// infos
// are
// updated
// from
// last
// mouse
// move
d.setZPick(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
}
}
}
/** shift for getting alpha value */
private static final int ALPHA_SHIFT = 24;
/**
* get alpha channel of the array ARGB description
*
* @param pix
* @return the alpha channel of the array ARGB description
*/
protected static byte[] ARGBtoAlpha(DrawLabel3D label, int[] pix) {
return ARGBtoAlpha(label, label.getWidth(), label.getHeight(), pix);
}
protected static byte[] ARGBtoAlpha(DrawLabel3D label, int labelWidthRes,
int labelHeightRes, int[] pix) {
// calculates 2^n dimensions
int w = firstPowerOfTwoGreaterThan(labelWidthRes);
int h = firstPowerOfTwoGreaterThan(labelHeightRes);
// Application.debug("width="+width+",height="+height+"--w="+w+",h="+h);
// get alpha channel and extends to 2^n dimensions
byte[] bytes = new byte[w * h];
byte b;
int bytesIndex = 0;
int pixIndex = 0;
int xmin = w, xmax = 0, ymin = h, ymax = 0;
for (int y = 0; y < labelHeightRes; y++) {
for (int x = 0; x < labelWidthRes; x++) {
b = (byte) (pix[pixIndex] >> ALPHA_SHIFT);
if (b != 0) {
if (x < xmin) {
xmin = x;
}
if (x > xmax) {
xmax = x;
}
if (y < ymin) {
ymin = y;
}
if (y > ymax) {
ymax = y;
}
}
bytes[bytesIndex] = b;
bytesIndex++;
pixIndex++;
}
bytesIndex += w - labelWidthRes;
}
// values for picking (ignore transparent bytes)
label.setPickingDimension(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
// update width and height
label.setDimensionPowerOfTwo(w, h);
return bytes;
}
@Override
protected void enableNormalNormalized() {
// only need for non-shader renderers
}
// //////////////////////////////////////////////////
// TODO implement methods below for export image (see
// RendererCheckGLVersionD)
@Override
public void display() {
// used in desktop and for export image
}
@Override
protected void exportImageEquirectangular() {
// only in Desktop for now
}
@Override
protected void initExportImageEquirectangularTiles() {
// only in Desktop for now
}
@Override
protected void setExportImageEquirectangularTileLeft(int i) {
// only in Desktop for now
}
@Override
protected void setExportImageEquirectangularTileRight(int i) {
// only in Desktop for now
}
@Override
protected void setExportImageEquirectangularFromTiles() {
// only in Desktop for now
}
@Override
protected void exportImage() {
// only in Desktop; Web uses canvas methods
}
@Override
protected void selectFBO() {
rendererImpl.selectFBO();
}
@Override
protected void unselectFBO() {
rendererImpl.unselectFBO();
}
@Override
protected void needExportImage(double scale, int w, int h) {
rendererImpl.needExportImage(scale, w, h);
}
@Override
protected void setExportImageDimension(int w, int h) {
rendererImpl.setExportImageDimension(w, h);
}
protected RendererImpl getRendererImpl() {
return rendererImpl;
}
protected void setRendererImpl(RendererImpl rendererImpl) {
this.rendererImpl = rendererImpl;
}
}