diff --git a/uppsrc/CtrlCore/X11DHCtrl.cpp b/uppsrc/CtrlCore/X11DHCtrl.cpp index f6c56aa3f..896889b46 100644 --- a/uppsrc/CtrlCore/X11DHCtrl.cpp +++ b/uppsrc/CtrlCore/X11DHCtrl.cpp @@ -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 diff --git a/uppsrc/CtrlLib/FileSel.cpp b/uppsrc/CtrlLib/FileSel.cpp index 4a12136af..ef9c700a4 100644 --- a/uppsrc/CtrlLib/FileSel.cpp +++ b/uppsrc/CtrlLib/FileSel.cpp @@ -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 diff --git a/uppsrc/GLCtrl/GLCtrl.cpp b/uppsrc/GLCtrl/GLCtrl.cpp new file mode 100644 index 000000000..52a5cc0b9 --- /dev/null +++ b/uppsrc/GLCtrl/GLCtrl.cpp @@ -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 diff --git a/uppsrc/GLCtrl/GLCtrl.h b/uppsrc/GLCtrl/GLCtrl.h index a48e86436..397ba0667 100644 --- a/uppsrc/GLCtrl/GLCtrl.h +++ b/uppsrc/GLCtrl/GLCtrl.h @@ -8,17 +8,36 @@ NAMESPACE_UPP +class GLPicking +{ +private: + static int const _bufferSize = 512; + bool _isPicking; + Point _pickPoint; + + Vector ParseHits(GLuint *buffer, int hits); + +public: + void InitPickMatrix(); + Vector Pick(int x, int y, Callback resizeCallback, Callback paintCallback); + + GLPicking(); +}; + #ifdef PLATFORM_X11 #include -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 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 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 Pick(int x, int y); }; #endif diff --git a/uppsrc/GLCtrl/GLCtrl.upp b/uppsrc/GLCtrl/GLCtrl.upp index 60e6ed9bd..71dd724ac 100644 --- a/uppsrc/GLCtrl/GLCtrl.upp +++ b/uppsrc/GLCtrl/GLCtrl.upp @@ -9,6 +9,8 @@ library(FREEBSD) "GL GLU"; file GLCtrl.h, - Win32GlCtrl.cpp, - X11GLCtrl.cpp; + GLPicking.cpp, + Win32GLCtrl.cpp, + X11GLCtrl.cpp, + GLCtrl.cpp; diff --git a/uppsrc/GLCtrl/GLPicking.cpp b/uppsrc/GLCtrl/GLPicking.cpp new file mode 100644 index 000000000..07e6ea0a8 --- /dev/null +++ b/uppsrc/GLCtrl/GLPicking.cpp @@ -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 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(); + else + return ParseHits(buffer, hits); +} + +Vector 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 result; + for (GLuint i = 0; i < *minPtr; i++) + result.Add(*(minPtr + 3 + i)); + + return result; +} + +END_UPP_NAMESPACE diff --git a/uppsrc/GLCtrl/Win32GlCtrl.cpp b/uppsrc/GLCtrl/Win32GLCtrl.cpp similarity index 55% rename from uppsrc/GLCtrl/Win32GlCtrl.cpp rename to uppsrc/GLCtrl/Win32GLCtrl.cpp index c0b6ffc6a..ad7d3f803 100644 --- a/uppsrc/GLCtrl/Win32GlCtrl.cpp +++ b/uppsrc/GLCtrl/Win32GLCtrl.cpp @@ -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 GLCtrl::Pick(int x, int y) +{ + wglMakeCurrent(hDC, hRC); + Vector result = _picking.Pick(x, y, THISBACK2(GLResize, GetSize().cx, GetSize().cy), THISBACK(GLPickingPaint)); + wglMakeCurrent(NULL, NULL); + + return result; +} + +#endif + +END_UPP_NAMESPACE diff --git a/uppsrc/GLCtrl/X11GLCtrl.cpp b/uppsrc/GLCtrl/X11GLCtrl.cpp index fc61e1390..5e7b270fa 100644 --- a/uppsrc/GLCtrl/X11GLCtrl.cpp +++ b/uppsrc/GLCtrl/X11GLCtrl.cpp @@ -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 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 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 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