diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index eddbf18a0..0545819eb 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -21,7 +21,7 @@ void Ctrl::RefreshFrame(const Rect& r) { LLOG("RefreshRect " << Name() << ' ' << r); if(GuiPlatformRefreshFrameSpecial(r)) return; - if(!top) { + if(!top && !isdhctrl) { if(InFrame()) parent->RefreshFrame(r + GetRect().TopLeft()); else @@ -168,6 +168,10 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy) #else if(IsFullRefresh() || !IsVisible()) return; + if(isdhctrl) { + Refresh(_r); + return; + } Size vsz = GetSize(); dx = sgn(dx) * min(abs(dx), vsz.cx); dy = sgn(dy) * min(abs(dy), vsz.cy); diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 4155838c0..abceac62e 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -188,7 +188,7 @@ void Ctrl::SetPos0(LogPos p, bool _inframe) { GuiLock __; if(p == pos && inframe == _inframe) return; - if(parent) { + if(parent && !isdhctrl) { if(!globalbackbuffer) { Rect from = GetRect().Size(); Top *top = GetTopRect(from, true)->top; diff --git a/uppsrc/CtrlCore/DHCtrl.cpp b/uppsrc/CtrlCore/DHCtrl.cpp index d880f5deb..1ac261da2 100644 --- a/uppsrc/CtrlCore/DHCtrl.cpp +++ b/uppsrc/CtrlCore/DHCtrl.cpp @@ -46,6 +46,8 @@ void DHCtrl::NcDestroy() LRESULT DHCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { GuiLock __; + if(message == WM_ERASEBKGND) + return 1L; return DefWindowProc(hwnd, message, wParam, lParam); } @@ -76,11 +78,14 @@ void DHCtrl::SyncHWND() GuiLock __; HWND phwnd = GetTopCtrl()->GetHWND(); if(phwnd) { - Rect r = GetScreenView(); - Rect pr = GetScreenClient(phwnd); - SetWindowPos(hwnd, NULL, r.left - pr.left, r.top - pr.top, r.Width(), r.Height(), - SWP_NOACTIVATE|SWP_NOZORDER); - ShowWindow(hwnd, IsVisible() ? SW_SHOW : SW_HIDE); + Rect r = GetScreenView() - GetScreenClient(phwnd).TopLeft(); + if(r != current_pos || IsVisible() != (bool)current_visible) { + SetWindowPos(hwnd, NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOACTIVATE|SWP_NOZORDER); + ShowWindow(hwnd, IsVisible() ? SW_SHOW : SW_HIDE); + Refresh(); + current_pos = r; + current_visible = IsVisible(); + } } } @@ -88,6 +93,8 @@ void DHCtrl::State(int reason) { switch(reason) { case OPEN: + current_pos = Null; + current_visible = Null; OpenHWND(); default: SyncHWND(); @@ -111,6 +118,17 @@ DHCtrl::~DHCtrl() RemoveActive(); } +void Ctrl::UpdateDHCtrls() +{ // we call this in WM_PAINT to force updating in single WM_PAINT, this makes things smoother e.g. with OpenGL in splitter + for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) { + DHCtrl *dh = dynamic_cast(q); + if(dh) + UpdateWindow(dh->GetHWND()); + q->UpdateDHCtrls(); + } +} + + #endif } diff --git a/uppsrc/CtrlCore/Win32Ctrl.h b/uppsrc/CtrlCore/Win32Ctrl.h index b0faa982d..37fa0f786 100644 --- a/uppsrc/CtrlCore/Win32Ctrl.h +++ b/uppsrc/CtrlCore/Win32Ctrl.h @@ -22,6 +22,8 @@ private: static void RenderAllFormats(); static void DestroyClipboard(); + void UpdateDHCtrls(); + public: static Win32Event ExitLoopEvent; static bool endsession; diff --git a/uppsrc/CtrlCore/Win32GuiA.h b/uppsrc/CtrlCore/Win32GuiA.h index 0955fbc91..ce2dce93d 100644 --- a/uppsrc/CtrlCore/Win32GuiA.h +++ b/uppsrc/CtrlCore/Win32GuiA.h @@ -91,6 +91,9 @@ private: static bool PreprocessMessageAll(MSG& msg); + Rect current_pos = Null; + int current_visible = Null; + friend class Ctrl; protected: diff --git a/uppsrc/CtrlCore/Win32Proc.cpp b/uppsrc/CtrlCore/Win32Proc.cpp index 72e8e8c62..89bdbc451 100644 --- a/uppsrc/CtrlCore/Win32Proc.cpp +++ b/uppsrc/CtrlCore/Win32Proc.cpp @@ -112,6 +112,8 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { #endif } EndPaint(hwnd, &ps); + + UpdateDHCtrls(); // so that they are displayed withing the same WM_PAINT - looks better } return 0L; #ifndef PLATFORM_WINCE diff --git a/uppsrc/GLCtrl/GLCtrl.cpp b/uppsrc/GLCtrl/GLCtrl.cpp index 885fc348a..9a438cf75 100644 --- a/uppsrc/GLCtrl/GLCtrl.cpp +++ b/uppsrc/GLCtrl/GLCtrl.cpp @@ -43,7 +43,7 @@ Image GLCtrl::GLPane::MouseEvent(int event, Point p, int zdelta, dword keyflags) Vector GLCtrl::Pick(int x, int y) { - pane.ActivateContext(); +// pane.ActivateContext(); return picking.Pick(x, y, THISBACK2(GLResize, GetSize().cx, GetSize().cy), THISBACK(GLPickingPaint)); } diff --git a/uppsrc/GLCtrl/GLCtrl.h b/uppsrc/GLCtrl/GLCtrl.h index 17cfa7701..1df666bc5 100644 --- a/uppsrc/GLCtrl/GLCtrl.h +++ b/uppsrc/GLCtrl/GLCtrl.h @@ -111,13 +111,12 @@ private: struct GLPane : DHCtrl { friend class GLCtrl; - HDC hDC; - HGLRC hRC; + // HDC hDC; + // HGLRC hRC; GLCtrl *ctrl; public: - GLPane() : hDC(NULL), hRC(NULL) { NoWantFocus(); } - ~GLPane() { Destroy(); } + GLPane()/* : hDC(NULL), hRC(NULL)*/ { NoWantFocus(); } virtual void State(int reason); virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); diff --git a/uppsrc/GLCtrl/Win32GLCtrl.cpp b/uppsrc/GLCtrl/Win32GLCtrl.cpp index 4b4fe0cb9..1996bbb17 100644 --- a/uppsrc/GLCtrl/Win32GLCtrl.cpp +++ b/uppsrc/GLCtrl/Win32GLCtrl.cpp @@ -7,6 +7,81 @@ namespace Upp { #pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking #pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking +static HGLRC s_openGLContext; // we only have single OpenGL context for all windows +static PIXELFORMATDESCRIPTOR s_pfd; +static int s_pixelFormatID; + +void MakeGLContext(HWND hwnd, int depthBits, int stencilBits, int samples) +{ + ONCELOCK { + for(int pass = 0; pass < 2; pass++) { + HWND hWND = CreateWindow("UPP-CLASS-A", "Fake Window", + WS_CAPTION|WS_SYSMENU|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 0, 0, 1, 1, NULL, NULL, + NULL, NULL); + if(!hWND) + return; + HDC hDC = ::GetDC(hWND); + if(!hDC) + return; + memset(&s_pfd, 0, sizeof(s_pfd)); + if(pass == 0) { + s_pfd.nSize = sizeof(s_pfd); + s_pfd.nVersion = 1; + s_pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_GENERIC_FORMAT; + s_pfd.iPixelType = PFD_TYPE_RGBA; + s_pfd.cColorBits = 32; + s_pfd.cAlphaBits = 8; + s_pfd.cDepthBits = 24; + s_pfd.cStencilBits = 8; + s_pfd.iLayerType = PFD_MAIN_PLANE; + s_pixelFormatID = ChoosePixelFormat(hDC, &s_pfd); + } + else { + Vector attr; + attr + << WGL_DRAW_TO_WINDOW_ARB << GL_TRUE + << WGL_SUPPORT_OPENGL_ARB << GL_TRUE + << WGL_DOUBLE_BUFFER_ARB << GL_TRUE + << WGL_PIXEL_TYPE_ARB << WGL_TYPE_RGBA_ARB + << WGL_ACCELERATION_ARB << WGL_FULL_ACCELERATION_ARB + << WGL_COLOR_BITS_ARB << 32 + << WGL_ALPHA_BITS_ARB << 8 + << WGL_DEPTH_BITS_ARB << depthBits + << WGL_STENCIL_BITS_ARB << stencilBits + ; + if(samples > 1) + attr + << WGL_SAMPLE_BUFFERS_ARB << GL_TRUE + << WGL_SAMPLES_ARB << samples + ; + attr << 0; + UINT numFormats; + if(!wglChoosePixelFormatARB(hDC, attr, NULL, 1, &s_pixelFormatID, &numFormats)) + return; + } + + DescribePixelFormat(hDC, s_pixelFormatID, sizeof(PIXELFORMATDESCRIPTOR), &s_pfd); + if(!SetPixelFormat(hDC, s_pixelFormatID, &s_pfd)) + return; + + if(pass == 0) { + HGLRC hRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hRC); + glewInit(); + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC); + } + else + s_openGLContext = wglCreateContext(hDC); + + ReleaseDC(hWND, hDC); + DestroyWindow(hWND); + } + } +} + + void InitializeGlew() { ONCELOCK { // create temporary window to initialize glew @@ -19,22 +94,22 @@ void InitializeGlew() HDC 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_GENERIC_ACCELERATED | PFD_GENERIC_FORMAT; -// if (ctrl->doubleBuffering) pfd.dwFlags |= PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 32; - pfd.cAlphaBits = 8; - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; - pfd.iLayerType = PFD_MAIN_PLANE; - int pixelFormatID = ChoosePixelFormat(hDC, &pfd); + PIXELFORMATDESCRIPTOR s_pfd; + memset(&s_pfd, 0, sizeof(s_pfd)); + s_pfd.nSize = sizeof(s_pfd); + s_pfd.nVersion = 1; + s_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_GENERIC_FORMAT; +// if (ctrl->doubleBuffering) s_pfd.dwFlags |= PFD_DOUBLEBUFFER; + s_pfd.iPixelType = PFD_TYPE_RGBA; + s_pfd.cColorBits = 32; + s_pfd.cAlphaBits = 8; + s_pfd.cDepthBits = 24; + s_pfd.cStencilBits = 8; + s_pfd.iLayerType = PFD_MAIN_PLANE; + int pixelFormatID = ChoosePixelFormat(hDC, &s_pfd); - DescribePixelFormat(hDC, pixelFormatID, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - SetPixelFormat(hDC, pixelFormatID, &pfd); + DescribePixelFormat(hDC, pixelFormatID, sizeof(PIXELFORMATDESCRIPTOR), &s_pfd); + SetPixelFormat(hDC, pixelFormatID, &s_pfd); HGLRC hRC = wglCreateContext(hDC); @@ -49,110 +124,41 @@ void InitializeGlew() } } -void GLCtrl::GLPane::Init() -{ - InitializeGlew(); - - HWND hwnd = GetHWND(); - if(!hwnd) - return; - hDC = ::GetDC(hwnd); - if(!hDC) - return; - int pixelFormatID; - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(pfd)); - - Vector attr; - attr - << WGL_DRAW_TO_WINDOW_ARB << GL_TRUE - << WGL_SUPPORT_OPENGL_ARB << GL_TRUE - << WGL_DOUBLE_BUFFER_ARB << GL_TRUE - << WGL_PIXEL_TYPE_ARB << WGL_TYPE_RGBA_ARB - << WGL_ACCELERATION_ARB << WGL_FULL_ACCELERATION_ARB - << WGL_COLOR_BITS_ARB << 32 - << WGL_ALPHA_BITS_ARB << 8 - << WGL_DEPTH_BITS_ARB << ctrl->depthSize - << WGL_STENCIL_BITS_ARB << ctrl->stencilSize - ; - if(ctrl->numberOfSamples > 1) - attr - << WGL_SAMPLE_BUFFERS_ARB << GL_TRUE - << WGL_SAMPLES_ARB << ctrl->numberOfSamples - ; - attr << 0; - UINT numFormats; - if(!wglChoosePixelFormatARB(hDC, attr, NULL, 1, &pixelFormatID, &numFormats)) { - Destroy(); - return; - } - - DescribePixelFormat(hDC, pixelFormatID, sizeof(pfd), &pfd); - if(!SetPixelFormat(hDC, pixelFormatID, &pfd)) { - Destroy(); - return; - } - hRC = wglCreateContext(hDC); - ActivateContext(); - glEnable(GL_MULTISAMPLE); - - ctrl->GLInit(); - ctrl->GLResize(GetSize().cx, GetSize().cy); - ctrl->GLPaint(); -} - -void GLCtrl::GLPane::Destroy() -{ - if (hDC != NULL && hRC != NULL) - { - ActivateContext(); - ctrl->GLDone(); - wglMakeCurrent(NULL, NULL); - } - - if(hRC) - wglDeleteContext(hRC); - if(hDC) - ReleaseDC(GetHWND(), hDC); -} - -void GLCtrl::GLPane::ActivateContext() -{ - if (hRC != NULL && wglGetCurrentContext() != hRC) - wglMakeCurrent(hDC, hRC); -} - void GLCtrl::GLPane::State(int reason) { - if (reason == CLOSE) - Destroy(); - - if ((reason == LAYOUTPOS || reason == POSITION) && hDC != NULL && hRC != NULL) - { - ActivateContext(); - ctrl->GLResize(GetSize().cx, GetSize().cy); - } - DHCtrl::State(reason); - if (reason == OPEN) - Init(); + if(reason == OPEN) { + HWND hwnd = GetHWND(); + MakeGLContext(hwnd, ctrl->depthSize, ctrl->stencilSize, ctrl->numberOfSamples); + HDC hDC = GetDC(hwnd); + if(!SetPixelFormat(hDC, s_pixelFormatID, &s_pfd)) + return; + ReleaseDC(hwnd, hDC); + } } LRESULT GLCtrl::GLPane::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { - if((message == WM_PAINT || message == WM_SIZE || message == WM_ERASEBKGND) && hDC && hRC) - { + if(message == WM_PAINT && s_openGLContext) { + static int i = 0; PAINTSTRUCT ps; - BeginPaint(GetHWND(), &ps); - ActivateContext(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + HWND hwnd = GetHWND(); + BeginPaint(hwnd, &ps); + HDC hDC = ps.hdc; + wglMakeCurrent(hDC, s_openGLContext); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + glEnable(GL_MULTISAMPLE); + Size sz = GetSize(); + glViewport(0, 0, (GLsizei)sz.cx, (GLsizei)sz.cy); ctrl->GLPaint(); if(ctrl->doubleBuffering) SwapBuffers(hDC); else glFlush(); - EndPaint(GetHWND(), &ps); + wglMakeCurrent(NULL, NULL); + ReleaseDC(hwnd, hDC); + EndPaint(hwnd, &ps); return 0; } diff --git a/uppsrc/GLDraw/GLDraw.h b/uppsrc/GLDraw/GLDraw.h index 6d1836d8a..d3d2a67de 100644 --- a/uppsrc/GLDraw/GLDraw.h +++ b/uppsrc/GLDraw/GLDraw.h @@ -18,8 +18,9 @@ namespace Upp { enum { - TEXTURE_LINEAR = 0x01, - TEXTURE_MIPMAP = 0x02, + TEXTURE_LINEAR = 0x01, + TEXTURE_MIPMAP = 0x02, + TEXTURE_COMPRESSED = 0x04, }; GLuint CreateGLTexture(const Image& img, dword flags); diff --git a/uppsrc/plugin/glew/glew.upp b/uppsrc/plugin/glew/glew.upp index becb67099..e1799736a 100644 --- a/uppsrc/plugin/glew/glew.upp +++ b/uppsrc/plugin/glew/glew.upp @@ -1,9 +1,9 @@ description "OpenGL extension wrangler library\3770,128,128"; file - glew.c, glew.h, glxew.h, wglew.h, + glew.c, Copying;