2012-06-05 159 views
6

我打算在Linux紅帽子上使用GLFW打開一個OpenGL全屏窗口。我有一個桌面,跨越兩臺顯示器,總分辨率爲3840 * 1080。打開全屏OpenGL窗口

我有兩個問題: 1.窗口只在一個顯示器上打開,最大窗口寬度爲1920(單個顯示器的寬度)。 2.窗口的最大高度是1003(我認爲這是屏幕的高度減去任務欄和頂欄的高度)。

這是我用來打開該窗口中的代碼:

if (glfwInit() == GL_FALSE) 
    std::cout<< "Unable to initialize GLFW\n"; 
glfwOpenWindowHint(GLFW_STEREO, GL_FALSE); 
if (glfwOpenWindow(3840,1080,8,8,8,0,24,0,GLFW_FULLSCREEN) == GL_FALSE) 
    std::cout<< "Unable to open window\n"; 
int width, height; 
glfwGetWindowSize(&width, &height); 
std::cout << "width = " << width << " height = " << height << "\n"; 

輸出:寬度= 1920高度= 1003

編輯: 我用xrandr檢查可用屏幕模式,並得到:

屏幕0:最小3840 x 1080,最大3840 x 1080,最大3840 x 1080 默認連接3840x1080 + 0 + 0 0mm x 0mm 3840x1080 50.0 *

EDIT2: 我已經改變了我的代碼使用X11

int doubleBufferAttributes[] = { 
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 
GLX_RENDER_TYPE, GLX_RGBA_BIT, 
GLX_DOUBLEBUFFER, True, /* Request a double-buffered color buffer with */ 
GLX_RED_SIZE,  1,  /* the maximum number of bits per component */ 
GLX_GREEN_SIZE, 1, 
    GLX_BLUE_SIZE,  1, 
    None 
}; 

static Bool WaitForNotify(Display *dpy, XEvent *event, XPointer arg) { 
    return (event->type == MapNotify) && (event->xmap.window == (Window) arg); 
} 
int main(int argc, char *argv[]) 
{ 
    Display    *dpy; 
    Window    xWin; 
    XEvent    event; 
    XVisualInfo   *vInfo; 
    XSetWindowAttributes swa; 
    GLXFBConfig   *fbConfigs; 
    GLXContext   context; 
    GLXWindow    glxWin; 
    int     swaMask; 
    int     numReturned; 
    int     swapFlag = True; 

    /* Open a connection to the X server */ 

dpy = XOpenDisplay(NULL); 
if (dpy == NULL) { 
    printf("Unable to open a connection to the X server\n"); 
    exit(EXIT_FAILURE); 
} 

/* Request a suitable framebuffer configuration - try for a double 
** buffered configuration first */ 
fbConfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), 
           doubleBufferAttributes, &numReturned); 

/* Create an X colormap and window with a visual matching the first 
** returned framebuffer config */ 
vInfo = glXGetVisualFromFBConfig(dpy, fbConfigs[0]); 

swa.border_pixel = 0; 
swa.event_mask = StructureNotifyMask; 
swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vInfo->screen), 
           vInfo->visual, AllocNone); 

swaMask = CWBorderPixel | CWColormap | CWEventMask; 

xWin = XCreateWindow(dpy, RootWindow(dpy, vInfo->screen), 0, 0, 3840, 1080, 
         0, vInfo->depth, InputOutput, vInfo->visual, 
         swaMask, &swa); 
XWindowAttributes attt; 

XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "he = " << attt.height << " wi = " << attt.width << "\n"; 

/* Create a GLX context for OpenGL rendering */ 
context = glXCreateNewContext(dpy, fbConfigs[0], GLX_RGBA_TYPE, 
      NULL, True); 
XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "2he = " << attt.height << " wi = " << attt.width << "\n"; 


/* Create a GLX window to associate the frame buffer configuration 
** with the created X window */ 
glxWin = glXCreateWindow(dpy, fbConfigs[0], xWin, NULL); 
XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "3he = " << attt.height << " wi = " << attt.width << "\n"; 

/* Map the window to the screen, and wait for it to appear */ 
XMapWindow(dpy, xWin); 
XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "4he = " << attt.height << " wi = " << attt.width << "\n"; 

XIfEvent(dpy, &event, WaitForNotify, (XPointer) xWin); 
XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "5he = " << attt.height << " wi = " << attt.width << "\n"; 


/* Bind the GLX context to the Window */ 
glXMakeContextCurrent(dpy, glxWin, glxWin, context); 
XGetWindowAttributes(dpy,xWin, &attt); 
std::cout << "6he = " << attt.height << " wi = " << attt.width << "\n"; 

輸出是打開的窗口:

he = 1080 wi = 3840 
2he = 1080 wi = 3840 
3he = 1080 wi = 3840 
4he = 1080 wi = 3840 
5he = 1003 wi = 1920 
6he = 1003 wi = 1920 

看來,當窗口得到顯示它的尺寸縮小。

+0

您是否嘗試過列舉可用的視頻模式並檢查可用內容? –

+0

我用GLFW打開窗口,所以沒有。我使用'xrandr'查詢視頻模式: 屏幕0:最小3840 x 1080,當前3840 x 1080,最大3840 x 1080. 我目前正在更改代碼以直接使用X打開窗口。您能指出我到枚舉可用視頻模式的功能? 默認連接3840x1080 + 0 + 0 0mm x 0mm 3840x1080 50.0 * –

+0

@NicolBolas請參閱最新編輯的問題。 –

回答

15

不知道GLFW,也許它是越野車,但X11全屏窗戶不這樣工作。任何值得使用它的窗口管理器都會強制窗口適合(單一,非虛擬)屏幕。

你想要麼繞過窗口管理器完全(使用OverrideRedirect窗口屬性),或詢問您的WM合作(使用窗口屬性_NET_WM_STATE_FULLSCREEN)。第一種方法有許多缺點,所以我們使用第二種方法。下面的程序將在您的顯示器上顯示一個窗口,然後將其切換至全屏模式:

#include <X11/X.h> 
#include <X11/Xlib.h> 
#include <strings.h> 
#include <memory.h> 
#include <stdlib.h> 
#include <stdio.h> 

int main() 
{ 
    Display* dis = XOpenDisplay(NULL); 
    Window win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 0, 0, 10, 10, 
            0, BlackPixel (dis, 0), BlackPixel(dis, 0)); 

    Atom wm_state = XInternAtom(dis, "_NET_WM_STATE", False); 
    Atom fullscreen = XInternAtom(dis, "_NET_WM_STATE_FULLSCREEN", False); 

    XEvent xev; 
    memset(&xev, 0, sizeof(xev)); 
    xev.type = ClientMessage; 
    xev.xclient.window = win; 
    xev.xclient.message_type = wm_state; 
    xev.xclient.format = 32; 
    xev.xclient.data.l[0] = 1; 
    xev.xclient.data.l[1] = fullscreen; 
    xev.xclient.data.l[2] = 0; 

    XMapWindow(dis, win); 

    XSendEvent (dis, DefaultRootWindow(dis), False, 
        SubstructureRedirectMask | SubstructureNotifyMask, &xev); 

    XFlush(dis); 
    /*Sleep 5 seconds before closing.*/ 
    sleep(5); 
    return(0); 

} 

你可能使用你的真實屏幕尺寸,從一開始的窗口,以避免任何調整大小動畫效果。

我沒有在一個多頭系統上嘗試這個,因爲我沒有一個,但在單個顯示系統上它能正常工作(覆蓋面板,刪除窗口裝飾等)。請讓我知道它是否適合你。

更新他們說了多頭的工作,你需要使用_NET_WM_FULLSCREEN_MONITORS財產(見here)。它是應該被這樣設置4個整數數組:

Atom fullmons = XInternAtom(dis, "_NET_WM_FULLSCREEN_MONITORS", False); 
    XEvent xev; 
    memset(&xev, 0, sizeof(xev)); 
    xev.type = ClientMessage; 
    xev.xclient.window = win; 
    xev.xclient.message_type = fullmons; 
    xev.xclient.format = 32; 
    xev.xclient.data.l[0] = 0; /* your topmost monitor number */ 
    xev.xclient.data.l[1] = 0; /* bottommost */ 
    xev.xclient.data.l[2] = 0; /* leftmost */ 
    xev.xclient.data.l[3] = 1; /* rightmost */ 
    xev.xclient.data.l[4] = 0; /* source indication */ 

    XSendEvent (dis, DefaultRootWindow(dis), False, 
        SubstructureRedirectMask | SubstructureNotifyMask, &xev); 

有了這個,你應該能夠設置你的全屏窗口占用一臺顯示器,整個桌面,或(超過2個監視器)之間的任何事情。

我還沒有檢查過,因爲我沒有多頭系統。

+0

感謝您的詳細解答。在我看到您的答案之前,我嘗試使用OverrideRedirect(您的第一個建議方法)。最後,我打開了xorg.conf中的Xinerama模式(這個模式讓WM認爲只有一個大顯示器)。 –