WxWidgets and modern opengl (3.3+) - user-interface

Does anyone know if the WxWidgets library plays well with modern shader style openGL (3.3+)? All the stuff I found seems to be using the old style. I'm looking to use either QT or WxWidgets for my application, but it seems like getting shader stuff to work with widgets might be a nightmare. Does anyone have experience with this?

In wxWidgets >= 3.1 using wxGLContext with an appropriate Core-context wxGLContextAttrs ought to work:
wxGLContextAttrs cxtAttrs;
cxtAttrs.CoreProfile().OGLVersion(3, 3).EndList();
As Ripi2 pointed out from the pyramid sample:
//We create a wxGLContext in this constructor.
//We do OGL initialization at OnSize().
MyGLCanvas::MyGLCanvas(MyFrame* parent, const wxGLAttributes& canvasAttrs)
: wxGLCanvas(parent, canvasAttrs)
{
m_parent = parent;
m_oglManager = NULL;
m_winHeight = 0; // We have not been sized yet
// Explicitly create a new rendering context instance for this canvas.
wxGLContextAttrs ctxAttrs;
#ifndef __WXMAC__
// An impossible context, just to test IsOk()
ctxAttrs.PlatformDefaults().OGLVersion(99, 2).EndList();
m_oglContext = new wxGLContext(this, NULL, &ctxAttrs);
if ( !m_oglContext->IsOK() )
{
#if wxUSE_LOGWINDOW
wxLogMessage("Trying to set OpenGL 99.2 failed, as expected.");
#endif // wxUSE_LOGWINDOW
delete m_oglContext;
ctxAttrs.Reset();
#endif //__WXMAC__
ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(3, 2).EndList();
m_oglContext = new wxGLContext(this, NULL, &ctxAttrs);
#ifndef __WXMAC__
}
#endif //__WXMAC__
if ( !m_oglContext->IsOK() )
{
wxMessageBox("This sample needs an OpenGL 3.2 capable driver.\nThe app will end now.",
"OpenGL version error", wxOK | wxICON_INFORMATION, this);
delete m_oglContext;
m_oglContext = NULL;
}
else
{
#if wxUSE_LOGWINDOW
wxLogMessage("OpenGL Core Profile 3.2 successfully set.");
#endif // wxUSE_LOGWINDOW
}
}

Related

Windows Bitmap print driver winddk OEMNextBand, OEMSendPage

I am observing the OEMSendPage doesn't get invoked always.
When does OEMSendPage get called?
We have a legacy printer which does some processing inside OEMSendPage. I hate to move it to a different place in the process. It has been working but now I am working on some enhancements and need to figure this out.
The other commands are OEMStartPage, OEMStartDoc, OEMTextOut, OEMStartBanding,OEMNextBand,OEMEndDoc.
These all are called except SendPage.
Currently I am attaching VS to spool.exe and the printer is installed at File:port.
When does SendPage command get called?
static const DRVFN s_aOemHookFuncs[] =
#if defined(IMPL_TEXTOUT)
{INDEX_DrvTextOut, (PFN)OEMTextOut},
#endif
#if defined(IMPL_TRANSPARENTBLT)
{INDEX_DrvTransparentBlt, (PFN)OEMTransparentBlt},
#endif
#if defined(IMPL_STARTDOC)
{INDEX_DrvStartDoc, (PFN)OEMStartDoc},
#endif
#if defined(IMPL_ENDDOC)
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
#endif
#if defined(IMPL_STARTPAGE)
{INDEX_DrvStartPage, (PFN)OEMStartPage},
#endif
#if defined(IMPL_SENDPAGE)
{INDEX_DrvSendPage, (PFN)OEMSendPage},
#endif
As an update I found on the following link
https://learn.microsoft.com/en-us/windows-hardware/drivers/print/rendering-a-print-job#-banding-not-in-use
So I added the part of processing to NextBand also including SendPage.
But something is not correct. OEMNextBand gets called multiple times and the PCL has many pages. The original is only one page but PCL has so many pages.
Can anyone suggest?
char gszPageText[32767];
BOOL APIENTRY
OEMStartBanding(
SURFOBJ *pso,
POINTL *pptl
)
{
return (pOemPDEV->m_pfnDrvStartBanding)(pso,
pptl);
}
BOOL APIENTRY
OEMNextBand(
SURFOBJ *pso,
POINTL *pptl
)
/*++
{
//VERBOSE(L"OEMNextBand entry.");
PDEVOBJ pDevObj = (PDEVOBJ)pso->dhpdev;
POEMPDEV pOemPDEV = (POEMPDEV)pDevObj->pdevOEM;
// Punt call back to UNIDRV.
BOOL b= (pOemPDEV->m_pfnDrvNextBand)(pso,
pptl);
if (pptl != NULL && pptl->x == -1 && pptl->y == -1)
{
BOOL c = DOPCLProcessingPerPage(pso, gFirstPage, gszPageText);
if (!c)
return TRUE;
}
//if (!CreatePCLRasterGraphicPage(pso, gFirstPage, gszPageText))
//return TRUE;
return b;
}
DrvEnableSurface to call EngModifySurface to disable banding. I don't know the pros and cons of disabling banding w.r.t performance. This is a bitmap driver
Edited
**For Mono**
StartDoc
-- then for as many pages in the document
StartPage
SendPage
EndDoc
**For Colour**
StartDoc
-- then for as many pages in the document
StartPage
StartBanding
-- then for so many bands
NextBand
SendPage ?? (what is the send page equivalent here for color)
EndDoc
**
Edited for EnableDriverSurface
static const DRVFN s_aOemHookFuncs[] =
{
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
{INDEX_DrvSendPage, (PFN)OEMSendPage},
{INDEX_DrvStartBanding, (PFN)OEMStartBanding},
{INDEX_DrvNextBand, (PFN)OEMNextBand},
{INDEX_DrvTextOut, (PFN)OEMTextOut},
{INDEX_DrvStartPage, (PFN)OEMStartPage},
{INDEX_DrvStartDoc,(PFN)OEMStartDoc},
//added this
{INDEX_DrvEnableSurface ,(PFN)DrvEnableSurface}
// {INDEX_DrvEnableSurface, (PFN)DrvEnableSurface},
};
HSURF APIENTRY DrvEnableSurface(
DHPDEV dhpdev)
{
HSURF hsurf;
SIZEL sizl;
ULONG ulBitmapType;
FLONG flHooks;
// Create engine bitmap around frame buffer.
PDEVOBJ ppdev = (PDEVOBJ)dhpdev;
POEMPDEV pOemPDEV = (POEMPDEV)ppdev->pdevOEM;
EngModifySurface(hsurf,......)
return(hsurf);
}
**

Zero-Copy messaging with zmqpp

ZeroCopy messaging is something that can be implemented in zeromq, but is it possible to use it with the zmqpp c++ bindings? There is almost no documentation, and I was not able to find anything in the examples...
I would switch to cppzmq.
It's a more active project and maintained by some of the core libzmq people.
It's header only and has support for zero copy.
Just simply use zmqpp::message::copy().
In the zmqpp source code we can see:
void message::copy(message const& source)
{
_parts.resize( source._parts.size() );
for(size_t i = 0; i < source._parts.size(); ++i)
{
_parts[i] = source._parts[i].copy();
}
// we don't need a copy of the releasers as we did data copies of the internal data,
//_releasers = source._releasers;
//_strings = source._strings
}
the _parts which defined as:
private:
typedef std::vector<frame> parts_type;
parts_type _parts;
so, source._parts[i].copy() actually call zmqpp::frame::copy() which defined here:
frame frame::copy() const
{
frame other( size() );
other._sent = _sent;
if( 0 != zmq_msg_copy( &other._msg, const_cast<zmq_msg_t*>(&_msg) ) )
{
throw zmq_internal_exception();
}
return other;
}
zmqpp::frame::_msg in the code snippet is defined as zmq_msg_t. All zmq_msg_t object in the frame objects of source zmqpp::message object been zero copied by zmq_msg_copy to new zmqpp::message object.
so, zmqpp::message::copy() help us get a new zmqpp::message object which it's all frame is zero copied from the source zmqpp::message object.

Custom FireMonkey component does not get drawn

Working in C++Builder 10.2 Tokyo, I am trying to add a custom component to a FireMonkey TForm programmatically at runtime.
The custom component is not installed as a package and registered in the IDE (as that ended up complicating the project too much), rather it is simply a subclass of TPanel.
However, The component, and its children, do not get drawn when I run the application. I have tested this on Windows and Android, and tried multiple modifications, like setting the Width and Height explicitly.
How can I fix this?
Below is the relevant bit of my code:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm3D(Owner)
{
mkView = new MKView(this);
mkView->Align = TAlignLayout::Client;
mkView->Enabled = true;
mkView->Visible = true;
mkView->Parent = this;
}
__fastcall MKView::MKView(TComponent *Owner)
: TPanel(Owner)
{
this->OnMouseDown = MKView_OnMouseDown;
TLabel1 = new TLabel(this);
TLabel1->Text = "Here I am!";
TLabel1->Enabled = true;
TLabel1->Visible = true;
TLabel1->Parent = this;
TLabel1->OnMouseDown = MKView_OnMouseDown;
}
It looks like TForm3D doesn't work well with standard FireMonkey components, as it is designed for rendering FireMonkey 3D components and uses OnRender() instead of OnPaint(). I was using TForm3D for its OpenGL context, but having switched to a standard TForm the components are now being drawn.

Qt seems to leak memory everywhere

I have big problems with memory leaks in Qt.
The problems is that when i run methods like:
qwidget->show();
qwidget->hide();
qwidget->setVisible(...);
qlabel->setText(...);
qwidget->setEnabled(...);
then it leaks memory.
I do not create any objects on the fly. I have created all widgets on startup and I just hiding and showing widgets and changing text on some labels all the time.
And when I remove those methods, then it doesn't leaks memory at all.
Is there someone who know why it is that way or if someone knows what happens under the hood? Or does Qt have memory problems?
I run windows 7 x64 with Qt 5.0.1 x64 in release mode.
Now i have added a test code:
#include "qtmemoryleaktest.h"
#include "Content_Logs.h"
QWidget* m_placeholder;
bool m_toggle;
QtMemoryLeakTest::QtMemoryLeakTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
m_placeholder = new Content_Logs(this);
this->layout()->addWidget( m_placeholder );
connect( ui.pushButton, &QPushButton::clicked, this, &QtMemoryLeakTest::toggleClick );
}
void QtMemoryLeakTest::toggleClick()
{
if( m_toggle = !m_toggle )
{
m_placeholder->show();
}
else
{
m_placeholder->hide();
}
}
Memory grows everytime a click on the button. from 8 mb to 47 mb in 20 minutes. But if a replace Content_Logs to a QWidget, no memory leaks. So i Think there is a bug in Qts self gererated ui-classes? In Content_Logs i have labels, lineEdits, Spacers, TableWidgets, Checkboxes, DateTimeEdits, ComboBoxes and so on.
Code in Conte_Logs:
#include "Content_Logs.h"
Content_Logs::Content_Logs( QWidget* parent = 0 )
: QWidget( parent )
{
ui.setupUi( this );
}
Content_Logs::~Content_Logs()
{
}

how do I set quad buffering with jogl 2.0

I'm trying to create a 3d renderer for stereo vision with quad buffering with Processing/Java. The hardware I'm using is ready for this so that's not the problem.
I had a stereo.jar library in jogl 1.0 working for Processing 1.5, but now I have to use Processing 2.0 and jogl 2.0 therefore I have to adapt the library.
Some things are changed in the source code of Jogl and Processing and I'm having a hard time trying to figure out how to tell Processing I want to use quad buffering.
Here's the previous code:
public class Theatre extends PGraphicsOpenGL{
protected void allocate()
{
if (context == null)
{
// If OpenGL 2X or 4X smoothing is enabled, setup caps object for them
GLCapabilities capabilities = new GLCapabilities();
// Starting in release 0158, OpenGL smoothing is always enabled
if (!hints[DISABLE_OPENGL_2X_SMOOTH])
{
capabilities.setSampleBuffers(true);
capabilities.setNumSamples(2);
}
else if (hints[ENABLE_OPENGL_4X_SMOOTH])
{
capabilities.setSampleBuffers(true);
capabilities.setNumSamples(4);
}
capabilities.setStereo(true);
// get a rendering surface and a context for this canvas
GLDrawableFactory factory = GLDrawableFactory.getFactory();
drawable = factory.getGLDrawable(parent, capabilities, null);
context = drawable.createContext(null);
// need to get proper opengl context since will be needed below
gl = context.getGL();
// Flag defaults to be reset on the next trip into beginDraw().
settingsInited = false;
}
else
{
// The following three lines are a fix for Bug #1176
// http://dev.processing.org/bugs/show_bug.cgi?id=1176
context.destroy();
context = drawable.createContext(null);
gl = context.getGL();
reapplySettings();
}
}
}
This was the renderer of the old library. In order to use it, I needed to do size(100, 100, "stereo.Theatre").
Now I'm trying to do the stereo directly in my Processing sketch. Here's what I'm trying:
PGraphicsOpenGL pg = ((PGraphicsOpenGL)g);
pgl = pg.beginPGL();
gl = pgl.gl;
glu = pg.pgl.glu;
gl2 = pgl.gl.getGL2();
GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities capabilities = new GLCapabilities(profile);
capabilities.setSampleBuffers(true);
capabilities.setNumSamples(4);
capabilities.setStereo(true);
GLDrawableFactory factory = GLDrawableFactory.getFactory(profile);
If I go on, I should do something like this:
drawable = factory.getGLDrawable(parent, capabilities, null);
but drawable isn't a field anymore and I can't find a way to do it.
How do I set quad buffering?
If I try this:
gl2.glDrawBuffer(GL.GL_BACK_RIGHT);
it obviously doesn't work :/
Thanks.

Resources