diff options
| author | Arisotura <thetotalworm@gmail.com> | 2019-05-25 20:42:27 +0200 | 
|---|---|---|
| committer | Arisotura <thetotalworm@gmail.com> | 2019-05-25 20:42:27 +0200 | 
| commit | 94f5ecb64714c3a4026bebe4f81a99ca4dba0362 (patch) | |
| tree | cfc88ac94ce13bb1332aadde9f15c6eb4e61aee5 /src/libui_sdl/libui | |
| parent | 63e42bf90fa9d78c92123dcbc9c2b8ca5bb5e3ba (diff) | |
| parent | 9ed1dda9ca18e571fc6613885ac944bbb938cd9a (diff) | |
Merge branch 'blackmagic'
BAHAHAHHAHAHAHAAHAHAHAHHH
HARK HARK HARK HARK HA-*~
Diffstat (limited to 'src/libui_sdl/libui')
| -rw-r--r-- | src/libui_sdl/libui/ui.h | 19 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/area.cpp | 73 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/area.hpp | 11 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/areadraw.cpp | 27 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/areaevents.cpp | 2 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/areautil.cpp | 21 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/gl.cpp | 142 | ||||
| -rw-r--r-- | src/libui_sdl/libui/windows/window.cpp | 15 | 
8 files changed, 294 insertions, 16 deletions
| diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 5f40aff..d2e9960 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -108,6 +108,8 @@ typedef struct uiWindow uiWindow;  #define uiWindow(this) ((uiWindow *) (this))  _UI_EXTERN char *uiWindowTitle(uiWindow *w);  _UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title); +_UI_EXTERN void uiWindowPosition(uiWindow *w, int *x, int *y); +_UI_EXTERN void uiWindowSetPosition(uiWindow *w, int x, int y);  _UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height);  _UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height);  _UI_EXTERN int uiWindowMinimized(uiWindow *w); @@ -326,6 +328,10 @@ _UI_ENUM(uiWindowResizeEdge) {  	// TODO way to bring up the system menu instead?  }; +#define uiGLVersion(major, minor)  ((major) | ((minor)<<16)) +#define uiGLVerMajor(ver)          ((ver) & 0xFFFF) +#define uiGLVerMinor(ver)          ((ver) >> 16) +  #define uiArea(this) ((uiArea *) (this))  // TODO give a better name  // TODO document the types of width and height @@ -342,6 +348,7 @@ _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a);  _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);  _UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b);  _UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); +_UI_EXTERN uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions);  _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);  struct uiAreaDrawParams { @@ -599,6 +606,18 @@ _UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar  _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout); + +// OpenGL support + +typedef struct uiGLContext uiGLContext; + +_UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a); +_UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); +_UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx); +_UI_EXTERN void *uiGLGetProcAddress(const char* proc); +_UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx); + +  _UI_ENUM(uiModifiers) {  	uiModifierCtrl = 1 << 0,  	uiModifierAlt = 1 << 1, diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp index 2185f25..72d5145 100644 --- a/src/libui_sdl/libui/windows/area.cpp +++ b/src/libui_sdl/libui/windows/area.cpp @@ -25,8 +25,11 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM  	}  	// always recreate the render target if necessary -	if (a->rt == NULL) -		a->rt = makeHWNDRenderTarget(a->hwnd); +	if (!a->openGL) +    { +        if (a->rt == NULL) +            a->rt = makeHWNDRenderTarget(a->hwnd); +    }  	if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE)  		return lResult; @@ -34,12 +37,14 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM  	if (uMsg == WM_WINDOWPOSCHANGED) {  		if ((wp->flags & SWP_NOSIZE) != 0)  			return DefWindowProcW(hwnd, uMsg, wParam, lParam); +        a->width = -1; +        a->height = -1;  		uiWindowsEnsureGetClientRect(a->hwnd, &client);  		areaDrawOnResize(a, &client);  		areaScrollOnResize(a, &client);  		{  		    double w, h; -		    loadAreaSize(a, a->rt, &w, &h); +		    loadAreaSize(a, &w, &h);  		    a->ah->Resize(a->ah, a, (int)w, (int)h);  		}  		return 0; @@ -56,7 +61,15 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM  // control implementation -uiWindowsControlAllDefaults(uiArea) +uiWindowsControlAllDefaultsExceptDestroy(uiArea) + +static void uiAreaDestroy(uiControl *c) +{ +    uiArea* a = uiArea(c); +    if (a->openGL && a->glcontext) freeGLContext(a->glcontext); +    uiWindowsEnsureDestroyWindow(a->hwnd); +    uiFreeControl(c); +}  static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height)  { @@ -182,6 +195,9 @@ uiArea *uiNewArea(uiAreaHandler *ah)  	uiWindowsNewControl(uiArea, a); +	a->width = -1; +	a->height = -1; +  	a->ah = ah;  	a->scrolling = FALSE;  	clickCounterReset(&(a->cc)); @@ -195,6 +211,50 @@ uiArea *uiNewArea(uiAreaHandler *ah)      uiAreaSetBackgroundColor(a, -1, -1, -1); +    a->openGL = 0; + +	return a; +} + +uiGLContext *uiAreaGetGLContext(uiArea* a) +{ +    if (!a->openGL) userbug("trying to get GL context from non-GL area"); + +    return a->glcontext; +} + +uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions) +{ +	uiArea *a; + +	uiWindowsNewControl(uiArea, a); + +	a->width = -1; +	a->height = -1; + +	a->ah = ah; +	a->scrolling = FALSE; +	clickCounterReset(&(a->cc)); + +	// a->hwnd is assigned in areaWndProc() +	uiWindowsEnsureCreateControlHWND(0, +		areaClass, L"", +		0, +		hInstance, a, +		FALSE); + +    uiAreaSetBackgroundColor(a, -1, -1, -1); + +    a->openGL = 1; + +    for (int i = 0; req_versions[i]; i++) +    { +        int major = uiGLVerMajor(req_versions[i]); +        int minor = uiGLVerMinor(req_versions[i]); +        a->glcontext = createGLContext(a, major, minor); +        if (a->glcontext) break; +    } +  	return a;  } @@ -204,6 +264,9 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)  	uiWindowsNewControl(uiArea, a); +	a->width = -1; +	a->height = -1; +  	a->ah = ah;  	a->scrolling = TRUE;  	a->scrollWidth = width; @@ -219,6 +282,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)      uiAreaSetBackgroundColor(a, -1, -1, -1); +    a->openGL = 0; // TODO, eventually??? +  	// set initial scrolling parameters  	areaUpdateScroll(a); diff --git a/src/libui_sdl/libui/windows/area.hpp b/src/libui_sdl/libui/windows/area.hpp index add62dd..cfc45a4 100644 --- a/src/libui_sdl/libui/windows/area.hpp +++ b/src/libui_sdl/libui/windows/area.hpp @@ -10,6 +10,8 @@ struct uiArea {  	HWND hwnd;  	uiAreaHandler *ah; +	int width, height; +  	BOOL scrolling;  	int scrollWidth;  	int scrollHeight; @@ -26,6 +28,9 @@ struct uiArea {  	int bgR, bgG, bgB; +	int openGL; +	uiGLContext* glcontext; +  	ID2D1HwndRenderTarget *rt;  }; @@ -42,6 +47,10 @@ extern void areaUpdateScroll(uiArea *a);  extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);  // areautil.cpp -extern void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height); +extern void loadAreaSize(uiArea *a, double *width, double *height);  extern void pixelsToDIP(uiArea *a, double *x, double *y);  extern void dipToPixels(uiArea *a, double *x, double *y); + +// gl.cpp +extern uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor); +extern void freeGLContext(uiGLContext* c); diff --git a/src/libui_sdl/libui/windows/areadraw.cpp b/src/libui_sdl/libui/windows/areadraw.cpp index a9ad477..f369255 100644 --- a/src/libui_sdl/libui/windows/areadraw.cpp +++ b/src/libui_sdl/libui/windows/areadraw.cpp @@ -6,6 +6,13 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)  {  	uiAreaHandler *ah = a->ah;  	uiAreaDrawParams dp; + +	if (a->openGL) +    { +        //(*(ah->Draw))(ah, a, &dp); +        return S_OK; +    } +  	COLORREF bgcolorref;  	D2D1_COLOR_F bgcolor;  	D2D1_MATRIX_3X2_F scrollTransform; @@ -13,7 +20,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)  	// no need to save or restore the graphics state to reset transformations;  it's handled by resetTarget() in draw.c, called during the following  	dp.Context = newContext(rt); -	loadAreaSize(a, rt, &(dp.AreaWidth), &(dp.AreaHeight)); +	loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight));  	dp.ClipX = clip->left;  	dp.ClipY = clip->top; @@ -113,6 +120,9 @@ static void onWM_PAINT(uiArea *a)  static void onWM_PRINTCLIENT(uiArea *a, HDC dc)  { +    // TODO???? +    if (a->openGL) return; +  	ID2D1DCRenderTarget *rt;  	RECT client;  	HRESULT hr; @@ -143,13 +153,16 @@ BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lRe  // TODO only if the render target wasn't just created?  void areaDrawOnResize(uiArea *a, RECT *newClient)  { -	D2D1_SIZE_U size; +    if (!a->openGL) +    { +        D2D1_SIZE_U size; -	size.width = newClient->right - newClient->left; -	size.height = newClient->bottom - newClient->top; -	// don't track the error; we'll get that in EndDraw() -	// see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx -	a->rt->Resize(&size); +        size.width = newClient->right - newClient->left; +        size.height = newClient->bottom - newClient->top; +        // don't track the error; we'll get that in EndDraw() +        // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx +        a->rt->Resize(&size); +    }  	// according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572)  	// we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore diff --git a/src/libui_sdl/libui/windows/areaevents.cpp b/src/libui_sdl/libui/windows/areaevents.cpp index 3ff7a47..46d6ab9 100644 --- a/src/libui_sdl/libui/windows/areaevents.cpp +++ b/src/libui_sdl/libui/windows/areaevents.cpp @@ -109,7 +109,7 @@ static void areaMouseEvent(uiArea *a, int down, int  up, WPARAM wParam, LPARAM l  		me.Y += a->vscrollpos;  	} -	loadAreaSize(a, NULL, &(me.AreaWidth), &(me.AreaHeight)); +	loadAreaSize(a, &(me.AreaWidth), &(me.AreaHeight));  	me.Down = down;  	me.Up = up; diff --git a/src/libui_sdl/libui/windows/areautil.cpp b/src/libui_sdl/libui/windows/areautil.cpp index 212ea42..ea13221 100644 --- a/src/libui_sdl/libui/windows/areautil.cpp +++ b/src/libui_sdl/libui/windows/areautil.cpp @@ -2,20 +2,35 @@  #include "uipriv_windows.hpp"  #include "area.hpp" -void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height) +// TODO: make those int rather than double +void loadAreaSize(uiArea *a, double *width, double *height)  {  	D2D1_SIZE_F size; +	if (a->width != -1) +    { +        *width = (double)a->width; +        *height = (double)a->height; +        return; +    } +  	*width = 0;  	*height = 0;  	if (!a->scrolling) { -		if (rt == NULL) +		/*if (rt == NULL)  			rt = a->rt;  		size = realGetSize(rt);  		*width = size.width;  		*height = size.height; -		dipToPixels(a, width, height); +		dipToPixels(a, width, height);*/ +		RECT rect; +        GetWindowRect(a->hwnd, &rect); +        *width = (double)(rect.right - rect.left); +        *height = (double)(rect.bottom - rect.top);  	} + +	a->width = (int)*width; +	a->height = (int)*height;  }  void pixelsToDIP(uiArea *a, double *x, double *y) diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp new file mode 100644 index 0000000..1e3732c --- /dev/null +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -0,0 +1,142 @@ +// 31 march 2019 +#include "uipriv_windows.hpp" +#include "area.hpp" + +#include <GL/gl.h> +#include <GL/wglext.h> + +struct uiGLContext +{ +    uiArea* a; + +    HWND hwnd; +    HDC dc; +    HGLRC rc; + +    unsigned int version; +}; + + +uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor) +{ +    uiGLContext* ctx; +    BOOL res; + +    ctx = uiNew(uiGLContext); + +    ctx->a = a; +    ctx->hwnd = a->hwnd; + +    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; +    pfd.iPixelType = PFD_TYPE_RGBA; +    pfd.cColorBits = 24; +    pfd.cAlphaBits = 8; +    pfd.cDepthBits = 24; +    pfd.cStencilBits = 8; +    pfd.iLayerType = PFD_MAIN_PLANE; + +    ctx->dc = GetDC(ctx->hwnd); +    if (!ctx->dc) +    { +        uiFree(ctx); +        return NULL; +    } + +    int pixelformat = ChoosePixelFormat(ctx->dc, &pfd); +    res = SetPixelFormat(ctx->dc, pixelformat, &pfd); +    if (!res) +    { +        ReleaseDC(ctx->hwnd, ctx->dc); +        uiFree(ctx); +        return NULL; +    } + +    ctx->rc = wglCreateContext(ctx->dc); +    if (!ctx->rc) +    { +        ReleaseDC(ctx->hwnd, ctx->dc); +        uiFree(ctx); +        return NULL; +    } + +    wglMakeCurrent(ctx->dc, ctx->rc); + +    if (vermajor >= 3) +    { +        HGLRC (*wglCreateContextAttribsARB)(HDC,HGLRC,const int*); +        HGLRC rc_better = NULL; + +        wglCreateContextAttribsARB = (HGLRC(*)(HDC,HGLRC,const int*))wglGetProcAddress("wglCreateContextAttribsARB"); +        if (wglCreateContextAttribsARB) +        { +            int attribs[15]; +            int i = 0; + +            attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; +            attribs[i++] = vermajor; +            attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; +            attribs[i++] = verminor; + +            attribs[i] = 0; +            rc_better = wglCreateContextAttribsARB(ctx->dc, NULL, attribs); +        } + +        wglMakeCurrent(NULL, NULL); +        wglDeleteContext(ctx->rc); + +        if (!rc_better) +        { +            ReleaseDC(ctx->hwnd, ctx->dc); +            uiFree(ctx); +            return NULL; +        } + +        ctx->version = uiGLVersion(vermajor, verminor); +        ctx->rc = rc_better; +        wglMakeCurrent(ctx->dc, ctx->rc); +    } + +    return ctx; +} + +void freeGLContext(uiGLContext* ctx) +{ +    if (ctx == NULL) return; +    wglMakeCurrent(NULL, NULL); +    wglDeleteContext(ctx->rc); +    ReleaseDC(ctx->hwnd, ctx->dc); +    uiFree(ctx); +} + +void uiGLMakeContextCurrent(uiGLContext* ctx) +{ +    if (ctx == NULL) +    { +        wglMakeCurrent(NULL, NULL); +        return; +    } + +    if (wglGetCurrentContext() == ctx->rc) return; +    int res = wglMakeCurrent(ctx->dc, ctx->rc); +} + +unsigned int uiGLGetVersion(uiGLContext* ctx) +{ +    if (ctx == NULL) return 0; +    return ctx->version; +} + +void *uiGLGetProcAddress(const char* proc) +{ +    return (void*)wglGetProcAddress(proc); +} + +void uiGLSwapBuffers(uiGLContext* ctx) +{ +    if (ctx == NULL) return; +    SwapBuffers(ctx->dc); +} diff --git a/src/libui_sdl/libui/windows/window.cpp b/src/libui_sdl/libui/windows/window.cpp index f52e2f6..18d1171 100644 --- a/src/libui_sdl/libui/windows/window.cpp +++ b/src/libui_sdl/libui/windows/window.cpp @@ -363,6 +363,21 @@ static void windowMonitorRect(HWND hwnd, RECT *r)  	*r = mi.rcMonitor;  } +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ +    RECT rect; +    if (GetWindowRect(w->hwnd, &rect) == 0) +        logLastError(L"error getting window position"); +    *x = rect.left; +    *y = rect.top; +} + +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ +    if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) +        logLastError(L"error moving window"); +} +  void uiWindowContentSize(uiWindow *w, int *width, int *height)  {  	RECT r; |