Package com.xith3d.render.jogl

Source Code of com.xith3d.render.jogl.PBufferCanvasPeer

/*
* Copyright Nicolas Brodu
* License: Blah blah blah. If this becomes part of the Xith3D project,
* it will use the project license. In the meantime, let's say it is LGPL. 
*/
package com.xith3d.render.jogl;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

import net.java.games.jogl.DefaultGLCapabilitiesChooser;
import net.java.games.jogl.GL;
import net.java.games.jogl.GLCapabilities;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.impl.GLContext;
import net.java.games.jogl.impl.GLContextFactory;
import net.java.games.jogl.impl.GLPbufferImpl;

import com.xith3d.image.DirectBufferedImage;
import com.xith3d.render.RenderFrame;
import com.xith3d.render.RenderPeer;
import com.xith3d.utility.profile.ProfileTimer;


/**
* @author Nicolas Brodu
*
* This CanvasPeer renders into an Image made from a pbuffer => uses hardware acceleration
* Note that since is is copied back to an image, this is probably not what you want
* to make fast games.
* On the other hand, if all you want is visualize large scenes requirering HW rendering to
* compute, and with a nice Swing interface all around, this maybe worth a look.
*
* This canvas only renders the scene when updateImage is called. It will not render
* the scene when View.renderOnce() is called.
*
* TODO: Many improvements.
* Main idea would be to write directly to a VolatileImage. Indeed, as it is now,
* the rendering happens on a pbuffer in vram. But instead of a direct vram->vram
* operation as could be expected with a VolatileImage, the BufferedImage used here
* does vram->ram and then will do ram->vram again probably when the user displays the image.
* What a mess!
*/
public class PBufferCanvasPeer extends CanvasPeerImpl {

    protected GLPbufferImpl pbuffer;
    protected static GLContext ctx; // context of parent to pbuffer
    protected GLCapabilities glc;
    protected String title = "";
    protected boolean refreshing = false;
    protected DirectBufferedImage snapshotImage = null;
    protected PBufferCanvas3D c3d;
    protected boolean initialized = false;
   
    public PBufferCanvasPeer(PBufferCanvas3D c3d, RenderPeer renderPeer, Object owner, int width, int height, int bits, boolean fullScreen, GLCapabilities gc) throws RuntimeException {
        super(renderPeer, owner, width, height, bits, fullScreen, gc);

        canvas.removeGLEventListener(this);

        this.c3d = c3d;
        glc = gc;
        if (glc==null) glc = new GLCapabilities();
        if (ctx==null) ctx = GLContextFactory.getFactory().createGLContext((Component)owner, glc, new DefaultGLCapabilitiesChooser(), null);
        if (!ctx.canCreatePbufferContext()) throw new RuntimeException("PBuffers not supported.");
        pbuffer = new GLPbufferImpl(ctx.createPbufferContext(glc,width,height));

        pbuffer.addGLEventListener(this);
    }

    public static void initContext(Object owner) {
        ctx = GLContextFactory.getFactory().createGLContext((Component)owner, new GLCapabilities(), new DefaultGLCapabilitiesChooser(), null);
    }
   
    public boolean isInitialized() {
        if (initialized) return true;
        initialized = pbuffer.isInitialized();
        //System.out.println("pbuffer is "+(ret?"":"not ")+"initialized"+(ret?"!":""));
        return initialized;
    }

    public void display(GLDrawable drawable) {
        if (!refreshing) return;
        canvas.setGL(drawable.getGL());
        canvas.setGLU(drawable.getGLU());
        super.display(pbuffer);
        if (snapshotImage==null) snapshotImage = (DirectBufferedImage)DirectBufferedImage.getDirectImageRGB(width, height);
        pbuffer.getGL().glReadPixels(0, 0, width, height, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, snapshotImage.getBackingStore());
        refreshing = false; // one time display
    }
   
    public void init() {
        // Force onscreen GL context to instanciate pbuffers.
        ctx.invokeGL(new Runnable() {
            public void run() {
                //System.out.println("Run in context");
                pbuffer.display();
        }},false,new Runnable() {
            public void run() {
                //System.out.println("Init action");
        }});
    }

    // parent override to render in the pbuffer, not the canvas
    public void render(RenderFrame frame) {
        ProfileTimer.startProfile("PBufferCanvasPeer::render");
        renderFrame = frame;
       
        pbuffer.display();

        ProfileTimer.endProfile();
    }

    // parent override to render in the pbuffer, not the canvas
    public void renderDebug(RenderFrame frame, String logfile) {

        try {
            debugStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(logfile)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }
        debugFrame = true;
        pbuffer.display();
        debugFrame = false;
        debugStream.close();

    }
   
    public BufferedImage updateImage() {
        if (!isInitialized()) {
            init();
            if (!isInitialized()) return null;
        }
        refreshing = true;
        render(c3d.getView().getRenderFrame(c3d));
        return snapshotImage;
    }

    public BufferedImage getLastImage() {
        if (snapshotImage==null) updateImage();
        return snapshotImage;
    }

    /**
     * @see CanvasPeer#setTitle
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * {@inheritDoc}
     */
    public String getTitle() {
        return title;
    }
   
    /**
     * {@inheritDoc}
     */
    public void setSize(int width, int height) {
        try {
            pbuffer.setSize(width, height);
        } catch(net.java.games.jogl.GLException gle) {
            pbuffer.removeGLEventListener(this);
            pbuffer = new GLPbufferImpl(ctx.createPbufferContext(glc,width,height));
            initialized = false;
            snapshotImage = null;
            this.width = width; this.height = height;
            pbuffer.addGLEventListener(this);
        }
    }
    /**
     * {@inheritDoc}
     */
    public void setSize(Dimension d) {
        setSize(d.width, d.height);
    }
    /**
     * {@inheritDoc}
     */
    public Dimension getSize() {
        return pbuffer.getSize();
    }
   
    /**
     * {@inheritDoc}
     */
    public void setLocation(int x, int y) {
        // TODO: link with shapes
    }
   
    /**
     * {@inheritDoc}
     */
    public void setLocation(Point p) {
        // TODO: link with shapes
    }

    /**
     * {@inheritDoc}
     */
    public Point getLocation() {
        return new Point(0,0);
    }
   
   
   
}
TOP

Related Classes of com.xith3d.render.jogl.PBufferCanvasPeer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.