Subversion Repositories seema-scanner

Rev

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