【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
- 【LWJGL2 WIKI】【基础篇】基础5:全屏
- 【LWJGL2 WIKI】【基础篇】基础1:显示
- 【LWJGL2 WIKI】【基础篇】基础2:输入
- 【LWJGL2 WIKI】【基础篇】基础3:方形
- 【LWJGL2 WIKI】【基础篇】基础4:计时
- 【LWJGL2 WIKI】【现代OpenGL篇】版本选择
- 【LWJGL2 WIKI】【辅助库篇】Slick-Util库:介绍
- 【LWJGL2 WIKI】【现代OpenGL篇】用DrawArrays画方形
- 【LWJGL2 WIKI】【现代OpenGL篇】用DrawElements画方形
- 【LWJGL2 WIKI】【现代OpenGL篇】画颜色方形
- 【LWJGL2 WIKI】【现代OpenGL篇】交叉数据画方形
- 【LWJGL2 WIKI】【现代OpenGL篇】用纹理画方形
- 【LWJGL2 WIKI】【现代OpenGL篇】用BufferSubData更新VBO方形
- 【LWJGL2 WIKI】翻译文章目录
- 【LWJGL2 WIKI】【辅助库篇】Slick-Util库:第一部分-读取图片
- 【LWJGL2 WIKI】【辅助库篇】Slick-Util库:第二部分-读取声音
- 【LWJGL2 WIKI】【辅助库篇】Slick-Util库:第三部分-读取TrueType字体
- 【LWJGL2 WIKI】【现代OpenGL篇】用投影、视图、模型矩阵画方形
- 关于Segmentation fault(段错误)探究
- Hive命令的3种调用方式
- Hive 设置map 和 reduce 的个数
- 关于iOS默认中文输入法乱码的Bug解决记录
- 机器学习方法(六):随机森林Random Forest,bagging
- 【LWJGL2 WIKI】【基础篇】基础5:全屏
- 黑马程序员-C语言-self和super
- 业余非专业型IT人员杂谈
- 20.2 Windos 中的多线程
- python实用技巧(三)
- 安卓SQLite的练习
- 写你的shell,其实很简单
- HDURPG的错排
- java web学习(基础篇)二 走进JSP