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

来源:互联网 发布:vue.js实战pdf 编辑:程序博客网 时间:2024/04/28 06:51

原文: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

0 0