use of au.gov.asd.tac.constellation.utilities.camera.AnaglyphCamera in project constellation by constellation-app.
the class GraphRenderable method display.
/**
* Display this batch store to OpenGL.
*
* display is called in response to various events such as the move moving
* or right clicking. It isn't a continuous render call one might expect in
* an OpenGL application.
*
* @param drawable From the reference: A higher-level abstraction than
* GLDrawable which supplies an event based mechanism (GLEventListener) for
* performing OpenGL rendering. A GLAutoDrawable automatically creates a
* primary rendering context which is associated with the GLAutoDrawable for
* the lifetime of the object.
* @param pMatrix
*/
@Override
public void display(final GLAutoDrawable drawable, final Matrix44f pMatrix) {
final GL3 gl = drawable.getGL().getGL3();
graphDisplayer.bindDisplayer(gl);
if (!skipRedraw) {
// Direction Indicators.
if (motion == -1) {
if (DirectionIndicatorsAction.isShowIndicators()) {
initialMotion = System.currentTimeMillis();
motion = 0;
}
} else if (DirectionIndicatorsAction.isShowIndicators()) {
motion = (System.currentTimeMillis() - initialMotion) / 100F;
} else {
motion = -1;
}
gl.glEnable(GL.GL_LINE_SMOOTH);
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
gl.glClearColor(graphBackgroundColor[0], graphBackgroundColor[1], graphBackgroundColor[2], graphBackgroundColor[3]);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Bind the textures to their texture units.
// This only needs to be done once.
gl.glActiveTexture(GL.GL_TEXTURE0 + TextureUnits.VERTICES);
gl.glBindTexture(GL2ES3.GL_TEXTURE_BUFFER, xyzTexturiser.getTextureName());
gl.glActiveTexture(GL.GL_TEXTURE0 + TextureUnits.ICONS);
gl.glBindTexture(GL2ES3.GL_TEXTURE_2D_ARRAY, iconTextureArray);
gl.glActiveTexture(GL.GL_TEXTURE0 + TextureUnits.VERTEX_FLAGS);
gl.glBindTexture(GL2ES3.GL_TEXTURE_BUFFER, vertexFlagsTexturiser.getTextureName());
final Matrix44f mvMatrix = parent.getDisplayModelViewMatrix();
if (AnaglyphicDisplayAction.isAnaglyphicDisplay()) {
// Draw (some parts of) the graph in anaglyph format.
// To do this, we use an AnaglyphicCamera to draw the graph twice,
// from the viewpoints of the left and right eyes.
//
// The convergence is the plane where objects appear to be at the same depth as the screen.
// Objects closer than this appear to be in front of the screen; objects further than
// this appear to be inside the screen.
//
// Ideally we want this to be some fixed distance from the camera(s), taking the size of
// the graph into consideration; for example, half the width of the graph. However,
// this would mean recalculating the physical size of the graph every time we displayed it (because
// here we don't want to keep track of which graph we're displaying).
//
// As a reasonable substitute, we'll use the distance from the eye to the centre.
// Resetting the view puts the lookAt centre in the middle of the graph anyway,
// and moving around generally seems to keep the centre at the same distance from the eye.
// As a convenient side effect, if the centre is changed to a node, then that node will be at the convergence.
//
final Vector3f eye = camera.lookAtEye;
final Vector3f centre = camera.lookAtCentre;
final float distanceToCentre = Vector3f.subtract(centre, eye).getLength();
final float convergence = Camera.PERSPECTIVE_NEAR + distanceToCentre;
// This is an arbitrary value, arrived at by experimentation.
final float eyeSeparation = 0.25F;
final float aspect = (float) graphDisplayer.getWidth() / (float) graphDisplayer.getHeight();
final AnaglyphCamera anaglyphCam = new AnaglyphCamera(convergence, eyeSeparation, aspect, Camera.FIELD_OF_VIEW, Camera.PERSPECTIVE_NEAR, Camera.PERSPECTIVE_FAR);
// The eye colors are pulled from the preferences by AnaglyphicDisplayAction when
// anaglyphic mode is turned on. A bit ugly, but it gives us quick access to the colors.
// Note that the eye glass colors go to the opposite camera.
//
final AnaglyphicDisplayAction.EyeColorMask leftEyeColor = AnaglyphicDisplayAction.getLeftColorMask();
final AnaglyphicDisplayAction.EyeColorMask rightEyeColor = AnaglyphicDisplayAction.getRightColorMask();
// Draw view from left eye.
//
Matrix44f mv = anaglyphCam.applyLeftFrustum(mvMatrix);
Matrix44f p = anaglyphCam.getProjectionMatrix();
gl.glColorMask(rightEyeColor.red, rightEyeColor.green, rightEyeColor.blue, true);
drawBatches(gl, mv, p, true);
// Draw view from right eye.
//
// Don't overwrite the other eye.
//
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
mv = anaglyphCam.applyRightFrustum(mvMatrix);
p = anaglyphCam.getProjectionMatrix();
gl.glColorMask(leftEyeColor.red, leftEyeColor.green, leftEyeColor.blue, true);
drawBatches(gl, mv, p, true);
gl.glColorMask(true, true, true, true);
} else {
drawBatches(gl, mvMatrix, pMatrix, false);
if (hitTestFboName > 0 && drawHitTest) {
// Draw the lines and icons again with unique colors on the hitTest framebuffer.
// The lines will be thicker for easier hitting.
gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, hitTestFboName);
// Explicitly clear the color to black: we need the default color to be 0 so elements drawn as non-zero are recognised.
gl.glClearColor(0.0F, 0.0F, 0.0F, 1.0F);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glDisable(GL.GL_LINE_SMOOTH);
// Is this the default anyway?
final int[] fboBuffers = { GL.GL_COLOR_ATTACHMENT0 };
gl.glDrawBuffers(1, fboBuffers, 0);
gl.glPolygonOffset(FURTHER_F, FURTHER_U);
if (drawFlags.drawConnections()) {
lineBatcher.setNextDrawIsHitTest();
lineBatcher.drawBatch(gl, camera, mvMatrix, pMatrix, false);
loopBatcher.setNextDrawIsHitTest();
loopBatcher.drawBatch(gl, camera, mvMatrix, pMatrix, false);
}
gl.glPolygonOffset(NEARER_F, NEARER_U);
// Draw node icons into hit test buffer
if (drawFlags.drawNodes()) {
iconBatcher.setNextDrawIsHitTest();
iconBatcher.drawBatch(gl, camera, mvMatrix, pMatrix, false);
}
gl.glPolygonOffset(0, 0);
gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, 0);
gl.glEnable(GL.GL_LINE_SMOOTH);
}
}
}
// Get the graph displayer to render its contents to the screen
graphDisplayer.display(drawable, pMatrix);
}
Aggregations