Search in sources :

Example 1 with AnaglyphCamera

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);
}
Also used : AnaglyphCamera(au.gov.asd.tac.constellation.utilities.camera.AnaglyphCamera) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) GL3(com.jogamp.opengl.GL3)

Aggregations

AnaglyphCamera (au.gov.asd.tac.constellation.utilities.camera.AnaglyphCamera)1 Matrix44f (au.gov.asd.tac.constellation.utilities.graphics.Matrix44f)1 Vector3f (au.gov.asd.tac.constellation.utilities.graphics.Vector3f)1 GL3 (com.jogamp.opengl.GL3)1