mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
GLCtrl: DHCtrl improvements
git-svn-id: svn://ultimatepp.org/upp/trunk@12376 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
e0b020d27f
commit
f6c972f05e
11 changed files with 155 additions and 120 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ private:
|
|||
static void RenderAllFormats();
|
||||
static void DestroyClipboard();
|
||||
|
||||
void UpdateDHCtrls();
|
||||
|
||||
public:
|
||||
static Win32Event ExitLoopEvent;
|
||||
static bool endsession;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ private:
|
|||
|
||||
static bool PreprocessMessageAll(MSG& msg);
|
||||
|
||||
Rect current_pos = Null;
|
||||
int current_visible = Null;
|
||||
|
||||
friend class Ctrl;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ namespace Upp {
|
|||
enum {
|
||||
TEXTURE_LINEAR = 0x01,
|
||||
TEXTURE_MIPMAP = 0x02,
|
||||
TEXTURE_COMPRESSED = 0x04,
|
||||
};
|
||||
|
||||
GLuint CreateGLTexture(const Image& img, dword flags);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
description "OpenGL extension wrangler library\3770,128,128";
|
||||
|
||||
file
|
||||
glew.c,
|
||||
glew.h,
|
||||
glxew.h,
|
||||
wglew.h,
|
||||
glew.c,
|
||||
Copying;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue