关于OpenGL游戏全屏模式的设置
使用DirectX的API的话可以给游戏窗口设置指定的显示器和全屏独占模式,但是如果使用OpenGL的API就比较遗憾不能直接设置。
以下内容基于Windows系统。
如果使用OpenGL渲染,第一步当然是创建窗口,如果想要设置全屏模式,需要做以下几步操作:
一、把窗口设为无边框
二、把窗口坐标设置到屏幕左上角,窗口大小设为跟屏幕同样大小
三、如果有必要调整屏幕刷新率,要需要调用 ChangeDisplaySettingsEx 函数
四、窗口必须有焦点并且是激活的。
关于OpenGL全屏独占模式,经过我在某404网站的努力搜索,得到如下的结论:
一、如果OpenGL窗口要使用全屏独占模式,首先得按上面的几步来做。
二、不断调用 wglSwapBuffers 之后,显卡驱动可能就会认为你的全屏OpenGL窗口需要加速渲染,然后把你的窗口设置为全屏独占模式。
三、能不能用全屏独占还得看显卡驱动的心情。
以下是多显示器测试的一点代码:
// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there.
// #include "pch.h"
#include <iostream>
#include <vector>
#include <algorithm> struct UsableMode
{
// 分辨率宽度(像素)
DWORD dmPelsWidth;
// 分辨率高度(像素)
DWORD dmPelsHeight;
// 颜色深度(位)
DWORD dmBitsPerPel;
// 刷新率(Hz)
DWORD dmDisplayFrequency;
}; // 这个操作符用于std::sort排序
bool operator<( const UsableMode& lhs, const UsableMode& rhs )
{
if ( lhs.dmPelsWidth > rhs.dmPelsWidth )
{
return true;
}
else if ( lhs.dmPelsWidth == rhs.dmPelsWidth )
{
if ( lhs.dmPelsHeight > rhs.dmPelsHeight )
{
return true;
}
else if ( lhs.dmPelsHeight == rhs.dmPelsHeight )
{
if ( lhs.dmDisplayFrequency > rhs.dmDisplayFrequency )
{
return true;
}
}
} return false;
} struct UsableMonitor
{
// 存储显示器的设备名,通过这个设备名可以改变任意一台显示器的显示模式
// 此处的设备名是系统逻辑上的标识,这个设备名可以用来指定所有连接到电脑的显示器,不管显示器插在哪张显卡上
wchar_t device_name[]; // 存储显示器在系统桌面中的坐标范围
RECT rect; // 存储所有该显示器支持的显示模式的基本数据
std::vector<UsableMode> modes;
}; BOOL CALLBACK MonitorEnumProc( HMONITOR hMonitor, HDC hDC, LPRECT lpRect, LPARAM lParam )
{
std::vector<UsableMonitor>* monitors = reinterpret_cast<decltype(monitors)>(lParam); monitors->push_back( UsableMonitor() );
auto& new_monitor = monitors->back(); MONITORINFOEX monitor_info;
monitor_info.cbSize = sizeof( monitor_info ); GetMonitorInfo( hMonitor, &monitor_info ); // 存储设备名
wcscpy_s( new_monitor.device_name, monitor_info.szDevice );
// 存储坐标范围
new_monitor.rect = monitor_info.rcMonitor; DEVMODE display_setting;
int mode_num; display_setting.dmSize = sizeof( display_setting );
mode_num = ; // 枚举该显示器所有支持的显示模式
while ( EnumDisplaySettings( monitor_info.szDevice, mode_num++, &display_setting ) )
{
UsableMode new_mode; // 只保存关心的数据就够了
new_mode.dmPelsWidth = display_setting.dmPelsWidth;
new_mode.dmPelsHeight = display_setting.dmPelsHeight;
new_mode.dmBitsPerPel = display_setting.dmBitsPerPel;
new_mode.dmDisplayFrequency = display_setting.dmDisplayFrequency; new_monitor.modes.push_back( new_mode );
} // 排序一下,分辨率高的模式排前面
std::sort( new_monitor.modes.begin(), new_monitor.modes.end() ); wprintf( L"Device: [%s]\n", new_monitor.device_name ); for ( auto& mode : new_monitor.modes )
{
wprintf( L"Mode: Width=%d Height=%d Bits=%d Frequency=%d\n", mode.dmPelsWidth, mode.dmPelsHeight, mode.dmBitsPerPel, mode.dmDisplayFrequency );
} return TRUE;
} int main()
{
// 存储所有可用的显示器
std::vector<UsableMonitor> monitors; // 枚举所有显示器
EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&monitors) ); const UsableMonitor& use_monitor = monitors[]; // 这里随便选一个显示器
const UsableMode& use_mode = use_monitor.modes[]; // 这里随便选一个模式 DEVMODE test_mode;
ZeroMemory( &test_mode, sizeof( test_mode ) );
test_mode.dmSize = sizeof( test_mode );
test_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
test_mode.dmPelsWidth = use_mode.dmPelsWidth;
test_mode.dmPelsHeight = use_mode.dmPelsHeight;
test_mode.dmBitsPerPel = use_mode.dmBitsPerPel;
test_mode.dmDisplayFrequency = use_mode.dmDisplayFrequency; // 改变该显示器的显示模式
// 使用 CDS_FULLSCREEN 这个标识之后系统会在进程退出后还原该显示器的显示模式
ChangeDisplaySettingsEx( use_monitor.device_name, &test_mode, NULL, CDS_FULLSCREEN, NULL ); system( "PAUSE" ); return ;
}
关于OpenGL游戏全屏模式的设置的更多相关文章
- Unity 开发游戏Game分辨率设置
最近自己开发小游戏,突然又被Game视图中设置分辨率被诱惑了, 我到底该怎么设置分辨率设置的图片才能让电脑和手机尺寸显示的大小一模一样呢? 然后又被手机尺寸和分辨率迷惑了! =.= 越搞越混 分辨 ...
- 【OpenGL游戏开发之二】OpenGL常用API
OpenGL常用API 开发基于OpenGL的应用程序,必须先了解OpenGL的库函数.它采用C语言风格,提供大量的函数来进行图形的处理和显示.OpenGL库函数的命名方式非常有规律.所有OpenGL ...
- 【OpenGL游戏开发之三】OpenGl核心函数库汇总
OpenGl核心函数库 glAccum 操作累加缓冲区 glAddSwapHintRectWIN 定义一组被SwapBuffers拷贝的三角形 glAlphaFunc允许设置alpha检测功能 glA ...
- OpenGL的glViewPort窗口设置函数实现分屏
之前实现过全景图片查看(OpenGL的几何变换3之内观察全景图),那么我们需要进行分屏该如何实现呢?如下图: 没错就是以前提过的glViewPort函数,废话不多说了,我直接上代码: //从这里开始进 ...
- 《OpenGL游戏编程》第9章-PlanarShadow关键代码注释
阴影这块确实是难点.说到阴影就必须提到投影矩阵.模板值为1和2时分别渲染.说来话长,仅仅放上代码,供日后查阅. /** 渲染墙面和阴影 */ void CPlanarShadow::Render() ...
- VUE,使用物理引擎Box2D设计类愤怒小鸟的击球游戏--基本架构设置
- Html5 Egret游戏开发 成语大挑战(九)设置界面和声音管理
在上一篇中,简单的使用界面元素快速实现了一个游戏中的二级页面,这种直接在游戏页面上做UI的做法并不太好,原因是,UI会让游戏的压力变大,即使它是隐蔽的,如果同样的功能在其它的地方也是一样的,那么就要写 ...
- OpenGL(三) RGBA颜色设置
OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. 像素点附加颜色信息之后,就必须为每一个像素点额外分配一个内存空间保存该点的颜色信息,对于RGBA颜色模式,保存的数据直接代表了颜色, ...
- OpenGL(七) 光照模型及设置
OpenGL把现实世界中的光照系统近似归为三部分,分别是光源.材质和光照环境. 光源就是光的来源,是"光"这种物质的提供者: 材质是指被光源照射的物体的表面的反射.漫反射(Open ...
随机推荐
- 【Unity Shader】(八) ------ 高级纹理之立方体纹理及光线反射、折射的实现
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) -- ...
- 【LeetCode算法题库】Day7:Remove Nth Node From End of List & Valid Parentheses & Merge Two Lists
[Q19] Given a linked list, remove the n-th node from the end of list and return its head. Example: G ...
- 前端开发利器 livereload -- 从此告别浏览器F5键
各位从事前端开发的童鞋们,大家每天coding && coding,然后F5 && F5,今天推荐一个静态文件在浏览器中自动更新的扩展 livereload,不同手动刷 ...
- 如何掌握 Kubernetes ?系统学习 k8s 的大纲一份
深度剖析 Kubernetes 深度剖析 k8s 如何学习 Kubernetes ?如何入门 Kubernetes? 为了帮帮初学者,2018 年 InfoQ 旗下(就是你知道的那个 InfoQ 哇) ...
- k倍区间:前缀和
[蓝桥杯][2017年第八届真题]k倍区间 题目描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数 ...
- fetch上传文件
通过简单的配置,实现form表单文件上传 var formData = new FormData(); var fileField = document.querySelector("inp ...
- rest_framework_api规范
目录 一.什么是RESTful 二.什么是API 三.RESTful API规范 四.基于Django实现API 五.基于Django Rest Framework框架实现 一. 什么是RESTful ...
- Alpha阶段产品功能说明
先展示一下我们的功能流程图吧~ 一.学生用户 1. 学生登陆注册 BuaaClubs是北航所有在校生都可以注册登录的网站. 登陆界面是这样哒~ 2. 浏览报名活动 同学们可以在这个网站上查看所有社团发 ...
- IT职业道路的苦与甜
每当有人问起你学的是什么专业啊?学的怎么样啊?好不好学啊?等等一些类似的问题.我都会默默的说一句,会者不难,难者不会.当然现在的我还处于菜鸟级别,不过我相信在不久后的一天我一定会脱离菜鸟的行列,然后挺 ...
- 索引超出了数组界限。 在 System.Collections.Generic.Dictionary`2.Resize
博问:Dictionary 超出了数组界限 异常: Exception type: IndexOutOfRangeException Exception message: 索引超出了数组界限. 在 S ...