Subversion Repositories seema-scanner

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 jakw 1
#include "OpenGLContext.h"
2
 
3
#include <GL/gl.h>
4
#include <GL/glx.h>
5
#include <X11/Xlib.h>
6
#include <stdio.h>
7
#include <string.h>
8
 
9
#include <unistd.h>
10
 
11
// vmode extension for mode settings, gamma control, etc.
12
#include <X11/extensions/xf86vmode.h>
13
 
14
// XRandR extension for virtual screens, mode setting, etc.
15
//#include <X11/extensions/Xrandr.h>
16
 
17
struct OpenGLContext::OpenGLContextInfo{
18
    Display *display;
19
    Window window;
20
    GLXContext context;
21
    OpenGLContextInfo() : display(NULL), window(0), context(NULL){}
22
};
23
 
24
std::vector<ScreenInfo> OpenGLContext::GetScreenInfo(){
25
    std::vector<ScreenInfo> ret;
26
 
27
    // Connection to default X Server
28
    Display *display = XOpenDisplay(NULL);
29
 
30
    unsigned int nScreens = ScreenCount(display);
31
 
32
    for(unsigned int i=0; i<nScreens; i++){
33
        Screen *XScreen = ScreenOfDisplay(display, i);
34
        ScreenInfo screen;
35
        screen.resX = XScreen->width;
36
        screen.resY = XScreen->height;
37
        char buff[100];
38
        sprintf(buff, "XScreen no. %d", i);
39
        screen.name = buff;
40
 
41
        ret.push_back(screen);
42
    }
43
 
44
    XCloseDisplay(display);
45
 
46
    return ret;
47
}
48
 
49
OpenGLContext::OpenGLContext(uint _screenNum) : screenNum(_screenNum){
50
 
51
    contextInfo = new OpenGLContextInfo();
52
 
53
    contextInfo->display = XOpenDisplay(NULL);
54
 
55
    if((int)screenNum+1 > ScreenCount(contextInfo->display))
56
        throw "Could not create OpenGLContext. Screen not available!";
57
 
58
    Screen *xScreen = ScreenOfDisplay(contextInfo->display, screenNum);
59
 
60
    screenResX = xScreen->width;
61
    screenResY = xScreen->height;
62
 
63
    // Create a OpenGL OpenGLContext on the specified X screen
64
    contextInfo->window = RootWindow(contextInfo->display, screenNum);
65
 
66
    int attrListDbl[] = {
67
        GLX_RGBA, GLX_DOUBLEBUFFER,
68
        GLX_RED_SIZE, 4,
69
        GLX_GREEN_SIZE, 4,
70
        GLX_BLUE_SIZE, 4,
71
        None
72
    };
73
 
74
    XVisualInfo *visualInfo = glXChooseVisual(contextInfo->display, screenNum, attrListDbl);
75
 
76
    int glxMajor, glxMinor = 0;
77
    glXQueryVersion(contextInfo->display, &glxMajor, &glxMinor);
78
    std::cout << "GLX-Version " << glxMajor << "." << glxMinor << std::endl;
79
 
80
    // Create a GLX OpenGLContext
81
    bool directRendering = True;
82
    contextInfo->context = glXCreateContext(contextInfo->display, visualInfo,  NULL, directRendering);
83
 
84
    // Create colormap
85
    Colormap colormap = XCreateColormap(contextInfo->display,contextInfo->window,visualInfo->visual,AllocNone);
86
 
87
    // Create the actual window
88
    unsigned long wamask = CWColormap;
89
 
90
    XSetWindowAttributes wa;
91
    wa.colormap = colormap;
92
    wa.border_pixel = 0;
93
    wa.event_mask = 0;
94
 
95
    // bypass window manager
96
    wa.override_redirect = False;
97
 
98
    // show no cursor
99
    wa.cursor = 0;
100
 
101
    contextInfo->window = XCreateWindow(contextInfo->display, contextInfo->window, 0, 0, screenResX, screenResY, 0, visualInfo->depth, InputOutput, visualInfo->visual, wamask, &wa);
102
 
103
    if(!contextInfo->window)
104
        std::cerr << "Failed to create X window!" << std::endl;
105
 
106
    // Raise window (necessary)
107
    XMapRaised(contextInfo->display, contextInfo->window);
108
 
109
    // Connect the glx-OpenGLContext to the window
110
    glXMakeCurrent(contextInfo->display, contextInfo->window, contextInfo->context);
111
 
112
    //XSaveOpenGLContext
113
    XFlush(contextInfo->display);
114
 
115
    // Check if OpenGLContext is direct
116
    if (glXIsDirect(contextInfo->display, contextInfo->context))
117
        std::cout << "OpenGLContext is direct\n";
118
    else
119
        std::cout << "OpenGLContext is not direct\n";
120
 
121
    // Set swap interval to 1 for standard vsync
122
    typedef GLvoid (*glXSwapIntervalSGIFunc) (GLint);
123
    const char *glx_extensions = glXQueryExtensionsString(contextInfo->display, screenNum);
124
    if (strstr(glx_extensions, "GLX_SGI_swap_control")) {
125
        PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalSGI");
126
        SwapIntervalSGI(1);
127
    } else if (strstr(glx_extensions, "GLX_EXT_swap_control")) {
128
        PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
129
        SwapIntervalEXT(contextInfo->display, contextInfo->window, 1);
130
    } else {
131
        std::cerr << "OpenGLContext.Unix Error: Could not access swap interval extension!" << std::endl;
132
    }
133
 
134
    // Adjust gamma to one
135
    setGamma(1.0);
136
}
137
 
138
void OpenGLContext::setGamma(float gamma){
139
    // Adjust gamma
140
    XF86VidModeGamma xf86Gamma = {gamma, gamma, gamma};
141
    XF86VidModeSetGamma(contextInfo->display, screenNum, &xf86Gamma);
142
}
143
 
144
void OpenGLContext::makeContextCurrent(){
145
    glXMakeCurrent(contextInfo->display, contextInfo->window, contextInfo->context);
146
}
147
 
148
void OpenGLContext::flush(){
149
 
150
    // Swap buffers
151
    glXSwapBuffers(contextInfo->display, contextInfo->window);
152
 
153
    // Synchronize CPU with vsync buffer swap
154
    //glFinish();
155
    //glXWaitGL();
156
}
157
 
158
OpenGLContext::~OpenGLContext(){
159
    std::cout<<"Releasing OpenGL Context\n"<<std::flush;
160
    if(contextInfo->context){
161
        // Release context (None, NULL)
162
        if(!glXMakeCurrent(contextInfo->display, None, NULL))
163
            std::cerr << "Error. Could not release drawing OpenGLContext." << std::endl;
164
 
165
        glXDestroyContext(contextInfo->display, contextInfo->context);
166
        XCloseDisplay(contextInfo->display);
167
        delete contextInfo;
168
    }
169
}
170