GLCtrl: GTK variant refactored

git-svn-id: svn://ultimatepp.org/upp/trunk@12575 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-11-25 19:01:43 +00:00
parent 0cb218755a
commit e6fd79d0c3
8 changed files with 159 additions and 24 deletions

View file

@ -1,3 +1,5 @@
#include "CtrlLib.h"
#ifdef PLATFORM_X11

View file

@ -12,10 +12,13 @@ extern void (*restore_gl_viewport__)(); // in Draw/DrawUtil.cpp
void GLCtrl::DoGLPaint()
{
glClearDepth(1);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glEnable(GL_MULTISAMPLE);
{
MemoryIgnoreLeaksBlock __; // probably a driver error, but what one can do...
glClearDepth(1);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glEnable(GL_MULTISAMPLE);
}
Size sz = GetSize();
current_viewport = sz;
SetCurrentViewport();

View file

@ -40,28 +40,12 @@ class GLCtrl : public Ctrl {
typedef GLCtrl CLASSNAME;
public:
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags);
Image MouseEvent(int event, Point p, int zdelta, dword keyflags) override;
#ifdef GUI_GTK
virtual void Paint(Draw& w);
void Paint(Draw& w) override;
#endif
private:
class GLPicking
{
private:
static int const _bufferSize = 512;
bool _isPicking;
Point _pickPoint;
Vector<int> ParseHits(GLuint *buffer, int hits);
public:
void InitPickMatrix();
Vector<int> Pick(int x, int y, Callback resizeCallback, Callback paintCallback);
GLPicking() : _isPicking(false) {}
};
#ifdef GUI_X11
class GLPane : public DHCtrl {
friend class GLCtrl;
@ -78,7 +62,6 @@ private:
GLPane() { NoWantFocus(); }
};
#elif defined(PLATFORM_WIN32)
struct GLPane : DHCtrl {
friend class GLCtrl;
@ -100,7 +83,17 @@ private:
};
#endif
#ifndef GUI_GTK
#ifdef GUI_GTK
unsigned long win = 0;
bool visible;
Rect position;
void Create();
void Sync();
void Destroy();
void State(int reason) override;
#else
GLPane pane;
#endif

View file

@ -12,6 +12,7 @@ file
GLCtrl.h,
Win32GLCtrl.cpp,
X11GLCtrl.cpp,
GtkGLCtrl2.cpp,
GtkGLCtrl.cpp,
GLCtrl.cpp;

View file

@ -1,5 +1,7 @@
#include "GLCtrl.h"
#if 0
#ifdef GUI_GTK
#include <gtk/gtkgl.h>
@ -76,3 +78,5 @@ void GLCtrl::Paint(Draw& w)
}
#endif
#endif

View file

@ -0,0 +1,126 @@
#include "GLCtrl.h"
#ifdef GUI_GTK
#include <GL/glx.h>
#include <GL/gl.h>
#include <gdk/gdkx.h>
namespace Upp {
static XVisualInfo *s_XVisualInfo;
static Colormap s_Colormap;
static GLXContext s_GLXContext;
static ::Display *s_Display;
void GLCtrl::Create()
{
Ctrl *top = GetTopCtrl();
if(!top)
return;
GdkWindow *gdk = top->gdk();
if(!gdk)
return;
Window w = gdk_x11_drawable_get_xid((GdkDrawable *)gdk);
ONCELOCK {
s_Display = gdk_x11_drawable_get_xdisplay((GdkDrawable *)gdk);
int samples = numberOfSamples;
GLXFBConfig *fbc;
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;
int fbcount;
fbc = glXChooseFBConfig(s_Display, DefaultScreen(s_Display), attr, &fbcount);
}
while(!fbc && samples > 0);
if(!fbc)
return;
s_XVisualInfo = glXGetVisualFromFBConfig(s_Display, fbc[0]);
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()
{
if(win) {
bool b = IsVisible();
if(b != visible) {
visible = b;
if(b)
XMapWindow(s_Display, win);
else
XUnmapWindow(s_Display, win);
}
Rect r = GetScreenView() - GetTopCtrl()->GetScreenRect().TopLeft();
if(r != position) {
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::Paint(Draw& w)
{
if(!s_GLXContext)
return;
glXMakeCurrent(s_Display, win, s_GLXContext);
ONCELOCK {
glewInit();
}
DoGLPaint();
if(doubleBuffering)
glXSwapBuffers(s_Display, win);
else
glFlush();
glXMakeCurrent(s_Display, win, NULL);
}
}
#endif

View file

@ -50,6 +50,10 @@ void GLCtrl::GLPane::Paint(Draw &draw)
return;
glXMakeCurrent( (XDisplay*)Xdisplay, GetWindow(), s_GLXContext);
ONCELOCK {
glewInit();
}
ctrl->DoGLPaint();

View file

@ -36,6 +36,8 @@ static GLuint LoadShader(const char *src, GLenum type) {
void GLProgram::Create(const char *vertex_shader_, const char *fragment_shader_,
Tuple2<int, const char *> *bind_attr, int bind_count)
{
MemoryIgnoreLeaksBlock __;
Clear();
program = glCreateProgram();