add another btgui test
This commit is contained in:
415
btgui/OpenGLWindow/X11OpenGLWindow.cpp
Normal file
415
btgui/OpenGLWindow/X11OpenGLWindow.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
#include "X11OpenGLWindow.h"
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<X11/X.h>
|
||||
#include<X11/Xlib.h>
|
||||
#include<GL/gl.h>
|
||||
#include<GL/glx.h>
|
||||
#include<GL/glu.h>
|
||||
|
||||
|
||||
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
|
||||
|
||||
|
||||
struct InternalData2
|
||||
{
|
||||
Display* m_dpy;
|
||||
Window m_root;
|
||||
XVisualInfo* m_vi;
|
||||
Colormap m_cmap;
|
||||
XSetWindowAttributes m_swa;
|
||||
Window m_win;
|
||||
GLXContext m_glc;
|
||||
XWindowAttributes m_gwa;
|
||||
XEvent m_xev;
|
||||
|
||||
btWheelCallback m_wheelCallback;
|
||||
btMouseMoveCallback m_mouseMoveCallback;
|
||||
btMouseButtonCallback m_mouseButtonCallback;
|
||||
btResizeCallback m_resizeCallback;
|
||||
btKeyboardCallback m_keyboardCallback;
|
||||
|
||||
InternalData2()
|
||||
:m_dpy(0),
|
||||
m_vi(0),
|
||||
m_wheelCallback(0),
|
||||
m_mouseMoveCallback(0),
|
||||
m_mouseButtonCallback(0),
|
||||
m_resizeCallback(0),
|
||||
m_keyboardCallback(0)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
X11OpenGLWindow::X11OpenGLWindow()
|
||||
:m_OpenGLInitialized(false)
|
||||
{
|
||||
m_data = new InternalData2;
|
||||
}
|
||||
|
||||
X11OpenGLWindow::~X11OpenGLWindow()
|
||||
{
|
||||
if (m_OpenGLInitialized)
|
||||
{
|
||||
disableOpenGL();
|
||||
}
|
||||
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void X11OpenGLWindow::enableOpenGL()
|
||||
{
|
||||
|
||||
m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE);
|
||||
glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc);
|
||||
|
||||
const GLubyte* ven = glGetString(GL_VENDOR);
|
||||
printf("GL_VENDOR=%s\n", ven);
|
||||
const GLubyte* ren = glGetString(GL_RENDERER);
|
||||
printf("GL_RENDERER=%s\n",ren);
|
||||
const GLubyte* ver = glGetString(GL_VERSION);
|
||||
printf("GL_VERSION=%s\n", ver);
|
||||
const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);
|
||||
// const GLubyte* ext = glGetString(GL_EXTENSIONS);
|
||||
// printf("GL_EXTENSIONS=%s\n", ext);
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::disableOpenGL()
|
||||
{
|
||||
glXMakeCurrent(m_data->m_dpy, None, NULL);
|
||||
glXDestroyContext(m_data->m_dpy, m_data->m_glc);
|
||||
}
|
||||
|
||||
|
||||
void X11OpenGLWindow::createWindow(const btgWindowConstructionInfo& ci)
|
||||
{
|
||||
m_data->m_dpy = XOpenDisplay(NULL);
|
||||
|
||||
if(m_data->m_dpy == NULL) {
|
||||
printf("\n\tcannot connect to X server\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
m_data->m_root = DefaultRootWindow(m_data->m_dpy);
|
||||
|
||||
m_data->m_vi = glXChooseVisual(m_data->m_dpy, 0, att);
|
||||
|
||||
if(m_data->m_vi == NULL) {
|
||||
printf("\n\tno appropriate visual found\n\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
printf("\n\tvisual %p selected\n", (void *)m_data->m_vi->visualid); /* %p creates hexadecimal output like in glxinfo */
|
||||
}
|
||||
|
||||
|
||||
m_data->m_cmap = XCreateColormap(m_data->m_dpy, m_data->m_root, m_data->m_vi->visual, AllocNone);
|
||||
|
||||
m_data->m_swa.colormap = m_data->m_cmap;
|
||||
m_data->m_swa.event_mask = ExposureMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
|
||||
|
||||
m_data->m_win = XCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);
|
||||
|
||||
XMapWindow(m_data->m_dpy, m_data->m_win);
|
||||
XStoreName(m_data->m_dpy, m_data->m_win, "VERY SIMPLE APPLICATION");
|
||||
|
||||
enableOpenGL();
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::closeWindow()
|
||||
{
|
||||
disableOpenGL();
|
||||
|
||||
XDestroyWindow(m_data->m_dpy, m_data->m_win);
|
||||
XCloseDisplay(m_data->m_dpy);
|
||||
}
|
||||
|
||||
int X11OpenGLWindow::getAsciiCodeFromVirtualKeycode(int keycode)
|
||||
{
|
||||
KeySym key, key_lc, key_uc;
|
||||
|
||||
key = XKeycodeToKeysym( m_data->m_dpy, keycode, 0 );
|
||||
switch( key )
|
||||
{
|
||||
case XK_Escape: return BTG_ESCAPE;
|
||||
|
||||
case XK_F1: return BTG_F1;
|
||||
case XK_F2: return BTG_F2;
|
||||
case XK_F3: return BTG_F3;
|
||||
case XK_F4: return BTG_F4;
|
||||
case XK_F5: return BTG_F5;
|
||||
case XK_F6: return BTG_F6;
|
||||
case XK_F7: return BTG_F7;
|
||||
case XK_F8: return BTG_F8;
|
||||
case XK_F9: return BTG_F9;
|
||||
case XK_F10: return BTG_F10;
|
||||
case XK_F11: return BTG_F11;
|
||||
case XK_F12: return BTG_F12;
|
||||
case XK_F13: return BTG_F13;
|
||||
case XK_F14: return BTG_F14;
|
||||
case XK_F15: return BTG_F15;
|
||||
default:
|
||||
// Make uppercase
|
||||
XConvertCase( key, &key_lc, &key_uc );
|
||||
key = key_uc;
|
||||
// Valid ISO 8859-1 character?
|
||||
if( (key >= 32 && key <= 126) ||(key >= 160 && key <= 255) )
|
||||
{
|
||||
return (int) key;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::pumpMessage()
|
||||
{
|
||||
|
||||
int buttonState = 1;
|
||||
|
||||
// Process all pending events
|
||||
while( XPending( m_data->m_dpy ) )
|
||||
{
|
||||
XNextEvent(m_data->m_dpy, &m_data->m_xev);
|
||||
// printf("#");
|
||||
// fflush(stdout);
|
||||
switch( m_data->m_xev.type )
|
||||
{
|
||||
case KeyPress:
|
||||
{
|
||||
if (m_data->m_keyboardCallback)
|
||||
{
|
||||
int keycode = getAsciiCodeFromVirtualKeycode(m_data->m_xev.xkey.keycode);
|
||||
int state = 1;
|
||||
(*m_data->m_keyboardCallback)(keycode,state);
|
||||
// printf("keycode %d",keycode);
|
||||
// fflush(stdout);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyRelease:
|
||||
{
|
||||
// printf(",");
|
||||
// fflush(stdout);
|
||||
|
||||
if (m_data->m_keyboardCallback)
|
||||
{
|
||||
|
||||
unsigned short is_retriggered = 0;
|
||||
///filter out keyboard repeat
|
||||
//see http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
|
||||
if (XEventsQueued(m_data->m_dpy, QueuedAfterReading))
|
||||
{
|
||||
XEvent nev;
|
||||
XPeekEvent(m_data->m_dpy, &nev);
|
||||
|
||||
if (nev.type == KeyPress && nev.xkey.time == m_data->m_xev.xkey.time &&
|
||||
nev.xkey.keycode == m_data->m_xev.xkey.keycode)
|
||||
{
|
||||
fprintf (stdout, "key #%ld was retriggered.\n",
|
||||
(long) XLookupKeysym (&nev.xkey, 0));
|
||||
|
||||
// delete retriggered KeyPress event
|
||||
XNextEvent (m_data->m_dpy, & m_data->m_xev);
|
||||
is_retriggered = 1;
|
||||
}
|
||||
}
|
||||
int keycode = getAsciiCodeFromVirtualKeycode( m_data->m_xev.xkey.keycode);
|
||||
int state = 0;
|
||||
(*m_data->m_keyboardCallback)(keycode,state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ButtonRelease:
|
||||
buttonState = 0;
|
||||
//continue with ButtonPress code
|
||||
case ButtonPress:
|
||||
{
|
||||
// printf("!");
|
||||
// fflush(stdout);
|
||||
|
||||
int button=-1;
|
||||
|
||||
switch (m_data->m_xev.xbutton.button)
|
||||
{
|
||||
case Button1:
|
||||
{
|
||||
button=0;
|
||||
break;
|
||||
}
|
||||
case Button2:
|
||||
{
|
||||
button=1;
|
||||
break;
|
||||
}
|
||||
case Button3:
|
||||
{
|
||||
button=2;
|
||||
break;
|
||||
}
|
||||
case Button4:
|
||||
{
|
||||
if (m_data->m_wheelCallback)
|
||||
{
|
||||
(*m_data->m_wheelCallback)(0,10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Button5:
|
||||
{
|
||||
if (m_data->m_wheelCallback)
|
||||
{
|
||||
(*m_data->m_wheelCallback)(0,-10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
int xpos = m_data->m_xev.xmotion.x;
|
||||
int ypos = m_data->m_xev.xmotion.y;
|
||||
|
||||
if (button>=0 && m_data->m_mouseButtonCallback)
|
||||
{
|
||||
// printf("xpos = %d, ypos = %d\n",xpos,ypos);
|
||||
|
||||
(*m_data->m_mouseButtonCallback)(button,buttonState,xpos,ypos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MotionNotify:
|
||||
{
|
||||
// printf("!");
|
||||
// fflush(0);
|
||||
if (m_data->m_mouseMoveCallback)
|
||||
{
|
||||
int xpos = m_data->m_xev.xmotion.x;
|
||||
int ypos = m_data->m_xev.xmotion.y;
|
||||
(*m_data->m_mouseMoveCallback)(xpos,ypos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConfigureNotify:
|
||||
{
|
||||
// printf("@");
|
||||
// fflush(0);
|
||||
if (m_data->m_resizeCallback)
|
||||
{
|
||||
(*m_data->m_resizeCallback)(m_data->m_xev.xconfigure.width,m_data->m_xev.xconfigure.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ClientMessage:
|
||||
{
|
||||
// printf("?");
|
||||
// fflush(stdout);
|
||||
break;
|
||||
}
|
||||
case Expose:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DestroyNotify:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//XRRUpdateConfiguration( &event );
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void X11OpenGLWindow::startRendering()
|
||||
{
|
||||
pumpMessage();
|
||||
|
||||
XGetWindowAttributes(m_data->m_dpy, m_data->m_win, &m_data->m_gwa);
|
||||
glViewport(0, 0, m_data->m_gwa.width, m_data->m_gwa.height);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
|
||||
|
||||
//glCullFace(GL_BACK);
|
||||
//glFrontFace(GL_CCW);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::renderAllObjects()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::endRendering()
|
||||
{
|
||||
glXSwapBuffers(m_data->m_dpy, m_data->m_win);
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::runMainLoop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float X11OpenGLWindow::getTimeInSeconds()
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
bool X11OpenGLWindow::requestedExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setRequestExit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setRenderCallback( btRenderCallback renderCallback)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setWindowTitle(const char* title)
|
||||
{
|
||||
XStoreName(m_data->m_dpy, m_data->m_win, title);
|
||||
}
|
||||
|
||||
|
||||
void X11OpenGLWindow::setWheelCallback(btWheelCallback wheelCallback)
|
||||
{
|
||||
m_data->m_wheelCallback = wheelCallback;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setMouseMoveCallback(btMouseMoveCallback mouseCallback)
|
||||
{
|
||||
m_data->m_mouseMoveCallback = mouseCallback;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setMouseButtonCallback(btMouseButtonCallback mouseCallback)
|
||||
{
|
||||
m_data->m_mouseButtonCallback = mouseCallback;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setResizeCallback(btResizeCallback resizeCallback)
|
||||
{
|
||||
m_data->m_resizeCallback = resizeCallback;
|
||||
}
|
||||
|
||||
void X11OpenGLWindow::setKeyboardCallback( btKeyboardCallback keyboardCallback)
|
||||
{
|
||||
m_data->m_keyboardCallback = keyboardCallback;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user