2012-06-05 38 views
6

Linux Red Hat üzerinde GLFW kullanarak bir OpenGL tam ekran penceresi açmaya çalışıyorum. 3840 * 1080 çözünürlüğe sahip iki monitörü kapsayan bir masaüstüm var.Tam ekran OpenGL penceresi açma

İki sorunum var: 1. Pencere, maksimum pencere genişliği 1920 (tek bir monitörün genişliği) ile yalnızca bir monitörde açılır. 2. Pencerenin maksimum yüksekliği 1003'dür (ekranın yüksekliğinden, görev çubuğunun ve üst çubuğun yüksekliğinin eksi olduğunu düşünüyorum).

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"; 

çıkışı:: genişlik = 1920 height = 1003

DÜZENLEME: Ben kullanılabilir ekran modunu kontrol etmek xrandr kullanılan ve var:

Bu

pencereyi açmak için kullandığınız koddur

Ekran 0: x 1080 3840 akım, x 1080 3840 minimum, maksimum 3840 x 1080 varsayılan bağlı 3840x1080 + 0 + 0 0mm x 0mm 3840x1080 50.0 *

.210

EDIT2: Ben X11

çıkışı
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"; 

kullanarak pencereyi açmak için kodumu değişti:

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

o pencere olduğunda onun büyüklüğü küçülür görüntülenen olsun gibi görünüyor.

+0

Kullanılabilir video modlarını numaralandırmayı ve kullanılabilir olanı kontrol etmeyi denediniz mi? –

+0

Pencereyi açmak için GLFW kullanıyorum, yani hayır. Video modunu sorgulamak için 'xrandr' kullandım: Ekran 0: en az 3840 x 1080, geçerli 3840 x 1080, maksimum 3840 x 1080. Şu anda X'i kullanarak pencereyi doğrudan açmak için kodu değiştiriyorum. Mevcut video modlarını numaralayan bir işlev için? varsayılan bağlanır 3840x1080 + 0 + 0 0 mm x 0 mm 3840x1080 50.0 * –

+0

@NicolBolas Lütfen sorunun en son düzenlemesine bakın. –

cevap

15

GLFW hakkında bilmiyorum, belki de buggy, ama X11 tam ekran Windows bu şekilde çalışmıyor. Tuzuna değecek herhangi bir pencere yöneticisi, pencereyi (tek, sanal olmayan) ekrana sığmaya zorlar.

Pencere yöneticisini tamamen atlamak (OverrideRedirect pencere özniteliğini kullanın) veya WM'nizin işbirliği yapmasını istemek (pencere özelliğini _NET_WM_STATE_FULLSCREEN kullanın). İlk yaklaşımın çeşitli dezavantajları var, o yüzden ikincisini kullanalım. Aşağıdaki programı buna geçiş tam ekran moduna ardından ekranda bir pencere görüntüler ve olacak:

#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); 

} 

Muhtemelen herhangi boyutlandırmak önlemek amacıyla, baştan pencere için gerçek ekran boyutlarını kullanmak animasyon efekti.

Bunu bir çok açılı sistemde denemedim çünkü bir tane yok, ancak tek bir görüntü sistemi üzerinde düzgün çalışıyor (paneli kaplıyor, pencere süslerini kaldırıyor vb.). Eğer sizin için çalışıyorsa lütfen bana bildirin.

Güncelleme Onlar çok kafalı çalışması için, sen _NET_WM_FULLSCREEN_MONITORS özelliği (here bakınız) kullanmak gerekir derler. Bu 4 Böyle ayarlanmalıdır tamsayılar dizisi var: Bununla

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); 

, tek bir monitör, tüm masaüstü, ya da (2'den fazla ekranlar için) işgal etmek için tam ekran pencerelerini ayarlamak mümkün olmalıdır aradaki her şey.

Bunu kontrol etmedim çünkü çok açılı sistemim yok.

+0

Detaylı cevap için teşekkürler. Cevabınızı görmeden önce OverrideRedirect'i (ilk önerilen yaklaşımınızı) kullanmayı denedim. Sonunda xorg.conf'da Xinerama modunu açtım (WM'yi sadece tek bir büyük monitör olduğunu düşünürken uyaran bir mod). –