c – 在OpenGL / GLFW 3.2中切换窗口和全屏
我正在学习
Linux上的OpenGL,但我不能让模式切换工作(窗口全屏和后退).
窗口似乎进入全屏但看起来不正确.要切换模式,正在创建一个新窗口,旧窗口将被销毁. void OpenGLWindow::FullScreen(bool fullScreen,int width,int height) { GLFWwindow *oldHandle = m_window; m_fullscreen = fullScreen; m_width = width; m_height = height; m_window = glfwCreateWindow(width,height,m_caption.c_str(),fullScreen ? m_monitor : NULL,m_window); if (m_window == NULL) { glfwTerminate(); throw std::runtime_error("Failed to recreate window."); } glfwDestroyWindow(oldHandle); m_camera->Invalidate(); // Use entire window for rendering. glViewport(0,width,height); glfwMakeContextCurrent(m_window); glfwSwapInterval(1); if (m_keyboardHandler) SetKeyboardHandler(m_keyboardHandler); } 初始窗口 全屏(不正确) 回到窗口 更新问题 我已更新代码以使用您的代码并获得相同的问题.在你的建议我现在更新相机,但再次无济于事:( void OpenGLCamera::Invalidate() { RecalculateProjection(m_perspProjInfo->Width(),m_perspProjInfo->Height()); m_recalculateViewMatrix = true; m_recalculatePerspectiveMatrix = true; m_recalculateProjectionMatrix = true; } void OpenGLCamera::RecalculateProjection(int width,int height) { float aspectRatio = float(width) / height; float frustumYScale = cotangent(degreesToRadians( m_perspProjInfo->FieldOfView() / 2)); float frustumXScale = frustumYScale; if (width > height) { // Shrink the x scale in eye-coordinate space,so that when geometry is // projected to ndc-space,it is widened out to become square. m_projectionMatrix[0][0] = frustumXScale / aspectRatio; m_projectionMatrix[1][1] = frustumYScale; } else { // Shrink the y scale in eye-coordinate space,it is widened out to become square. m_projectionMatrix[0][0] = frustumXScale; m_projectionMatrix[1][1] = frustumYScale * aspectRatio; } } Rabbid:当我调整大小时: Rabbid:当我全屏播出时: 解决方法
在下文中,我将描述一个小而方便的类,它处理调整GLFW窗口的大小并处理开关全屏窗口的开关.
所有使用过的GLFW功能都在 GLFW documentation中有详细记载. #include <GL/gl.h> #include <GLFW/glfw3.h> #include <array> #include <stdexcept> class OpenGLWindow { private: std::array< int,2 > _wndPos {0,0}; std::array< int,2 > _wndSize {0,2 > _vpSize {0,0}; bool _updateViewport = true; GLFWwindow * _wnd = nullptr; GLFWmonitor * _monitor = nullptr; void Resize( int cx,int cy ); public: void Init( int width,int height ); static void CallbackResize(GLFWwindow* window,int cx,int cy); void MainLoop ( void ); bool IsFullscreen( void ); void SetFullScreen( bool fullscreen ); }; 在创建窗口时,则将用户函数指针(glfwSetWindowUserPointer)设置为窗口管理类.调整大小的回调由glfwSetWindowSizeCallback设置.创建窗口后,可以通过glfwGetWindowPos和glfwGetWindowSize获取当前大小和位置. void OpenGLWindow::Init( int width,int height ) { _wnd = glfwCreateWindow( width,"OGL window",nullptr,nullptr ); if ( _wnd == nullptr ) { glfwTerminate(); throw std::runtime_error( "error initializing window" ); } glfwMakeContextCurrent( _wnd ); glfwSetWindowUserPointer( _wnd,this ); glfwSetWindowSizeCallback( _wnd,OpenGLWindow::CallbackResize ); _monitor = glfwGetPrimaryMonitor(); glfwGetWindowSize( _wnd,&_wndSize[0],&_wndSize[1] ); glfwGetWindowPos( _wnd,&_wndPos[0],&_wndPos[1] ); _updateViewport = true; } 当调整大小通知发生时,可以通过glfwGetWindowUserPointer获取指向窗口管理类的指针: static void OpenGLWindow::CallbackResize(GLFWwindow* window,int cy) { void *ptr = glfwGetWindowUserPointer( window ); if ( OpenGLWindow *wndPtr = static_cast<OpenGLWindow*>( ptr ) ) wndPtr->Resize( cx,cy ); } 通知窗口大小的任何更改并存储新的窗口大小(glfwGetWindowSize): void OpenGLWindow::Resize( int cx,int cy ) { _updateViewport = true; } 当窗口大小发生变化时,视口必须适合窗口大小( void OpenGLWindow::MainLoop ( void ) { while (!glfwWindowShouldClose(_wnd)) { if ( _updateViewport ) { glfwGetFramebufferSize( _wnd,&_vpSize[0],&_vpSize[1] ); glViewport( 0,_vpSize[0],_vpSize[1] ); _updateViewport = false; } // ..... render the scene glfwSwapBuffers(_wnd); glfwPollEvents(); } } 如果当前窗口处于全屏模式,可以通过询问窗口用于全屏模式的监视器(glfwGetWindowMonitor)来实现: bool OpenGLWindow::IsFullscreen( void ) { return glfwGetWindowMonitor( _wnd ) != nullptr; } 要打开和关闭全屏模式,必须使用全屏模式的监视器或使用nullptr调用glfwSetWindowMonitor: void SetFullScreen( bool fullscreen ) { if ( IsFullscreen() == fullscreen ) return; if ( fullscreen ) { // backup windwo position and window size glfwGetWindowPos( _wnd,&_wndPos[1] ); glfwGetWindowSize( _wnd,&_wndSize[1] ); // get reolution of monitor const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); // swithc to full screen glfwSetWindowMonitor( _wnd,_monitor,mode->width,mode->height,0 ); } else { // restore last window size and position glfwSetWindowMonitor( _wnd,_wndPos[0],_wndPos[1],_wndSize[0],_wndSize[1],0 ); } _updateViewport = true; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 正则表达式 – TortoiseGit过滤2个用户名
- 主线程中同步的 XMLHttpRequest 已不推荐使用,因其对终端用
- ruby-on-rails-3 – 将实用程序脚本放在rails中
- ruby-on-rails – 为什么一些“Plain Old Ruby Objects”会
- 你如何称之为Swift的Objective-C可变方法?
- 将XML标记按字母顺序排序
- C# – 简单验证 – DialogResult
- 如何将C#中的颜色动态更改为十六进制值?
- How completely uninstall PostgreSQL 9.X on Mac OSX
- 详解vue 计算属性与方法跟侦听器区别(面试考点)