Fixed GLCtrl

git-svn-id: svn://ultimatepp.org/upp/trunk@548 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-10-19 16:09:39 +00:00
parent 54004f9d7a
commit dbeea0862e
8 changed files with 772 additions and 655 deletions

View file

@ -1,409 +1,409 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_X11
/////////////////////////////////////////////////////////////////////////////////////////
// Constructor
DHCtrl::DHCtrl()
{
// Sets control NOT initialized
isInitialized = false;
// Sets control NOT mapped
isMapped = false;
// Resets error contition
isError = false;
// Sets the user visual to null
UserVisualInfo = 0;
// No background painting
backpaint = NOBACKPAINT;
// transparent = true;
} // END Constructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Destructor
DHCtrl::~DHCtrl()
{
// Destroys the associated window and clean up stuffs
Terminate();
} // END Destructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Maps/unmaps the window
void DHCtrl::MapWindow(bool map)
{
// no action if not initialized
if(!isInitialized)
return;
if(map && !isMapped)
XMapWindow(Xdisplay, top->window);
else if(!map && isMapped)
XUnmapWindow(Xdisplay, top->window);
isMapped = map;
} // END DHCtrl::MapWndow()
/////////////////////////////////////////////////////////////////////////////////////////
// Initializes the view
bool DHCtrl::Init()
{
static bool isInitializing = false;
// Just for security sakes...
if(isInitialized)
return true;
// Prevents reentrant call....
if(isInitializing)
return false;
isInitializing = true;
// Call BeforeInit user func...
BeforeInit();
// if display is null, error
if(!Xdisplay)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Bad display");
isError = true;
isInitializing = false;
return false;
}
// Calls the user visual function
UserVisualInfo = CreateVisual();
// If error, returns
if(isError)
{
isInitializing = false;
return false;
}
// Gets the default visual, if none is given
Visual *visual;
int Depth;
if(UserVisualInfo)
{
visual = UserVisualInfo->visual;
Depth = UserVisualInfo->depth;
}
else
{
visual = DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
Depth = DefaultDepth(Xdisplay, DefaultScreen(Xdisplay));
}
// Initializes attribute setting flags
unsigned long ValueMask =
CWBorderPixel
| CWColormap
| CWSaveUnder
// | CWBackPixel
// | CWBorderPixel
| CWColormap
// | CWEventMask
// | CWWinGravity
// | CWBitGravity
; // END ValueMask
// Initializes attribute structure
XSetWindowAttributes winAttributes;
// creates a ColorMap, in case we're not using default visual
winAttributes.colormap = XCreateColormap(Xdisplay, GetTopWindow()->GetWindow(), visual, AllocNone);
winAttributes.border_pixel = 0;
winAttributes.save_under = XFalse;
// winAttributes.win_gravity = StaticGravity;
// winAttributes.bit_gravity = ForgetGravity;
// Calls the attributes user setting routine
SetAttributes(ValueMask, winAttributes);
// Creates the X11 window
Rect r = GetRectInParentWindow();
Window WindowHandle = XCreateWindow
(
Xdisplay, // display
// GetTopWindow()->GetWindow(), // parent
GetParentWindow(),
r.left, r.top, r.Width(), r.Height(), // x, y, width, height
0, // border width
Depth, // depth
InputOutput, // class
visual, // visual
ValueMask, // value mask
&winAttributes // attributes
);
// Frees VisualInfo
if (UserVisualInfo)
{
XFree( (char *)UserVisualInfo);
UserVisualInfo = 0;
}
// If problem creating window, error
if(!WindowHandle)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Can't create window");
isError = true;
isInitializing = false;
return false;
}
// Adds window to UPP managed windows
XWindow *cw = AddXWindow(WindowHandle);
cw->xic = xim ? XCreateIC
(
xim,
XNInputStyle,
XIMPreeditNothing | XIMStatusNothing,
XNClientWindow,
WindowHandle,
XNFocusWindow,
WindowHandle,
NULL
)
: NULL;
top = new Top;
top->window = WindowHandle;
long im_event_mask = 0;
if(cw->xic)
XGetICValues(cw->xic, XNFilterEvents, &im_event_mask, NULL);
XSelectInput
(
Xdisplay,
WindowHandle,
ExposureMask
// | StructureNotifyMask // *very* important, flag MUST NOT be set
| KeyPressMask
| FocusChangeMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PropertyChangeMask
| VisibilityChangeMask
| im_event_mask
);
int version = 5;
XChangeProperty
(
Xdisplay,
WindowHandle,
XAtom("XdndAware"),
XA_ATOM,
32,
0,
(byte *)&version,
1
);
// Maps the window if needed
if(IsShown())
MapWindow(true);
// Flushes the display
XFlush(Xdisplay);
// Stores the initial control size
CurrentSize = GetSize();
// Exits from initializing lock
isInitializing = false;
// mark control as initialized
isInitialized = true;
// Resets the message
isError = false;
SetErrorMessage("");
// Call AfterInit user func...
AfterInit(false);
return true;
} // END DHCtrl::Init()
/////////////////////////////////////////////////////////////////////////////////////////
// Terminates the view
void DHCtrl::Terminate(void)
{
if(!isInitialized)
return;
// Unmaps the window
MapWindow(false);
// gathers data from XWindow (needs Input Context...)
XWindow *cw = XWindowFromWindow(top->window);
// Frees input context as needed
if(cw->xic)
{
XDestroyIC(cw->xic);
cw->xic = NULL;
}
// Removes XWindow from Upp list
RemoveXWindow(top->window);
// Destroys the window
// Not to do, it's done destroying the parent window by X11 system
// XDestroyWindow(Xdisplay, top->window);
// Destroys created Top struct
delete top;
top = NULL;
// Resets initialization and error flags
isInitialized = false;
isError = false;
} // END DHCtrl::Terminate()
/////////////////////////////////////////////////////////////////////////////////////////
// State handler
void DHCtrl::State(int reason)
{
// Window dummy;
// int x, y;
// unsigned int width, height, border, depth;
Rect r;
// No handling if in error state
if( isError)
return;
// Initializes the control if needed (and possible...)
if(!isInitialized && GetTopWindow() && GetTopWindow()->GetWindow())
Init();
if(isInitialized)
{
switch( reason )
{
case FOCUS : // = 10,
break;
case ACTIVATE : // = 11,
break;
case DEACTIVATE : // = 12,
break;
case SHOW : // = 13,
MapWindow(IsShown());
break;
case ENABLE : // = 14,
break;
case EDITABLE : // = 15,
break;
case OPEN : // = 16,
MapWindow(IsShown());
break;
case CLOSE : // = 17,
Terminate();
break;
case POSITION : // = 100,
case LAYOUTPOS : // = 101,
SyncNativeWindows();
break;
default:
break;
} // switch(reason)
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Property Visual
Visual *DHCtrl::GetVisual(void)
{
if(UserVisualInfo)
return UserVisualInfo->visual;
else
return DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
} // END DHCtrl::getVisual()
/////////////////////////////////////////////////////////////////////////////////////////
// Property VisualInfo
XVisualInfo DHCtrl::GetVisualInfo(void)
{
// if present an user visual info, just return it
if(UserVisualInfo)
return *UserVisualInfo;
XVisualInfo visualInfo;
// get the active visual
Visual *visual = GetVisual();
// gets a list of all available XVsualinfo
XVisualInfo *v = 0;
XVisualInfo vtemplate;
int nVis;
XVisualInfo *vlist = XGetVisualInfo(Xdisplay, VisualNoMask, &vtemplate, &nVis);
// search for current visual inside the list
if(vlist)
{
for (v = vlist; v < vlist + nVis; v++)
{
if (v->visual == visual)
{
visualInfo = *v;
break;
}
}
XFree(vlist);
}
else
{
isError = true;
ErrorMessage = "DHCtrl: no XVisualInfo for current Visual";
}
// returns the found XVisualInfo struct
return visualInfo;
}
#endif
END_UPP_NAMESPACE
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_X11
/////////////////////////////////////////////////////////////////////////////////////////
// Constructor
DHCtrl::DHCtrl()
{
// Sets control NOT initialized
isInitialized = false;
// Sets control NOT mapped
isMapped = false;
// Resets error contition
isError = false;
// Sets the user visual to null
UserVisualInfo = 0;
// No background painting
backpaint = NOBACKPAINT;
// transparent = true;
} // END Constructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Destructor
DHCtrl::~DHCtrl()
{
// Destroys the associated window and clean up stuffs
Terminate();
} // END Destructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Maps/unmaps the window
void DHCtrl::MapWindow(bool map)
{
// no action if not initialized
if(!isInitialized)
return;
if(map && !isMapped)
XMapWindow(Xdisplay, top->window);
else if(!map && isMapped)
XUnmapWindow(Xdisplay, top->window);
isMapped = map;
} // END DHCtrl::MapWndow()
/////////////////////////////////////////////////////////////////////////////////////////
// Initializes the view
bool DHCtrl::Init()
{
static bool isInitializing = false;
// Just for security sakes...
if(isInitialized)
return true;
// Prevents reentrant call....
if(isInitializing)
return false;
isInitializing = true;
// Call BeforeInit user func...
BeforeInit();
// if display is null, error
if(!Xdisplay)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Bad display");
isError = true;
isInitializing = false;
return false;
}
// Calls the user visual function
UserVisualInfo = CreateVisual();
// If error, returns
if(isError)
{
isInitializing = false;
return false;
}
// Gets the default visual, if none is given
Visual *visual;
int Depth;
if(UserVisualInfo)
{
visual = UserVisualInfo->visual;
Depth = UserVisualInfo->depth;
}
else
{
visual = DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
Depth = DefaultDepth(Xdisplay, DefaultScreen(Xdisplay));
}
// Initializes attribute setting flags
unsigned long ValueMask =
CWBorderPixel
| CWColormap
| CWSaveUnder
// | CWBackPixel
// | CWBorderPixel
| CWColormap
// | CWEventMask
// | CWWinGravity
// | CWBitGravity
; // END ValueMask
// Initializes attribute structure
XSetWindowAttributes winAttributes;
// creates a ColorMap, in case we're not using default visual
winAttributes.colormap = XCreateColormap(Xdisplay, GetTopWindow()->GetWindow(), visual, AllocNone);
winAttributes.border_pixel = 0;
winAttributes.save_under = XFalse;
// winAttributes.win_gravity = StaticGravity;
// winAttributes.bit_gravity = ForgetGravity;
// Calls the attributes user setting routine
SetAttributes(ValueMask, winAttributes);
// Creates the X11 window
Rect r = GetRectInParentWindow();
Window WindowHandle = XCreateWindow
(
Xdisplay, // display
// GetTopWindow()->GetWindow(), // parent
GetParentWindow(),
r.left, r.top, r.Width(), r.Height(), // x, y, width, height
0, // border width
Depth, // depth
InputOutput, // class
visual, // visual
ValueMask, // value mask
&winAttributes // attributes
);
// Frees VisualInfo
if (UserVisualInfo)
{
XFree( (char *)UserVisualInfo);
UserVisualInfo = 0;
}
// If problem creating window, error
if(!WindowHandle)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Can't create window");
isError = true;
isInitializing = false;
return false;
}
// Adds window to UPP managed windows
XWindow *cw = AddXWindow(WindowHandle);
cw->xic = xim ? XCreateIC
(
xim,
XNInputStyle,
XIMPreeditNothing | XIMStatusNothing,
XNClientWindow,
WindowHandle,
XNFocusWindow,
WindowHandle,
NULL
)
: NULL;
top = new Top;
top->window = WindowHandle;
long im_event_mask = 0;
if(cw->xic)
XGetICValues(cw->xic, XNFilterEvents, &im_event_mask, NULL);
XSelectInput
(
Xdisplay,
WindowHandle,
ExposureMask
// | StructureNotifyMask // *very* important, flag MUST NOT be set
| KeyPressMask
| FocusChangeMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PropertyChangeMask
| VisibilityChangeMask
| im_event_mask
);
int version = 5;
XChangeProperty
(
Xdisplay,
WindowHandle,
XAtom("XdndAware"),
XA_ATOM,
32,
0,
(byte *)&version,
1
);
// Maps the window if needed
if(IsShown())
MapWindow(true);
// Flushes the display
XFlush(Xdisplay);
// Stores the initial control size
CurrentSize = GetSize();
// Exits from initializing lock
isInitializing = false;
// mark control as initialized
isInitialized = true;
// Resets the message
isError = false;
SetErrorMessage("");
// Call AfterInit user func...
AfterInit(false);
return true;
} // END DHCtrl::Init()
/////////////////////////////////////////////////////////////////////////////////////////
// Terminates the view
void DHCtrl::Terminate(void)
{
if(!isInitialized)
return;
// Unmaps the window
MapWindow(false);
// gathers data from XWindow (needs Input Context...)
XWindow *cw = XWindowFromWindow(top->window);
// Frees input context as needed
if(cw->xic)
{
XDestroyIC(cw->xic);
cw->xic = NULL;
}
// Removes XWindow from Upp list
RemoveXWindow(top->window);
// Destroys the window
// Not to do, it's done destroying the parent window by X11 system
// XDestroyWindow(Xdisplay, top->window);
// Destroys created Top struct
delete top;
top = NULL;
// Resets initialization and error flags
isInitialized = false;
isError = false;
} // END DHCtrl::Terminate()
/////////////////////////////////////////////////////////////////////////////////////////
// State handler
void DHCtrl::State(int reason)
{
// Window dummy;
// int x, y;
// unsigned int width, height, border, depth;
Rect r;
// No handling if in error state
if( isError)
return;
// Initializes the control if needed (and possible...)
if(!isInitialized && GetTopWindow() && GetTopWindow()->GetWindow())
Init();
if(isInitialized)
{
switch( reason )
{
case FOCUS : // = 10,
break;
case ACTIVATE : // = 11,
break;
case DEACTIVATE : // = 12,
break;
case SHOW : // = 13,
MapWindow(IsVisible());
break;
case ENABLE : // = 14,
break;
case EDITABLE : // = 15,
break;
case OPEN : // = 16,
MapWindow(IsShown());
break;
case CLOSE : // = 17,
Terminate();
break;
case POSITION : // = 100,
case LAYOUTPOS : // = 101,
SyncNativeWindows();
break;
default:
break;
} // switch(reason)
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Property Visual
Visual *DHCtrl::GetVisual(void)
{
if(UserVisualInfo)
return UserVisualInfo->visual;
else
return DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
} // END DHCtrl::getVisual()
/////////////////////////////////////////////////////////////////////////////////////////
// Property VisualInfo
XVisualInfo DHCtrl::GetVisualInfo(void)
{
// if present an user visual info, just return it
if(UserVisualInfo)
return *UserVisualInfo;
XVisualInfo visualInfo;
// get the active visual
Visual *visual = GetVisual();
// gets a list of all available XVsualinfo
XVisualInfo *v = 0;
XVisualInfo vtemplate;
int nVis;
XVisualInfo *vlist = XGetVisualInfo(Xdisplay, VisualNoMask, &vtemplate, &nVis);
// search for current visual inside the list
if(vlist)
{
for (v = vlist; v < vlist + nVis; v++)
{
if (v->visual == visual)
{
visualInfo = *v;
break;
}
}
XFree(vlist);
}
else
{
isError = true;
ErrorMessage = "DHCtrl: no XVisualInfo for current Visual";
}
// returns the found XVisualInfo struct
return visualInfo;
}
#endif
END_UPP_NAMESPACE

View file

@ -223,6 +223,7 @@ Image NativePathIcon(const char *path, bool folder)
#endif
#ifdef PLATFORM_POSIX
bool isdrive = folder && ((path == "/media") || (path == "/mnt"));
FindFile ff(path);
return isdrive ? PosixGetDriveImage(GetFileName(path))
: GetFileIcon(path, GetFileName(path), folder, ff.GetMode() & 0111);
#endif

23
uppsrc/GLCtrl/GLCtrl.cpp Normal file
View file

@ -0,0 +1,23 @@
#include "GLCtrl.h"
NAMESPACE_UPP
void GLCtrl::StdView()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
Size sz = GetSize();
glViewport(0, 0, (GLsizei)sz.cx, (GLsizei)sz.cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)(sz.cx)/(GLfloat)(sz.cy), 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
END_UPP_NAMESPACE

View file

@ -8,17 +8,36 @@
NAMESPACE_UPP
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();
};
#ifdef PLATFORM_X11
#include <GL/glx.h>
class GLCtrl : public DHCtrl
{
private:
class GLCtrl : public ParentCtrl {
class GLPane : public DHCtrl {
friend class GLCtrl;
GLCtrl *ctrl;
GLPicking _picking;
// OpenGL Context
GLXContext WindowContext;
// Number of instances
static int Instances;
@ -34,7 +53,7 @@ class GLCtrl : public DHCtrl
// Currently activated context number
static int ContextActivated;
// Activates current OpenGL context
void ActivateContext();
@ -50,81 +69,112 @@ class GLCtrl : public DHCtrl
// Overridden method to resize GL windows
virtual void Resize(int w, int h);
// Internal OpenGL Paint method
void doPaint(void);
// Paint method - with graphic context
// Called from DHCtrl - Graphic context is *not* uses
// Called from DHCtrl - Graphic context is *not* used
virtual void Paint(Draw &/*draw*/);
protected:
// Overridable methods for derived controls
// Called after succesful OpenGL initialization
virtual void GLInit() {};
// Called just before OpenGL termination
virtual void GLDone() {};
// Called on resize events
virtual void GLResize( int w, int h ) {};
// Called on paint events
virtual void GLPaint() {};
public:
typedef GLCtrl CLASSNAME;
// Constructor class GLCtrl
GLCtrl( int depthsize = 24,
GLPane( int depthsize = 24,
int stencilsize = 0,
bool doublebuffer = true,
bool multisamplebuffering = false,
int numberofsamples = 0 );
// Destructor class GLCtrl
~GLCtrl();
~GLPane();
// Initializes OpenGL context to a standard view
void StdView();
// Forces control repaint
void PostPaintGL(); // same as Refresh()
// Forces control resize
void PostResizeGL();
void InitPickMatrix() { _picking.InitPickMatrix(); }
Vector<int> Pick(int x, int y);
}; // END Class GLCtrl
GLPane pane;
}; // END Class GLCtrl
protected:
// Overridable methods for derived controls
// Called after succesful OpenGL initialization
virtual void GLInit() {}
// Called just before OpenGL termination
virtual void GLDone() {}
// Called on resize events
virtual void GLResize( int w, int h ) {}
// Called on paint events
virtual void GLPaint() {}
virtual void GLPickingPaint() {}
void StdView();
void InitPickMatrix() { pane.InitPickMatrix(); }
Vector<int> Pick(int x, int y) { return pane.Pick(x, y); }
GLCtrl(int depthsize = 24, int stencilsize = 0, bool doublebuffer = true,
bool multisamplebuffering = false, int numberofsamples = 0);
};
#else
class GLCtrl : public DHCtrl {
public:
virtual void State(int reason);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
class GLCtrl : public ParentCtrl {
typedef GLCtrl CLASSNAME;
struct GLPane : DHCtrl {
GLCtrl *ctrl;
virtual void State(int reason);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};
friend class GLCtrl;
private:
HDC hDC;
HGLRC hRC;
HDC hDC;
HGLRC hRC;
GLPicking _picking;
GLPane glpane;
void OpenGL();
void CloseGL();
public:
virtual void GLPaint();
protected:
// Overridable methods for derived controls
// Called after succesful OpenGL initialization
virtual void GLInit() {}
// Called just before OpenGL termination
virtual void GLDone() {}
// Called on resize events
virtual void GLResize(int w, int h) {}
// Called on paint events
virtual void GLPaint();
virtual void GLPickingPaint() {}
public:
Callback WhenGLPaint;
GLCtrl();
~GLCtrl();
void StdView();
HDC GetDC() const { return hDC; }
HGLRC GetHGLRC() const { return hRC; }
GLCtrl();
~GLCtrl();
void InitPickMatrix() { _picking.InitPickMatrix(); }
Vector<int> Pick(int x, int y);
};
#endif

View file

@ -9,6 +9,8 @@ library(FREEBSD) "GL GLU";
file
GLCtrl.h,
Win32GlCtrl.cpp,
X11GLCtrl.cpp;
GLPicking.cpp,
Win32GLCtrl.cpp,
X11GLCtrl.cpp,
GLCtrl.cpp;

View file

@ -0,0 +1,65 @@
#include "GLCtrl.h"
NAMESPACE_UPP
GLPicking::GLPicking()
: _isPicking(false)
{}
void GLPicking::InitPickMatrix()
{
if (_isPicking)
{
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
gluPickMatrix(_pickPoint.x, viewport[3] - _pickPoint.y, 3, 3, viewport);
}
}
Vector<int> GLPicking::Pick(int x, int y, Callback resizeCallback, Callback paintCallback)
{
GLuint buffer[_bufferSize];
_pickPoint = Point(x, y);
glSelectBuffer(_bufferSize, buffer);
glRenderMode(GL_SELECT);
_isPicking = true;
resizeCallback();
glInitNames();
paintCallback();
_isPicking = false;
resizeCallback();
// returning to normal rendering mode
int hits = glRenderMode(GL_RENDER);
if (hits == 0)
return Vector<int>();
else
return ParseHits(buffer, hits);
}
Vector<int> GLPicking::ParseHits(GLuint *buffer, int hits)
{
GLuint *minPtr = buffer;
for (int i = 0; i < hits; i++)
{
if (*(buffer + 1) < *(minPtr + 1))
minPtr = buffer;
buffer += *buffer + 3;
}
Vector<int> result;
for (GLuint i = 0; i < *minPtr; i++)
result.Add(*(minPtr + 3 + i));
return result;
}
END_UPP_NAMESPACE

View file

@ -1,112 +1,130 @@
#include "GLCtrl.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking
GLCtrl::GLCtrl()
{
hDC = NULL;
hRC = NULL;
}
GLCtrl::~GLCtrl()
{
CloseGL();
}
void GLCtrl::OpenGL()
{
HWND hwnd = GetHWND();
if(!hwnd)
return;
hDC = ::GetDC(hwnd);
if(!hDC)
return;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | 0x00008000;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int pf = ChoosePixelFormat(hDC, &pfd);
if(!pf) {
CloseGL();
return;
}
if(!SetPixelFormat(hDC, pf, &pfd)) {
CloseGL();
return;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
hRC = wglCreateContext(hDC);
}
void GLCtrl::CloseGL()
{
if(hRC)
wglDeleteContext(hRC);
if(hDC)
ReleaseDC(GetHWND(), hDC);
}
void GLCtrl::State(int reason)
{
if(reason == CLOSE)
CloseGL();
DHCtrl::State(reason);
if(reason == OPEN)
OpenGL();
}
void GLCtrl::GLPaint()
{
WhenGLPaint();
}
void GLCtrl::StdView()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
Size sz = GetSize();
glViewport(0, 0, (GLsizei)sz.cx, (GLsizei)sz.cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)(sz.cx)/(GLfloat)(sz.cy), 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
LRESULT GLCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_PAINT && hDC && hRC) {
wglMakeCurrent(hDC, hRC);
GLPaint();
glFlush();
glFinish();
SwapBuffers(hDC);
wglMakeCurrent(NULL, NULL);
PAINTSTRUCT ps;
BeginPaint(GetHWND(), &ps);
EndPaint(GetHWND(), &ps);
return 0;
}
if(message == WM_ERASEBKGND)
return 1;
return DHCtrl::WindowProc(message, wParam, lParam);
}
#endif
END_UPP_NAMESPACE
#include "GLCtrl.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking
GLCtrl::GLCtrl()
{
hDC = NULL;
hRC = NULL;
glpane.ctrl = this;
Add(glpane.SizePos());
}
GLCtrl::~GLCtrl()
{
CloseGL();
}
void GLCtrl::OpenGL()
{
HWND hwnd = glpane.GetHWND();
if(!hwnd)
return;
hDC = ::GetDC(hwnd);
if(!hDC)
return;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | 0x00008000;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int pf = ChoosePixelFormat(hDC, &pfd);
if(!pf) {
CloseGL();
return;
}
if(!SetPixelFormat(hDC, pf, &pfd)) {
CloseGL();
return;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
hRC = wglCreateContext(hDC);
if (!hRC)
return;
wglMakeCurrent(hDC, hRC);
GLInit();
GLResize(GetSize().cx, GetSize().cy);
}
void GLCtrl::CloseGL()
{
if (hDC != NULL && hRC != NULL)
{
wglMakeCurrent(hDC, hRC);
GLDone();
wglMakeCurrent(NULL, NULL);
}
if(hRC)
wglDeleteContext(hRC);
if(hDC)
ReleaseDC(glpane.GetHWND(), hDC);
}
void GLCtrl::GLPaint()
{
WhenGLPaint();
}
void GLCtrl::GLPane::State(int reason)
{
if (reason == CLOSE)
ctrl->CloseGL();
if (reason == LAYOUTPOS && ctrl->hDC != NULL && ctrl->hRC != NULL)
{
wglMakeCurrent(ctrl->hDC, ctrl->hRC);
ctrl->GLResize(GetSize().cx, GetSize().cy);
wglMakeCurrent(NULL, NULL);
}
DHCtrl::State(reason);
if (reason == OPEN)
ctrl->OpenGL();
}
LRESULT GLCtrl::GLPane::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_PAINT && ctrl->hDC && ctrl->hRC)
{
PAINTSTRUCT ps;
BeginPaint(GetHWND(), &ps);
wglMakeCurrent(ctrl->hDC, ctrl->hRC);
ctrl->GLPaint();
glFlush();
glFinish();
SwapBuffers(ctrl->hDC);
wglMakeCurrent(NULL, NULL);
EndPaint(GetHWND(), &ps);
return 0;
}
else if(message == WM_ERASEBKGND)
return 1;
return DHCtrl::WindowProc(message, wParam, lParam);
}
Vector<int> GLCtrl::Pick(int x, int y)
{
wglMakeCurrent(hDC, hRC);
Vector<int> result = _picking.Pick(x, y, THISBACK2(GLResize, GetSize().cx, GetSize().cy), THISBACK(GLPickingPaint));
wglMakeCurrent(NULL, NULL);
return result;
}
#endif
END_UPP_NAMESPACE

View file

@ -6,13 +6,13 @@ NAMESPACE_UPP
/////////////////////////////////////////////////////////////////////////////////////////
// Static members initialization
int GLCtrl::Instances = 0;
int GLCtrl::ContextActivated = 0;
int GLCtrl::GLPane::Instances = 0;
int GLCtrl::GLPane::ContextActivated = 0;
/////////////////////////////////////////////////////////////////////////////////////////
// Constructor
GLCtrl::GLCtrl( int depthsize, int stencilsize, bool doublebuffer,
bool multisamplebuffering, int numberofsamples )
GLCtrl::GLPane::GLPane(int depthsize, int stencilsize, bool doublebuffer,
bool multisamplebuffering, int numberofsamples )
{
// Sets the current instance number and updates total instances
InstanceNum = ++Instances;
@ -23,12 +23,11 @@ GLCtrl::GLCtrl( int depthsize, int stencilsize, bool doublebuffer,
StencilSize = stencilsize;
DoubleBuffering = doublebuffer;
NumberOfSamples = numberofsamples;
} // END Constructor class GLCtrl
} // END Constructor class GLCtrl::GLPane
/////////////////////////////////////////////////////////////////////////////////////////
// Destructor
GLCtrl::~GLCtrl()
GLCtrl::GLPane::~GLPane()
{
// If glx context is still there, destroy it
// That can happen on unclean exit
@ -37,12 +36,11 @@ GLCtrl::~GLCtrl()
glXDestroyContext( (Display *)Xdisplay, WindowContext );
WindowContext = NULL;
}
} // END Destructor class GLCtrl
} // END Destructor class GLCtrl::GLPane
/////////////////////////////////////////////////////////////////////////////////////////
// Ovverridden method to choose the correct visual
XVisualInfo *GLCtrl::CreateVisual(void)
XVisualInfo *GLCtrl::GLPane::CreateVisual(void)
{
Vector<int> visual;
visual << GLX_RGBA << GLX_DEPTH_SIZE << DepthSize;
@ -67,17 +65,15 @@ XVisualInfo *GLCtrl::CreateVisual(void)
if( visualInfo == NULL )
{
SetError(true);
SetErrorMessage("GLCtrl : Impossible to find a suitable visual.");
SetErrorMessage("GLCtrl::GLPane : Impossible to find a suitable visual.");
}
return visualInfo;
} // END GLCtrl::GLPane::CreateVisual()
} // END GLCtrl::CreateVisual()
/////////////////////////////////////////////////////////////////////////////////////////
// Overridden method for attribute setting
void GLCtrl::SetAttributes(unsigned long &ValueMask, XSetWindowAttributes &winAttributes)
void GLCtrl::GLPane::SetAttributes(unsigned long &ValueMask, XSetWindowAttributes &winAttributes)
{
ValueMask |=
CWBorderPixel
@ -87,13 +83,12 @@ void GLCtrl::SetAttributes(unsigned long &ValueMask, XSetWindowAttributes &winAt
winAttributes.border_pixel = 0;
winAttributes.event_mask = ExposureMask;
winAttributes.save_under = XFalse;
} // END GLCtrl::SetAttributes()
} // END GLCtrl::GLPane::SetAttributes()
/////////////////////////////////////////////////////////////////////////////////////////
// Activates current OpenGL context
void GLCtrl::ActivateContext()
void GLCtrl::GLPane::ActivateContext()
{
if( Instances > 0 && ContextActivated != InstanceNum )
{
@ -104,7 +99,7 @@ void GLCtrl::ActivateContext()
/////////////////////////////////////////////////////////////////////////////////////////
// Overridden method to create OpenGL context
void GLCtrl::AfterInit(bool Error)
void GLCtrl::GLPane::AfterInit(bool Error)
{
// Gets the activw XVisualInfo
XVisualInfo visualInfo = GetVisualInfo();
@ -120,7 +115,7 @@ void GLCtrl::AfterInit(bool Error)
if( WindowContext == NULL )
{
SetErrorMessage("GLCtrl : Error creating GLX context.");
SetErrorMessage("GLCtrl::GLPane : Error creating GLX context.");
SetError(true);
}
@ -128,116 +123,79 @@ void GLCtrl::AfterInit(bool Error)
glXMakeCurrent( (Display*)Xdisplay, GetWindow(), WindowContext );
// Call user init function
GLInit();
ctrl->GLInit();
// Calls resize and paint functions
GLResize( GetSize().cx, GetSize().cy );
GLPaint();
} // END GLCtrl::AfterInit()
ctrl->GLResize( GetSize().cx, GetSize().cy );
ctrl->GLPaint();
} // END GLCtrl::GLPane::AfterInit()
/////////////////////////////////////////////////////////////////////////////////////////
// Overridden method to destroy OpenGL context
void GLCtrl::BeforeTerminate(void)
void GLCtrl::GLPane::BeforeTerminate(void)
{
// Calls user terminate function
GLDone();
ctrl->GLDone();
// Resets context and destroys it
glXMakeCurrent( (Display*)Xdisplay, None, NULL );
glXDestroyContext( (Display *)Xdisplay, WindowContext );
WindowContext = NULL;
} // END GLCtrl::BeforeTerminate()
} // END GLCtrl::GLPane::BeforeTerminate()
/////////////////////////////////////////////////////////////////////////////////////////
// Overridden method to resize GL windows
void GLCtrl::Resize(int x, int y)
void GLCtrl::GLPane::Resize(int x, int y)
{
// Activates the current context
ActivateContext();
// Calls user resize hook
GLResize(x, y);
} // END GLCtrl::Resize()
ctrl->GLResize(x, y);
} // END GLCtrl::GLPane::Resize()
/////////////////////////////////////////////////////////////////////////////////////////
// Internal OpenGL Paint method
void GLCtrl::doPaint(void)
void GLCtrl::GLPane::doPaint(void)
{
// Activates the current context
ActivateContext();
// Calls user paint hook
GLPaint();
ctrl->GLPaint();
// Swap buffers or flush as needed
if( DoubleBuffering )
glXSwapBuffers( (Display*)Xdisplay, GetWindow() ); // Buffer swap does implicit glFlush
else
glFlush();
} // END GLCtrl::doPaint()
} // END GLCtrl::GLPane::doPaint()
/////////////////////////////////////////////////////////////////////////////////////////
// Paint method - with graphic context
void GLCtrl::Paint(Draw &draw)
void GLCtrl::GLPane::Paint(Draw &draw)
{
// Calls internal OpenGL Paint method
doPaint();
} // END GLCtrl::Paint()
} // END GLCtrl::GLPane::Paint()
/////////////////////////////////////////////////////////////////////////////////////////
// Forces control resize
void GLCtrl::PostResizeGL()
Vector<int> GLCtrl::GLPane::Pick(int x, int y)
{
// Gets sizes from Control
int w = GetSize().cx,
h = GetSize().cy;
// Calls Resize method
Resize(w, h);
ActivateContext();
Vector<int> result = _picking.Pick(x, y,
callback2(ctrl, &GLCtrl::GLResize, GetSize().cx, GetSize().cy),
callback(ctrl, &GLCtrl::GLPickingPaint));
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Forces control repaint
void GLCtrl::PostPaintGL()
GLCtrl::GLCtrl(int depthsize, int stencilsize, bool doublebuffer, bool multisamplebuffering, int numberofsamples)
: pane(depthsize, stencilsize, doublebuffer, multisamplebuffering, numberofsamples)
{
// Calls internal OpenGL Paint method
doPaint();
} // END GLCtrl::PostPaintGL()
/////////////////////////////////////////////////////////////////////////////////////////
// Initializes OpenGL context to a standard view
void GLCtrl::StdView()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
Size sz = GetSize();
glViewport(0, 0, (GLsizei)sz.cx, (GLsizei)sz.cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)(sz.cx)/(GLfloat)(sz.cy), 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} // END GLCtrl::StdView()
pane.ctrl = this;
Add(pane.SizePos());
}
#endif