00001 #include <blort/GLWindow/GLWindow.h>
00002 #include <stdio.h>
00003 #include <stdexcept>
00004 #include <vector>
00005
00006 #ifdef WIN32
00007 #include <windows.h>
00008 #include <gl/glew.h>
00009 #include <gl/gl.h>
00010 #endif
00011
00012 #ifdef LINUX
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <unistd.h>
00016 #include <X11/Xlib.h>
00017 #include <X11/Xutil.h>
00018 #include <GL/gl.h>
00019 #include <GL/glx.h>
00020 #endif
00021
00022 namespace blortGLWindow{
00023
00024 struct GLWindowImpl
00025 {
00026 #ifdef WIN32
00027 WNDCLASS wc;
00028 HWND hWnd;
00029 HDC hDC;
00030 HGLRC hRC;
00031 MSG msg;
00032 #endif
00033
00034 #ifdef LINUX
00035 Display *dpy;
00036 Window root;
00037 XVisualInfo *vi;
00038 Colormap cmap;
00039 XSetWindowAttributes swa;
00040 Window glWin;
00041 Window btWin;
00042 Atom wmDelete;
00043 GLXContext glc;
00044 XWindowAttributes gwa;
00045 #endif
00046
00047 void init(unsigned int width, unsigned int height, const char* name, bool visible)
00048 {
00049 #ifdef LINUX
00050 GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
00051 dpy = XOpenDisplay(NULL);
00052
00053 if(dpy == NULL){
00054 throw std::runtime_error("[GLWindow::init] Error cannot connect to X server");
00055 }
00056
00057 root = DefaultRootWindow(dpy);
00058 vi = glXChooseVisual(dpy, 0, att);
00059
00060 if(vi == NULL)
00061 throw std::runtime_error("[GLWindow::init] Error no appropriate visual found");
00062
00063 cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
00064
00065 swa.colormap = cmap;
00066 swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
00067
00068 glWin = XCreateWindow(dpy, root, 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
00069 wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", true);
00070 XSetWMProtocols(dpy, glWin, &wmDelete, 1);
00071
00072 if ( visible )
00073 {
00074 XMapWindow(dpy, glWin);
00075 }
00076
00077 XStoreName(dpy, glWin, name);
00078
00079 glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
00080 glXMakeCurrent(dpy, glWin, glc);
00081
00082 printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
00083
00084 glXSwapBuffers(dpy, glWin);
00085 if(!visible)
00086 {
00087 XUnmapWindow(dpy, glWin);
00088 }
00089 #endif // LINUX implementation
00090 }
00091
00092 void quit()
00093 {
00094 #ifdef LINUX
00095 glXMakeCurrent(dpy, None, NULL);
00096 glXDestroyContext(dpy, glc);
00097 XDestroyWindow(dpy, glWin);
00098 XCloseDisplay(dpy);
00099 #endif // LINUX implementation
00100 }
00101
00102 void Activate()
00103 {
00104 #ifdef LINUX
00105 glXMakeCurrent(dpy, glWin, glc);
00106 #endif // LINUX implementation
00107 }
00108
00109 void Update()
00110 {
00111 #ifdef LINUX
00112 glXSwapBuffers(dpy, glWin);
00113 #endif // LINUX implementation
00114 }
00115
00116 bool GetEvent(Event &event){
00117 #ifdef LINUX
00118 if(XPending(dpy)){
00119 XEvent xev;
00120
00121
00122 if( XCheckWindowEvent(dpy, glWin, KeyPressMask, &xev) )
00123 {
00124 event.type = TMGL_Press;
00125 KeySym ks = XKeycodeToKeysym(dpy, xev.xkey.keycode, 0);
00126 MapKey(ks, event.input);
00127 }
00128
00129 else if(XCheckWindowEvent(dpy, glWin, KeyReleaseMask, &xev))
00130 {
00131 event.type = TMGL_Release;
00132 KeySym ks = XKeycodeToKeysym(dpy, xev.xkey.keycode, 0);
00133 MapKey(ks, event.input);
00134 }
00135
00136 else if(XCheckWindowEvent(dpy, glWin, ButtonPressMask, &xev))
00137 {
00138 event.type = TMGL_Press;
00139 MapMouse(xev.xbutton.button, event.input);
00140 event.motion.x = xev.xbutton.x;
00141 event.motion.y = xev.xbutton.y;
00142 }
00143
00144 else if(XCheckWindowEvent(dpy, glWin, ButtonReleaseMask, &xev))
00145 {
00146 event.type = TMGL_Release;
00147 MapMouse(xev.xbutton.button, event.input);
00148 event.motion.x = xev.xbutton.x;
00149 event.motion.y = xev.xbutton.y;
00150 }
00151
00152 else if(XCheckWindowEvent(dpy, glWin, PointerMotionMask, &xev))
00153 {
00154 event.type = TMGL_Motion;
00155 event.motion.x = xev.xmotion.x;
00156 event.motion.y = xev.xmotion.y;
00157 }
00158
00159 else if(XCheckWindowEvent(dpy, glWin, ExposureMask, &xev))
00160 {
00161 XWindowAttributes gwa;
00162 event.type = TMGL_Expose;
00163 XGetWindowAttributes(dpy, glWin, &gwa);
00164 event.expose.width = gwa.width;
00165 event.expose.height = gwa.height;
00166 }
00167
00168
00169 else
00170 {
00171 return false;
00172 }
00173
00174 return true;
00175 }
00176 #endif // LINUX implementation
00177 return false;
00178 }
00179
00180 #ifdef LINUX
00181 void MapMouse(unsigned int xbutton, Input &input)
00182 {
00183 switch(xbutton)
00184 {
00185 case Button1:
00186 input = TMGL_Button1;
00187 break;
00188 case Button2:
00189 input = TMGL_Button2;
00190 break;
00191 case Button3:
00192 input = TMGL_Button3;
00193 break;
00194 case Button4:
00195 input = TMGL_Button4;
00196 break;
00197 case Button5:
00198 input = TMGL_Button5;
00199 break;
00200 }
00201 }
00202
00203 void MapKey(KeySym ks, Input &input)
00204 {
00205 switch(ks)
00206 {
00207 case XK_0:
00208 input = TMGL_0;
00209 break;
00210 case XK_1:
00211 input = TMGL_1;
00212 break;
00213 case XK_2:
00214 input = TMGL_2;
00215 break;
00216 case XK_3:
00217 input = TMGL_3;
00218 break;
00219 case XK_4:
00220 input = TMGL_4;
00221 break;
00222 case XK_5:
00223 input = TMGL_5;
00224 break;
00225 case XK_6:
00226 input = TMGL_6;
00227 break;
00228 case XK_7:
00229 input = TMGL_7;
00230 break;
00231 case XK_8:
00232 input = TMGL_8;
00233 break;
00234 case XK_9:
00235 input = TMGL_9;
00236 break;
00237
00238 case XK_a:
00239 input = TMGL_a;
00240 break;
00241 case XK_b:
00242 input = TMGL_b;
00243 break;
00244 case XK_c:
00245 input = TMGL_c;
00246 break;
00247 case XK_d:
00248 input = TMGL_d;
00249 break;
00250 case XK_e:
00251 input = TMGL_e;
00252 break;
00253 case XK_f:
00254 input = TMGL_f;
00255 break;
00256 case XK_g:
00257 input = TMGL_g;
00258 break;
00259 case XK_h:
00260 input = TMGL_h;
00261 break;
00262 case XK_i:
00263 input = TMGL_i;
00264 break;
00265 case XK_j:
00266 input = TMGL_j;
00267 break;
00268 case XK_k:
00269 input = TMGL_k;
00270 break;
00271 case XK_l:
00272 input = TMGL_l;
00273 break;
00274 case XK_m:
00275 input = TMGL_m;
00276 break;
00277 case XK_n:
00278 input = TMGL_n;
00279 break;
00280 case XK_o:
00281 input = TMGL_o;
00282 break;
00283 case XK_p:
00284 input = TMGL_p;
00285 break;
00286 case XK_q:
00287 input = TMGL_q;
00288 break;
00289 case XK_r:
00290 input = TMGL_r;
00291 break;
00292 case XK_s:
00293 input = TMGL_s;
00294 break;
00295 case XK_t:
00296 input = TMGL_t;
00297 break;
00298 case XK_u:
00299 input = TMGL_u;
00300 break;
00301 case XK_v:
00302 input = TMGL_v;
00303 break;
00304 case XK_w:
00305 input = TMGL_w;
00306 break;
00307 case XK_x:
00308 input = TMGL_x;
00309 break;
00310 case XK_y:
00311 input = TMGL_y;
00312 break;
00313 case XK_z:
00314 input = TMGL_z;
00315 break;
00316
00317 case XK_space:
00318 input = TMGL_Space;
00319 break;
00320 case XK_BackSpace:
00321 input = TMGL_BackSpace;
00322 break;
00323 case XK_Tab:
00324 input = TMGL_Tab;
00325 break;
00326 case XK_Return:
00327 input = TMGL_Return;
00328 break;
00329 case XK_Pause:
00330 input = TMGL_Pause;
00331 break;
00332 case XK_Escape:
00333 input = TMGL_Escape;
00334 break;
00335 case XK_Delete:
00336 input = TMGL_Delete;
00337 break;
00338 case XK_Left:
00339 input = TMGL_Left;
00340 break;
00341 case XK_Up:
00342 input = TMGL_Up;
00343 break;
00344 case XK_Right:
00345 input = TMGL_Right;
00346 break;
00347 case XK_Down:
00348 input = TMGL_Down;
00349 break;
00350 case XK_Page_Up:
00351 input = TMGL_Page_Up;
00352 break;
00353 case XK_Page_Down:
00354 input = TMGL_Page_Down;
00355 break;
00356 case XK_End:
00357 input = TMGL_End;
00358 break;
00359 case XK_Begin:
00360 input = TMGL_Begin;
00361 break;
00362 case XK_KP_Enter:
00363 input = TMGL_Return;
00364 break;
00365 case XK_KP_Multiply:
00366 input = TMGL_KP_Multiply;
00367 break;
00368 case XK_KP_Add:
00369 input = TMGL_KP_Add;
00370 break;
00371 case XK_KP_Subtract:
00372 input = TMGL_KP_Subtract;
00373 break;
00374 case XK_KP_Divide:
00375 input = TMGL_KP_Divide;
00376 break;
00377 case XK_KP_0:
00378 input = TMGL_KP_0;
00379 break;
00380 case XK_KP_1:
00381 input = TMGL_KP_1;
00382 break;
00383 case XK_KP_2:
00384 input = TMGL_KP_2;
00385 break;
00386 case XK_KP_3:
00387 input = TMGL_KP_3;
00388 break;
00389 case XK_KP_4:
00390 input = TMGL_KP_4;
00391 break;
00392 case XK_KP_5:
00393 input = TMGL_KP_5;
00394 break;
00395 case XK_KP_6:
00396 input = TMGL_KP_6;
00397 break;
00398 case XK_KP_7:
00399 input = TMGL_KP_7;
00400 break;
00401 case XK_KP_8:
00402 input = TMGL_KP_8;
00403 break;
00404 case XK_KP_9:
00405 input = TMGL_KP_9;
00406 break;
00407 case XK_F1:
00408 input = TMGL_F1;
00409 break;
00410 case XK_F2:
00411 input = TMGL_F2;
00412 break;
00413 case XK_F3:
00414 input = TMGL_F3;
00415 break;
00416 case XK_F4:
00417 input = TMGL_F4;
00418 break;
00419 case XK_F5:
00420 input = TMGL_F5;
00421 break;
00422 case XK_F6:
00423 input = TMGL_F6;
00424 break;
00425 case XK_F7:
00426 input = TMGL_F7;
00427 break;
00428 case XK_F8:
00429 input = TMGL_F8;
00430 break;
00431 case XK_F9:
00432 input = TMGL_F9;
00433 break;
00434 case XK_F10:
00435 input = TMGL_F10;
00436 break;
00437 case XK_F11:
00438 input = TMGL_F11;
00439 break;
00440 case XK_F12:
00441 input = TMGL_F12;
00442 break;
00443 case XK_Shift_L:
00444 input = TMGL_Shift_L;
00445 break;
00446 case XK_Shift_R:
00447 input = TMGL_Shift_R;
00448 break;
00449 case XK_Control_L:
00450 input = TMGL_Control_L;
00451 break;
00452 case XK_Control_R:
00453 input = TMGL_Control_R;
00454 break;
00455 }
00456 }
00457 #endif // LINUX implementation for Mouse/Keyboard mapping
00458 };
00459
00460 void GLWindow::init(unsigned int width, unsigned int height, const char* name, bool visible){
00461 impl->init(width, height, name, visible);
00462 }
00463
00464 void GLWindow::quit(){
00465 impl->quit();
00466 }
00467
00468 void GLWindow::Activate(){
00469 impl->Activate();
00470 }
00471
00472 void GLWindow::Update(){
00473 impl->Update();
00474 }
00475
00476 GLWindow::GLWindow()
00477 : impl(new GLWindowImpl())
00478 {
00479 init(320,240,"OpenGL Window");
00480 }
00481
00482 GLWindow::GLWindow(unsigned int width, unsigned int height)
00483 : impl(new GLWindowImpl())
00484 {
00485 init(width, height, "OpenGL Window");
00486 }
00487
00488 GLWindow::GLWindow(unsigned int width, unsigned int height, const char* name, bool visible)
00489 : impl(new GLWindowImpl())
00490 {
00491 init(width, height, name, visible);
00492 }
00493 GLWindow::~GLWindow(){
00494 quit();
00495 delete impl;
00496 }
00497
00498 bool GLWindow::GetEvent(Event &event){
00499 return impl->GetEvent(event);
00500 }
00501
00502 }