2012-06-05 29 views
6

मैं लिनक्स लाल-टोपी पर जीएलएफडब्ल्यू का उपयोग कर ओपनजीएल पूर्ण स्क्रीन विंडो खोलने की कोशिश कर रहा हूं। मेरे पास एक डेस्कटॉप है जो 3840 * 1080 के कुल रिज़ॉल्यूशन के साथ दो मॉनीटर फैलाता है।एक पूर्णस्क्रीन ओपनजीएल विंडो खोलना

मुझे दो समस्याएं हैं: 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 0 मिमी x 0 मिमी 3840x1080 50.0 *

,210

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

मैं विंडो खोलने के लिए जीएलएफडब्ल्यू का उपयोग करता हूं, इसलिए नहीं। मैंने वीडियो मोड से पूछने के लिए 'xrandr' का उपयोग किया: स्क्रीन 0: न्यूनतम 3840 x 1080, वर्तमान 3840 x 1080, अधिकतम 3840 x 1080. मैं वर्तमान में एक्स का उपयोग कर विंडो खोलने के लिए कोड बदल रहा हूं। क्या आप मुझे इंगित कर सकते हैं एक ऐसे फ़ंक्शन के लिए जो उपलब्ध वीडियो मोड का आकलन करता है? डिफ़ॉल्ट कनेक्ट 3840x1080 + 0 + 0 0 मिमी x 0 मिमी 3840x1080 50.0 * –

+0

@ निकोलबोलस कृपया प्रश्न का नवीनतम संपादन देखें। –

उत्तर

15

जीएलएफडब्ल्यू के बारे में पता नहीं, शायद यह छोटी है, लेकिन एक्स 11 फुलस्क्रीन विंडोज़ इस तरह काम नहीं करती हैं। इसके नमक के किसी भी खिड़की प्रबंधक खिड़की को (सिंगल, गैर वर्चुअल) स्क्रीन फिट करने के लिए मजबूर करेगा।

आप या तो विंडो प्रबंधक को पूरी तरह से बाईपास करना चाहते हैं (OverrideRedirect विंडो विशेषता का उपयोग करें), या अपने डब्ल्यूएम को सहयोग करने के लिए कहें (विंडो प्रॉपर्टी _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

विस्तृत उत्तर के लिए धन्यवाद। मैंने आपके जवाब को देखने से पहले मैंने ओवरराइड रीडरेक्ट (आपका पहला सुझाया गया दृष्टिकोण) का उपयोग करने का प्रयास किया। अंत में मैंने xorg.conf में Xinerama मोड चालू कर दिया (एक ऐसा तरीका जो डब्लूएम को यह सोचने में लगाता है कि केवल एक बड़ा मॉनिटर है)। –