|
|
Home » U++ Library support » U++ Library : Other (not classified elsewhere) » [Proposal] Adding a GLLock struct to GLCtrl
[Proposal] Adding a GLLock struct to GLCtrl [message #54712] |
Wed, 02 September 2020 18:55 |
|
Xemuth
Messages: 387 Registered: August 2018 Location: France
|
Senior Member |
|
|
Hello, with the new version of Glew I moved my application to GLCtrl.
However, in many part of my application, I need to get the OpenGL context to perform many actions. The actual way of executing something in the good OpenGL Context is to call ExecuteGL(Event<> paint, bool swap_buffers). Which force me to surround my code arround this function. It work but not convenient and for some part it block me and force me to change my architecture.
To allow more flexibility in the way we work with GLCtrl I propose to add a structure to GLCtrl named GLLock, which can be invoqued to get the OpenGL context and release it when the object got destroyed :
//class GLCtrl : public Ctrl{
public:
struct GLLock{
private:
HWND hwnd;
HDC hDC;
public:
GLLock(GLCtrl& ctrl);
~GLLock();
};
//};
Win32GLCtrl.cpp :
GLCtrl::GLLock::GLLock(GLCtrl& ctrl){
hwnd = ctrl.pane.GetHWND();
GLCtrl::CreateContext();
hDC = GetDC(hwnd);
wglMakeCurrent(hDC, s_openGLContext);
}
GLCtrl::GLLock::~GLLock(){
wglMakeCurrent(NULL, NULL);
ReleaseDC(hwnd, hDC);
}
XGLCtrl.cpp:
GLCtrl::GLLock::GLLock(GLCtrl& ctrl){
glXMakeCurrent(s_Display, ctrl.win, s_GLXContext);
}
GLCtrl::GLLock::~GLLock(){
glXMakeCurrent(s_Display, None, NULL);
}
Here is a trivial exemple of how to use it :
bool LoadSTL(){ //This function is used when a button is pressed
try {
GLCtrl::GLLock __(canvas); //Canvas is the GLCtrl object
//Shaders Stuff
//OpenGL buffer filling and loading
//Definition of draw
return true;
} catch (Exc e) {
Exclamation(DeQtf(e));
}
return false;
}
|
|
|
Re: [Proposal] Adding a GLLock struct to GLCtrl [message #54713 is a reply to message #54712] |
Thu, 03 September 2020 00:37 |
|
Klugier
Messages: 1085 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Xemuth,
From my point of view the idea of "locking" looks reasonable. However, we should make it more smarter. Please noticed that the API we commit will be with us for the very long time. So, we need to be careful here. All we need to do is make context current and release it at the end of the block. So, I would suggest adding three dedicated methods to context attaching/activating GLCtrl and buffer swapping:
- ActivateContext(); (Anyway void ActivateContext(); from Win32 GLPane seems unimplemented)
- DeactivateContext();
- SwapBuffers();
So, in your case the logic will look as follow:
canvas.ActivateContext();
//Shaders Stuff
//OpenGL buffer filling and loading
canvas.SwapBuffers();
canvas.DeactivateContext();
// All these method will be proxy and send work to GLPane's classes.
return true;
In case of simplification we should add lock mechanisms as you suggested (The three above method should still be available, so you will have a choice):
GLCtrl::ContextLock __(canvas); // <- If this is nested glass GL prefix is redundant.
// Do we always want buffer swpaing if not I would see additional lock...
GLCtrl::ContextLockWithSwapBuffers __(canvas); // <- Alternatively ContextLock can have additional bool parameter (true by default),
// however according to the clean code bool parameter should be avoided, so I
// use more verbose notation here.
We also need documentation for GLCtrl and it seems that Copying file is missing too. Mirek can we add the second file?
Klugier
U++ - one framework to rule them all.
[Updated on: Thu, 03 September 2020 00:39] Report message to a moderator
|
|
|
Re: [Proposal] Adding a GLLock struct to GLCtrl [message #54714 is a reply to message #54713] |
Thu, 03 September 2020 02:30 |
|
Xemuth
Messages: 387 Registered: August 2018 Location: France
|
Senior Member |
|
|
Hello Klugier, You are right about adding method in addition to struct:
Here is the code I got:
GLCtrl.h
//Class GLCtrl : public Ctrl{
void ActivateContext();
void SwapBuffer();
void DesactivateContext();
struct ContextLock {
private:
GLCtrl& parent;
public:
ContextLock(GLCtrl& ctrl);
~ContextLock();
};
struct ContextLockWithSwapBuffers{
private:
GLCtrl& parent;
public:
ContextLockWithSwapBuffers(GLCtrl& ctrl);
~ContextLockWithSwapBuffers();
};
//};
Win32GLCtrl.cpp :
void GLCtrl::ActivateContext(){
HWND hwnd = pane.GetHWND();
GLCtrl::CreateContext();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(hDC, s_openGLContext);
}
void GLCtrl::SwapBuffer(){
HWND hwnd = GetHWND();
HDC hDC = GetDC(hwnd);
SwapBuffers(hDC);
}
void GLCtrl::DesactivateContext(){
HWND hwnd = GetHWND();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(NULL, NULL);
ReleaseDC(hwnd, hDC);
}
GLCtrl::ContextLock::ContextLock(GLCtrl& ctrl) : parent(ctrl){
HWND hwnd = parent.pane.GetHWND();
GLCtrl::CreateContext();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(hDC, s_openGLContext);
}
GLCtrl::ContextLock::~ContextLock(){
HWND hwnd = parent.pane.GetHWND();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(NULL, NULL);
ReleaseDC(hwnd, hDC);
}
GLCtrl::ContextLockWithSwapBuffers::ContextLockWithSwapBuffers(GLCtrl& ctrl) : parent(ctrl){
HWND hwnd = parent.pane.GetHWND();
GLCtrl::CreateContext();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(hDC, s_openGLContext);
}
GLCtrl::ContextLockWithSwapBuffers::~ContextLockWithSwapBuffers(){
HWND hwnd = parent.pane.GetHWND();
HDC hDC = GetDC(hwnd);
SwapBuffers(hDC);
wglMakeCurrent(NULL, NULL);
ReleaseDC(hwnd, hDC);
}
XGLCtrl.cpp :
void GLCtrl::ActivateContext(){
glXMakeCurrent(s_Display, win, s_GLXContext);
}
void GLCtrl::SwapBuffer(){
glXSwapBuffers(s_Display, win);
}
void GLCtrl::DesactivateContext(){
glXMakeCurrent(s_Display, None, NULL);
}
GLCtrl::ContextLock::ContextLock(GLCtrl& ctrl) : parent(ctrl){
glXMakeCurrent(s_Display, parent.win, s_GLXContext);
}
GLCtrl::ContextLock::~ContextLock(){
glXMakeCurrent(s_Display, None, NULL);
}
GLCtrl::ContextLockWithSwapBuffers::ContextLockWithSwapBuffers(GLCtrl& ctrl) : parent(ctrl){
glXMakeCurrent(s_Display, parent.win, s_GLXContext);
}
GLCtrl::ContextLockWithSwapBuffers::~ContextLockWithSwapBuffers(){
glXSwapBuffers(s_Display, parent.win);
glXMakeCurrent(s_Display, None, NULL);
}
[Updated on: Thu, 03 September 2020 03:35] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
Re: [Proposal] Adding a GLLock struct to GLCtrl [message #54771 is a reply to message #54769] |
Wed, 09 September 2020 21:25 |
|
Klugier
Messages: 1085 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo, Mirek and Xemuth,
Koldo, you convinced me If two members of the community wants that functionality and probably more. I opt to add it also - with the version that will have the lowest maintenance cost.
And I think version without swapping should be:
GLLock __(canvas, false);
Without the need to call three methods/functions instead.
I do not have strong opinion about GLCtrl::GLLock - maybe simple GLLock within Upp namespace is better. Less typing at least.
So, Mirek we are waiting for final decision. We know that you follow this topic
Klugier
U++ - one framework to rule them all.
[Updated on: Wed, 09 September 2020 22:33] Report message to a moderator
|
|
|
Re: [Proposal] Adding a GLLock struct to GLCtrl [message #54775 is a reply to message #54771] |
Thu, 10 September 2020 16:52 |
|
Xemuth
Messages: 387 Registered: August 2018 Location: France
|
Senior Member |
|
|
Hello Klugier !
I then propose this integration :
struct GLLock{
private:
GLCtrl& ctrl;
bool swap;
public:
GLLock(GLCtrl& glCtrl, bool swapBuffer = false);
~GLLock();
};
class GLCtrl : public Ctrl {
typedef GLCtrl CLASSNAME;
friend class GLLock;
//*************************
//}
with for Win32GLCtrl.cpp :
GLLock::GLLock(GLCtrl& glCtrl, bool swapBuffer) : ctrl(glCtrl), swap(swapBuffer)
{
HWND hwnd = ctrl.pane.GetHWND();
HDC hDC = GetDC(hwnd);
wglMakeCurrent(hDC, s_openGLContext);
}
GLLock::~GLLock()
{
if(swap){
HWND hwnd = ctrl.pane.GetHWND();
HDC hDC = GetDC(hwnd);
SwapBuffers(hDC);
}else{
glFlush();
}
wglMakeCurrent(NULL, NULL);
}
and for XGLCtrl.cpp :
GLLock::GLLock(GLCtrl& glCtrl, bool swapBuffer) : ctrl(glCtrl), swap(swapBuffer)
{
glXMakeCurrent(s_Display, ctrl.win, s_GLXContext);
}
GLLock::~GLLock()
{
if(swap){
glXSwapBuffers(s_Display, win);
}else{
glFlush();
}
glXMakeCurrent(s_Display, None, NULL);
}
Here is diff file :
|
|
|
Goto Forum:
Current Time: Sat Dec 14 13:32:43 CET 2024
Total time taken to generate the page: 0.02323 seconds
|
|
|