GLCtrl: DHCtrl improvements

git-svn-id: svn://ultimatepp.org/upp/trunk@12376 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-10-19 07:44:01 +00:00
parent e0b020d27f
commit f6c972f05e
11 changed files with 155 additions and 120 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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);
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<DHCtrl *>(q);
if(dh)
UpdateWindow(dh->GetHWND());
q->UpdateDHCtrls();
}
}
#endif
}

View file

@ -22,6 +22,8 @@ private:
static void RenderAllFormats();
static void DestroyClipboard();
void UpdateDHCtrls();
public:
static Win32Event ExitLoopEvent;
static bool endsession;

View file

@ -91,6 +91,9 @@ private:
static bool PreprocessMessageAll(MSG& msg);
Rect current_pos = Null;
int current_visible = Null;
friend class Ctrl;
protected:

View file

@ -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

View file

@ -43,7 +43,7 @@ Image GLCtrl::GLPane::MouseEvent(int event, Point p, int zdelta, dword keyflags)
Vector<int> GLCtrl::Pick(int x, int y)
{
pane.ActivateContext();
// pane.ActivateContext();
return picking.Pick(x, y, THISBACK2(GLResize, GetSize().cx, GetSize().cy), THISBACK(GLPickingPaint));
}

View file

@ -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);

View file

@ -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<int> 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<int> 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;
}

View file

@ -20,6 +20,7 @@ namespace Upp {
enum {
TEXTURE_LINEAR = 0x01,
TEXTURE_MIPMAP = 0x02,
TEXTURE_COMPRESSED = 0x04,
};
GLuint CreateGLTexture(const Image& img, dword flags);

View file

@ -1,9 +1,9 @@
description "OpenGL extension wrangler library\3770,128,128";
file
glew.c,
glew.h,
glxew.h,
wglew.h,
glew.c,
Copying;