mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
158 lines
3.1 KiB
C++
158 lines
3.1 KiB
C++
#include "GLCtrl.h"
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
|
|
#include <GL/glx.h>
|
|
#include <GL/gl.h>
|
|
|
|
#define Time XTime
|
|
#define Font XFont
|
|
#define Display XDisplay
|
|
#define Picture XPicture
|
|
#define Status int
|
|
|
|
#ifdef GUI_GTK
|
|
#include <gdk/gdkx.h>
|
|
#endif
|
|
|
|
#undef Time
|
|
#undef Font
|
|
#undef Display
|
|
#undef Picture
|
|
#undef Status
|
|
|
|
namespace Upp {
|
|
|
|
static XVisualInfo *s_XVisualInfo;
|
|
static Colormap s_Colormap;
|
|
static GLXContext s_GLXContext;
|
|
static ::XDisplay *s_Display;
|
|
|
|
void GLCtrl::Create()
|
|
{
|
|
MemoryIgnoreLeaksBlock __;
|
|
|
|
Ctrl *top = GetTopCtrl();
|
|
if(!top)
|
|
return;
|
|
|
|
#ifdef GUI_GTK
|
|
GdkWindow *gdk = top->gdk();
|
|
if(!gdk)
|
|
return;
|
|
|
|
Window w = gdk_x11_window_get_xid(gdk);
|
|
#else
|
|
Window w = top->GetWindow();
|
|
#endif
|
|
|
|
ONCELOCK {
|
|
#ifdef GUI_GTK
|
|
s_Display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
#else
|
|
s_Display = Xdisplay;
|
|
#endif
|
|
int samples = numberOfSamples;
|
|
|
|
do {
|
|
Vector<int> attr;
|
|
attr << GLX_RGBA << GLX_DEPTH_SIZE << depthSize
|
|
<< GLX_STENCIL_SIZE << stencilSize;
|
|
if(doubleBuffering)
|
|
attr << GLX_DOUBLEBUFFER;
|
|
if(samples > 1)
|
|
attr << GLX_SAMPLE_BUFFERS_ARB << 1 << GLX_SAMPLES_ARB << samples;
|
|
attr << 0;
|
|
samples >>= 1;
|
|
s_XVisualInfo = glXChooseVisual(s_Display, DefaultScreen(s_Display), attr);
|
|
}
|
|
while(!s_XVisualInfo && samples > 0);
|
|
if(!s_XVisualInfo)
|
|
return;
|
|
s_Colormap = XCreateColormap(s_Display, RootWindow(s_Display, s_XVisualInfo->screen), s_XVisualInfo->visual, AllocNone);
|
|
s_GLXContext = glXCreateContext(s_Display, s_XVisualInfo, NULL, GL_TRUE);
|
|
}
|
|
|
|
if(!s_GLXContext)
|
|
return;
|
|
|
|
XSetWindowAttributes swa;
|
|
swa.colormap = s_Colormap;
|
|
swa.border_pixel = 0;
|
|
swa.event_mask = 0;
|
|
|
|
win = XCreateWindow(s_Display, w, 0, 0, 1, 1, 0,
|
|
s_XVisualInfo->depth, InputOutput, s_XVisualInfo->visual,
|
|
CWBorderPixel|CWColormap|CWEventMask, &swa);
|
|
visible = false;
|
|
position = Null;
|
|
}
|
|
|
|
void GLCtrl::Sync()
|
|
{
|
|
MemoryIgnoreLeaksBlock __;
|
|
|
|
if(win) {
|
|
Rect r = GetScreenView() - GetTopCtrl()->GetScreenRect().TopLeft();
|
|
bool b = IsVisible() && r.GetWidth() > 0 && r.GetHeight() > 0;
|
|
if(b != visible) {
|
|
visible = b;
|
|
position = Null;
|
|
if(b)
|
|
XMapWindow(s_Display, win);
|
|
else
|
|
XUnmapWindow(s_Display, win);
|
|
}
|
|
if(r != position && visible) {
|
|
position = r;
|
|
XMoveResizeWindow(s_Display, win, r.left, r.top, r.Width(), r.Height());
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLCtrl::State(int reason)
|
|
{
|
|
switch(reason) {
|
|
case CLOSE:
|
|
XDestroyWindow(s_Display, win);
|
|
break;
|
|
case OPEN:
|
|
Create();
|
|
default:
|
|
Sync();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GLCtrl::ExecuteGL(Event<> paint, bool swap_buffers)
|
|
{
|
|
MemoryIgnoreLeaksBlock __;
|
|
|
|
glXMakeCurrent(s_Display, win, s_GLXContext);
|
|
|
|
ONCELOCK {
|
|
glewInit();
|
|
}
|
|
|
|
paint();
|
|
|
|
if(swap_buffers)
|
|
glXSwapBuffers(s_Display, win);
|
|
else
|
|
glFlush();
|
|
|
|
glXMakeCurrent(s_Display, None, NULL);
|
|
}
|
|
|
|
void GLCtrl::Paint(Draw& w)
|
|
{
|
|
Size sz = GetSize();
|
|
if(!s_GLXContext || sz.cx == 0 || sz.cy == 0)
|
|
return;
|
|
|
|
ExecuteGL([&] { DoGLPaint(); }, doubleBuffering);
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|