com.ardor3d.framework.lwjgl.LwjglCanvasRenderer.java Source code

Java tutorial

Introduction

Here is the source code for com.ardor3d.framework.lwjgl.LwjglCanvasRenderer.java

Source

/**
 * Copyright (c) 2008-2012 Ardor Labs, Inc.
 *
 * This file is part of Ardor3D.
 *
 * Ardor3D is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or at <http://www.ardor3d.com/LICENSE>.
 */

package com.ardor3d.framework.lwjgl;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBMultisample;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;

import com.ardor3d.annotation.MainThread;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.framework.DisplaySettings;
import com.ardor3d.framework.Scene;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Camera.ProjectionMode;
import com.ardor3d.renderer.ContextCapabilities;
import com.ardor3d.renderer.ContextManager;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.lwjgl.LwjglContextCapabilities;
import com.ardor3d.renderer.lwjgl.LwjglRenderer;
import com.ardor3d.util.Ardor3dException;

public class LwjglCanvasRenderer implements CanvasRenderer {
    protected Scene _scene;
    protected Camera _camera;
    protected boolean _doSwap;
    protected LwjglRenderer _renderer;
    protected Object _context = new Object();
    protected int _frameClear = Renderer.BUFFER_COLOR_AND_DEPTH;

    private RenderContext _currentContext;
    private LwjglCanvasCallback _canvasCallback;

    // NOTE: This code commented out by Petter 090224, since it isn't really ready to be used,
    // and since it is at the moment more work than it is worth to get it ready. Later on, when
    // we have solved some more fundamental problems, it is probably time to revisit this.

    // ensure availability of LWJGL natives
    // {
    // final String[] libraryPaths = LwjglLibraryPaths.getLibraryPaths(System.getProperty("os.name"), System
    // .getProperty("os.arch"));
    //
    // try {
    // NativeLoader.makeLibrariesAvailable(libraryPaths);
    // } catch (final Exception e) {
    // ; // ignore
    // }
    // }

    public LwjglCanvasRenderer(final Scene scene) {
        _scene = scene;
    }

    @MainThread
    protected ContextCapabilities createContextCapabilities() {
        return new LwjglContextCapabilities(GLContext.getCapabilities());
    }

    @Override
    public LwjglRenderer createRenderer() {
        return new LwjglRenderer();
    }

    @MainThread
    public void init(final DisplaySettings settings, final boolean doSwap) {
        _doSwap = doSwap;

        // Look up a shared context, if a shared LwjglCanvasRenderer is given.
        // XXX: Shared contexts will probably not work... lwjgl does not seem to have a way to make a new glcontext that
        // shares lists, textures, etc.
        RenderContext sharedContext = null;
        if (settings.getShareContext() != null) {
            sharedContext = ContextManager
                    .getContextForKey(settings.getShareContext().getRenderContext().getContextKey());
        }

        try {
            _canvasCallback.makeCurrent();
            GLContext.useContext(_context);
        } catch (final LWJGLException e) {
            throw new Ardor3dException("Unable to init CanvasRenderer.", e);
        }

        final ContextCapabilities caps = createContextCapabilities();
        _currentContext = new RenderContext(this, caps, sharedContext);

        ContextManager.addContext(this, _currentContext);
        ContextManager.switchContext(this);

        _renderer = createRenderer();

        if (settings.getSamples() != 0 && caps.isMultisampleSupported()) {
            GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);
        }

        _renderer.setBackgroundColor(ColorRGBA.BLACK);

        if (_camera == null) {
            /** Set up how our camera sees. */
            _camera = new Camera(settings.getWidth(), settings.getHeight());
            _camera.setFrustumPerspective(45.0f, (float) settings.getWidth() / (float) settings.getHeight(), 1,
                    1000);
            _camera.setProjectionMode(ProjectionMode.Perspective);

            final Vector3 loc = new Vector3(0.0f, 0.0f, 10.0f);
            final Vector3 left = new Vector3(-1.0f, 0.0f, 0.0f);
            final Vector3 up = new Vector3(0.0f, 1.0f, 0.0f);
            final Vector3 dir = new Vector3(0.0f, 0f, -1.0f);
            /** Move our camera to a correct place and orientation. */
            _camera.setFrame(loc, left, up, dir);
        } else {
            // use new width and height to set ratio.
            _camera.setFrustumPerspective(_camera.getFovY(),
                    (float) settings.getWidth() / (float) settings.getHeight(), _camera.getFrustumNear(),
                    _camera.getFrustumFar());
        }
    }

    @MainThread
    public boolean draw() {

        // set up context for rendering this canvas
        makeCurrentContext();

        // render stuff, first apply our camera if we have one
        if (_camera != null) {
            if (Camera.getCurrentCamera() != _camera) {
                _camera.update();
            }
            _camera.apply(_renderer);
        }
        _renderer.clearBuffers(_frameClear);

        final boolean drew = _scene.renderUnto(_renderer);
        _renderer.flushFrame(drew && _doSwap);

        // release the context if we're done (swapped and all)
        if (_doSwap) {
            releaseCurrentContext();
        }

        return drew;
    }

    public Camera getCamera() {
        return _camera;
    }

    public Scene getScene() {
        return _scene;
    }

    public void setScene(final Scene scene) {
        _scene = scene;
    }

    public LwjglCanvasCallback getCanvasCallback() {
        return _canvasCallback;
    }

    public void setCanvasCallback(final LwjglCanvasCallback canvasCallback) {
        _canvasCallback = canvasCallback;
    }

    public Renderer getRenderer() {
        return _renderer;
    }

    public void makeCurrentContext() throws Ardor3dException {
        try {
            _canvasCallback.makeCurrent();
            GLContext.useContext(_context);
            ContextManager.switchContext(this);
        } catch (final LWJGLException e) {
            throw new Ardor3dException("Failed to claim OpenGL context.", e);
        }
    }

    public void releaseCurrentContext() {
        try {
            GLContext.useContext(null);
            _canvasCallback.releaseContext();
        } catch (final LWJGLException e) {
            throw new RuntimeException(e);
        }
    }

    public void setCamera(final Camera camera) {
        _camera = camera;
    }

    public RenderContext getRenderContext() {
        return _currentContext;
    }

    public int getFrameClear() {
        return _frameClear;
    }

    public void setFrameClear(final int buffers) {
        _frameClear = buffers;
    }
}