Subversion Repositories seema-scanner

Rev

Rev 16 | Rev 71 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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