⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jogldisplaysystem.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2008 SRA International, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jme.system.jogl;

import java.awt.Canvas;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.Threading;
import javax.media.opengl.glu.GLU;

import com.jme.image.Image;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.renderer.RenderContext;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.TextureRenderer.Target;
import com.jme.renderer.jogl.JOGLContextCapabilities;
import com.jme.renderer.jogl.JOGLRenderer;
import com.jme.renderer.jogl.JOGLTextureRenderer;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.system.canvas.CanvasConstructor;
import com.jme.system.canvas.JMECanvas;
import com.jme.util.WeakIdentityCache;
import com.jmex.awt.input.AWTKeyInput;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.jogl.JOGLAWTCanvas;

/**
 * @author Steve Vaughan
 */
public class JOGLDisplaySystem extends DisplaySystem {

    private static final Logger logger = Logger
            .getLogger(JOGLDisplaySystem.class.getName());

    private JOGLRenderer renderer;

    private RenderContext<GLContext> currentContext;

    private WeakIdentityCache<GLContext, RenderContext<GLContext>> contextStore = new WeakIdentityCache<GLContext, RenderContext<GLContext>>();

    private Frame frame;

    private GLAutoDrawable autoDrawable;

    private boolean isClosing = false;
    
    private final DisplayMode[] availableDisplayModes;
    
    
    JOGLDisplaySystem() {
        super();
        final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        availableDisplayModes = gd.getDisplayModes();
    }

    @Override
    public synchronized void createWindow(int width, int height, int bpp,
            int frq, boolean fs) {
        // For know, ensure that only one OpenGL surface is active at a time.
        if (autoDrawable != null) {
            throw new IllegalStateException(
                    "There is already an active OpenGL canvas.");
        }

        // Validate window dimensions.
        if (width <= 0 || height <= 0) {
            throw new JmeException("Invalid resolution values: " + width + " "
                    + height);
        }

        // Validate bit depth.
        if ((bpp != 32) && (bpp != 16) && (bpp != 24)) {
            throw new JmeException("Invalid pixel depth: " + bpp);
        }

        // Remember the window surfaces attributes.
        this.width = width;
        this.height = height;
        this.bpp = bpp;
        this.frq = frq;
        this.fs = fs;

        // Create the OpenGL canvas, and place it within a frame.
        frame = new Frame();

        // Create the singleton's status.
        GLCanvas glCanvas = createGLCanvas();
        glCanvas.setSize(width, height);
        glCanvas.setIgnoreRepaint(true);
        glCanvas.setAutoSwapBufferMode(false);

        // GLContext glContext = glCanvas.getContext();
        // glContext.makeCurrent();
        frame.add(glCanvas);
        final boolean isDisplayModeModified;
        final GraphicsDevice gd = GraphicsEnvironment
                .getLocalGraphicsEnvironment().getDefaultScreenDevice();
        // Get the current display mode
        final DisplayMode previousDisplayMode=gd.getDisplayMode();
        // Handle full screen mode if requested.
        if (fs) {
            frame.setUndecorated(true);
            // Check if the full-screen mode is supported by the OS
            boolean isFullScreenSupported = gd.isFullScreenSupported();
            if (isFullScreenSupported) {
            	gd.setFullScreenWindow(frame);
                // Check if display mode changes are supported by the OS
                if (gd.isDisplayChangeSupported()) {
                    // Get all available display modes
                    DisplayMode[] displayModes = gd.getDisplayModes();
                    DisplayMode multiBitsDepthSupportedDisplayMode = null;
                    DisplayMode refreshRateUnknownDisplayMode = null;
                    DisplayMode multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = null;
                    DisplayMode matchingDisplayMode = null;
                    DisplayMode currentDisplayMode;
                    // Look for the display mode that matches with our parameters
                    // Look for some display modes that are close to these parameters
                    // and that could be used as substitutes
                    // On some machines, the refresh rate is unknown and/or multi bit
                    // depths are supported. If you try to force a particular refresh 
                    // rate or a bit depth, you might find no available display mode
                    // that matches exactly with your parameters
                    for (int i = 0; i < displayModes.length && matchingDisplayMode == null; i++) {
                        currentDisplayMode = displayModes[i];
                        if (currentDisplayMode.getWidth()  == width &&
                            currentDisplayMode.getHeight() == height) {
                            if (currentDisplayMode.getBitDepth() == bpp) {
                                if (currentDisplayMode.getRefreshRate() == frq) {
                                    matchingDisplayMode = currentDisplayMode;
                                } else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
                                    refreshRateUnknownDisplayMode = currentDisplayMode;
                                }
                            } else if (currentDisplayMode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) {
                                if (currentDisplayMode.getRefreshRate() == frq) {
                                    multiBitsDepthSupportedDisplayMode = currentDisplayMode;
                                } else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
                                    multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = currentDisplayMode;
                                }
                            }
                        }
                    }
                    DisplayMode nextDisplayMode = null;
                    if (matchingDisplayMode != null) {
                        nextDisplayMode = matchingDisplayMode;                    
                    } else if (multiBitsDepthSupportedDisplayMode != null) {
                        nextDisplayMode = multiBitsDepthSupportedDisplayMode;
                    } else if (refreshRateUnknownDisplayMode != null) {
                        nextDisplayMode = refreshRateUnknownDisplayMode;
                    } else if (multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode != null) {
                        nextDisplayMode = multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode;
                    } else {
                        isFullScreenSupported = false;
                    }
                    // If we have found a display mode that approximatively matches
                    // with the input parameters, use it
                    if (nextDisplayMode != null) {
                        gd.setDisplayMode(nextDisplayMode);
                        isDisplayModeModified = true;
                    } else { 
                        isDisplayModeModified = false;
                    }
                 } else {
                     isDisplayModeModified = false;
                     // Resize the canvas if the display mode cannot be changed
                     // and the screen size is not equal to the canvas size
                     Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
                     if (screenSize.width != width || screenSize.height != height) {
                         this.width = screenSize.width;
                         this.height = screenSize.height;
                         glCanvas.setSize(screenSize);
                     }
                 }
            } else {
                isDisplayModeModified = false;
            }
                
            // Software windowed full-screen mode
            if (!isFullScreenSupported) {
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                // Resize the canvas
                glCanvas.setSize(screenSize);
                this.width = screenSize.width;
                this.height = screenSize.height;
                // Resize the frame so that it occupies the whole screen
                frame.setSize(screenSize);
                // Set its location at the top left corner
                frame.setLocation(0, 0);
            }
        }
        // Otherwise, center the window on the screen.
        else {
            isDisplayModeModified = false;
            frame.pack();

            int x, y;
            x = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2;
            y = (Toolkit.getDefaultToolkit().getScreenSize().height - height) / 2;
            frame.setLocation(x, y);
        }
       
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public final void windowClosing(WindowEvent e) {
                isClosing = true;
                // If required, restore the previous display mode
                if (isDisplayModeModified) {
                    gd.setDisplayMode(previousDisplayMode);
                }
                // If required, get back to the windowed mode
                if (gd.getFullScreenWindow() == frame) {
                    gd.setFullScreenWindow(null);
                }
            }
        });

        // Make the window visible to realize the OpenGL surface.
        frame.setVisible(true);

        // Make the GLContext the current.
        GLContext glContext = glCanvas.getContext();
        while (glContext.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException interruption) {
                logger.warning("Interruped while waiting for makeCurrent()");
            }
        }
        // Now it is time to request the focus because the canvas
        // is displayable, focusable, visible and its ancestor is
        // visible too
        glCanvas.requestFocusInWindow();

        // Store singleton OpenGL canvas.
        autoDrawable = glCanvas;
        created = true;

        // Initialize the display system.
        initForWindow(width, height);
    }

    @Override
    public JMECanvas createCanvas(int width, int height) {
        return this.createCanvas(width, height, "AWT",
                new HashMap<String, Object>());
    }

    @Override
    public synchronized JMECanvas createCanvas(int width, int height,
            String type, HashMap<String, Object> props) {
        // For know, ensure that only one OpenGL surface is active at a time.
        if (autoDrawable != null) {
            throw new IllegalStateException(
                    "There is already an active OpenGL canvas.");
        }

        // Validate window dimensions.
        if (width <= 0 || height <= 0) {
            throw new JmeException("Invalid resolution values: " + width + " "
                    + height);
        }

        // Retrieve registered constructor, or throw an exception.
        CanvasConstructor constructor = makeCanvasConstructor(type);

        // Remember the window surfaces attributes.
        this.width = width;
        this.height = height;
        // FIXME this.bpp = bpp;
        // FIXME this.frq = frq;
        this.fs = false;

        // Create the new canvas.
        JMECanvas glCanvas = constructor.makeCanvas(props);

        // Configure the canvas.
        ((Canvas) glCanvas).setSize(width, height);

        // Store singleton OpenGL canvas.
        autoDrawable = (GLAutoDrawable) glCanvas;
        created = true;

        return glCanvas;
    }

    @Override
    public void createHeadlessWindow(int w, int h, int bpp) {
        // TODOX Auto-generated method stub
    }

    @Override
    public TextureRenderer createTextureRenderer(final int width,
            final int height, final Target target) {
        if (!isCreated()) {
            return null;
        }

        return new JOGLTextureRenderer(width, height, this, renderer);
    }

    public static JOGLAWTCanvas createGLCanvas() {
        // Initialize the OpenGL requested capabilities.
        final GLCapabilities caps = new GLCapabilities();
        caps.setHardwareAccelerated(true);
        caps.setDoubleBuffered(true);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -