【LWJGL2 WIKI】【基础篇】基础5:全屏

本文档介绍了LWJGL2中如何使用全屏模式,包括为何选择全屏、如何创建全屏Display、DisplayMode的概念、获取全屏支持的分辨率,以及方便的切换分辨率方法和垂直同步的使用。提供了使用F键切换全屏,V键控制垂直同步的示例代码。
摘要由CSDN通过智能技术生成

原文:http://wiki.lwjgl.org/wiki/LWJGL_Basics_5_%28Fullscreen%29

Why use Fullscreen? 为何用全屏?

有许多原因,包括以下:

  • 改变屏幕分辨率会得到更快的游戏运行速度,使图片看起来效果更佳
  • 使垂直同步可以自由分割图形(??不知道什么意思)
  • 使用户更有沉浸感

Using Fullscreen 使用全屏

创建教程1里的Display窗口

Display.setDisplayMode(new DisplayMode(width,height));
Display.create();

要用全屏Display,设置好DisplayMode后,调用Display.setFullscreen(true).

Display.setDisplayMode(displayMode);
Display.setFullscreen(true);
Display.create();

What is a DisplayMode? DisplayMode是什么?

DisplayMode将许多参数压缩组成的一个类,包括以下参数:

  • getWidth() - 窗口的象素宽度
  • getHeight() - 窗口的象素高度
  • getBitsPerPixel() - 每象素的位数,也就是色彩数
  • getFrequency() - 画帧时的刷新率

初始化DisplayMode和桌面分辨率一样,原始的桌面分辨率可以任意时候调用DisplayMode取到。

Display.getDesktopDisplayMode().

Obtaining DisplayModes supported in fullscreen 获取全屏支持的DisplayMode

显卡支持的全屏分辨率可以调用Display.getAvailableDisplayModes()方法取到,此列表可以之后拿来遍历以获取对应的DisplayMode。

DisplayMode[] modes = Display.getAvailableDisplayModes();

for (int i=0;i<modes.length;i++) {
    DisplayMode current = modes[i];
    System.out.println(current.getWidth() + "x" + current.getHeight() + "x" +
                        current.getBitsPerPixel() + " " + current.getFrequency() + "Hz");
}

用Display.setDisplayMode()来设置DisplayMode。如果窗口己创建,它将直接立刻调整大小。如果还没创建,用Display.create()创建。
当前的DisplayMode可以用Display.getDisplayMode()取到,如果还没设置的话,它将和Display.getDesktopDisplayMode()一样。
Display.setFullscreen(boolean)方法用来切换全屏、窗口模式。
BitsPerPixel值更适用于32位色(Windows)和24位色(Linux和Mac),现在16位色、256色甚至更震惊的16色的老式电脑应该已经十分稀有了。因此,直接使用默认的桌面色彩值就是一个不错的主意。
Frequency值是帧描画率,同样的,使用默认的桌面刷新率可能对显示器支持最佳(虽然某些视频卡可能支持其他的)。CRT显示器可以轻松支持各种不同的频率和刷新率,但是TFT显示器现在越来越通用一些,所以最好用默认的频繁就好。

Convenience method to Switch Resolution 方便的切换分辨率的方法

根据上面讲的,用下面例子里的方法可以获取并切换到一个需要的分辨率。

/**
 * Set the display mode to be used
 *
 * @param width The width of the display required
 * @param height The height of the display required
 * @param fullscreen True if we want fullscreen mode
 */
public void setDisplayMode(int width, int height, boolean fullscreen) {

    // return if requested DisplayMode is already set
    if ((Display.getDisplayMode().getWidth() == width) &&
        (Display.getDisplayMode().getHeight() == height) &&
    (Display.isFullscreen() == fullscreen)) {
        return;
    }

    try {
        DisplayMode targetDisplayMode = null;

    if (fullscreen) {
        DisplayMode[] modes = Display.getAvailableDisplayModes();
        int freq = 0;

        for (int i=0;i<modes.length;i++) {
            DisplayMode current = modes[i];

        if ((current.getWidth() == width) && (current.getHeight() == height)) {
            if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
                if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
                targetDisplayMode = current;
                freq = targetDisplayMode.getFrequency();
                        }
                    }

            // if we've found a match for bpp and frequence against the
            // original display mode then it's probably best to go for this one
            // since it's most likely compatible with the monitor
            if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel()) &&
                        (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency())) {
                            targetDisplayMode = current;
                            break;
                    }
                }
            }
        } else {
            targetDisplayMode = new DisplayMode(width,height);
        }

        if (targetDisplayMode == null) {
            System.out.println("Failed to find value mode: "+width+"x"+height+" fs="+fullscreen);
            return;
        }

        Display.setDisplayMode(targetDisplayMode);
        Display.setFullscreen(fullscreen);

    } catch (LWJGLException e) {
        System.out.println("Unable to setup mode "+width+"x"+height+" fullscreen="+fullscreen + e);
    }
}

Vsync 垂直同步

为了自由分割图形,需要开启垂直同步。用Display.setVSyncEnabled(boolean)来开启或禁用此功能。垂直同步仅在全屏时工作,因为窗口程度是没有直接权限访问或控制整个屏幕的,所有的缓冲区交换都是由操作系统处理的。但是在窗口模式下,垂直同步仍然可以用来限制帧率。
一个完整的例子如下。用F键切换全屏/窗口,用V键开启或禁用简直同步。

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class FullscreenExample {

    /** position of quad */
    float x = 400, y = 300;
    /** angle of quad rotation */
    float rotation = 0;

    /** time at last frame */
    long lastFrame;

    /** frames per second */
    int fps;
    /** last fps time */
    long lastFPS;

    /** is VSync Enabled */
    boolean vsync;

    public void start() {
        try {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(0);
        }

        initGL(); // init OpenGL
        getDelta(); // call once before loop to initialise lastFrame
        lastFPS = getTime(); // call before loop to initialise fps timer

        while (!Display.isCloseRequested()) {
            int delta = getDelta();

            update(delta);
            renderGL();

            Display.update();
            Display.sync(60); // cap fps to 60fps
        }

        Display.destroy();
    }

    public void update(int delta) {
        // rotate quad
        rotation += 0.15f * delta;

        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) x -= 0.35f * delta;
        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) x += 0.35f * delta;

        if (Keyboard.isKeyDown(Keyboard.KEY_UP)) y -= 0.35f * delta;
        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) y += 0.35f * delta;

        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (Keyboard.getEventKey() == Keyboard.KEY_F) {
                    setDisplayMode(800, 600, !Display.isFullscreen());
                }
                else if (Keyboard.getEventKey() == Keyboard.KEY_V) {
                    vsync = !vsync;
                    Display.setVSyncEnabled(vsync);
                }
            }
        }

        // keep quad on the screen
        if (x < 0) x = 0;
        if (x > 800) x = 800;
        if (y < 0) y = 0;
        if (y > 600) y = 600;

        updateFPS(); // update FPS Counter
    }

    /**
     * Set the display mode to be used
     *
     * @param width The width of the display required
     * @param height The height of the display required
     * @param fullscreen True if we want fullscreen mode
     */
    public void setDisplayMode(int width, int height, boolean fullscreen) {

        // return if requested DisplayMode is already set
                if ((Display.getDisplayMode().getWidth() == width) &&
            (Display.getDisplayMode().getHeight() == height) &&
            (Display.isFullscreen() == fullscreen)) {
            return;
        }

        try {
            DisplayMode targetDisplayMode = null;

            if (fullscreen) {
                DisplayMode[] modes = Display.getAvailableDisplayModes();
                int freq = 0;

                for (int i=0;i<modes.length;i++) {
                    DisplayMode current = modes[i];

                    if ((current.getWidth() == width) && (current.getHeight() == height)) {
                        if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
                            if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
                                targetDisplayMode = current;
                                freq = targetDisplayMode.getFrequency();
                            }
                        }

                        // if we've found a match for bpp and frequence against the
                        // original display mode then it's probably best to go for this one
                        // since it's most likely compatible with the monitor
                        if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel()) &&
                            (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency())) {
                            targetDisplayMode = current;
                            break;
                        }
                    }
                }
            } else {
                targetDisplayMode = new DisplayMode(width,height);
            }

            if (targetDisplayMode == null) {
                System.out.println("Failed to find value mode: "+width+"x"+height+" fs="+fullscreen);
                return;
            }

            Display.setDisplayMode(targetDisplayMode);
            Display.setFullscreen(fullscreen);

        } catch (LWJGLException e) {
            System.out.println("Unable to setup mode "+width+"x"+height+" fullscreen="+fullscreen + e);
        }
    }

    /**
     * Calculate how many milliseconds have passed
     * since last frame.
     *
     * @return milliseconds passed since last frame
     */
    public int getDelta() {
        long time = getTime();
        int delta = (int) (time - lastFrame);
        lastFrame = time;

        return delta;
    }

    /**
     * Get the accurate system time
     *
     * @return The system time in milliseconds
     */
    public long getTime() {
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }

    /**
     * Calculate the FPS and set it in the title bar
     */
    public void updateFPS() {
        if (getTime() - lastFPS > 1000) {
            Display.setTitle("FPS: " + fps);
            fps = 0;
            lastFPS += 1000;
        }
        fps++;
    }

    public void initGL() {
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, 800, 0, 600, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public void renderGL() {
        // Clear The Screen And The Depth Buffer
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

        // R,G,B,A Set The Color To Blue One Time Only
        GL11.glColor3f(0.5f, 0.5f, 1.0f);

        // draw quad
        GL11.glPushMatrix();
            GL11.glTranslatef(x, y, 0);
            GL11.glRotatef(rotation, 0f, 0f, 1f);
            GL11.glTranslatef(-x, -y, 0);

            GL11.glBegin(GL11.GL_QUADS);
                GL11.glVertex2f(x - 50, y - 50);
                GL11.glVertex2f(x + 50, y - 50);
                GL11.glVertex2f(x + 50, y + 50);
                GL11.glVertex2f(x - 50, y + 50);
            GL11.glEnd();
        GL11.glPopMatrix();
    }

    public static void main(String[] argv) {
        FullscreenExample fullscreenExample = new FullscreenExample();
        fullscreenExample.start();
    }
}

Credit

Tutorial Credit - Ninja Cave

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值