Hi @stevebaer,
I will for sure post the code once I have it working!
RhinoCommon must be doing some stuff behind the scenes. If I open Rhino with Rhino.Runtime.InProcess.WindowStyle.Hidden, the viewport is just black. I’m making progress though. I’m now able to render a single frame to my control with the Rhino window hidden, but I’m getting an exception on the second frame.
Currently I create my new view like this.
CRhinoDoc* pDoc = RhinoApp().ObsoleteActiveDoc();
CRhinoView* pView = CRhinoView::FromRuntimeSerialNumber(pDoc->CreateRhinoView(nullptr, true))
if (nullptr == m_pView)
return;
// Setup the display pipeline
m_pView->SetupDisplayPipeline();
// Display attributes
CDisplayPipelineAttributes* pDP = new CDisplayPipelineAttributes(*CRhinoDisplayAttrsMgr::StdShadedAttrs());
I set up my render device context like this.
// Create a DC for rendering
HDC displayDC = ::GetDC(NULL);
m_RenderDC = ::CreateCompatibleDC(displayDC);
::ReleaseDC(NULL, displayDC);
// Create a bitmap buffer
BITMAPINFO bmi{};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height; // yup, negative for top-down order
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
uchar* data = nullptr;
m_RenderBitmap = ::CreateDIBSection(m_RenderDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&data), NULL, 0);
// Create a Qt wrapper over the bitmap data
m_RenderImage = QImage(data, width, height, QImage::Format_RGB32);
Then for my paint event, I do this. This works fine the first time it is called, then throws an exception somewhere down in DrawToDC the second time my paint event is triggered.
HGDIOBJ prevObj = ::SelectObject(m_RenderDC, m_RenderBitmap);
pPipeline->DrawToDC(m_RenderDC, w, h, *pDP);
::SelectObject(m_RenderDC, prevObj);
// Qt stuff
QPainter painter(this);
painter.drawImage(0, 0, m_RenderImage);
I admit, device contexts are not my specialty and I may not be handling them correctly. I’m not sure what the best practices are for display pipelines. Is there anything I need to be doing to manage the display pipeline?
This is the stack trace I get when the exception is thrown.
KernelBase.dll!RaiseException() Unknown
vcruntime140.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 80 C++
mfc140u.dll!AfxThrowResourceException() Line 1347 C++
mfc140u.dll!AfxRegisterWndClass(unsigned int nClassStyle, HICON__ * hCursor, HBRUSH__ * hbrBackground, HICON__ * hIcon) Line 1510 C++
[Inline Frame] RhinoCore.dll!COnScreenBuffer::{ctor}(int) Line 329 C++
RhinoCore.dll!CRhinoDisplayPipeline::CreateOnScreenBuffer(int nW, int nH) Line 1739 C++
RhinoCore.dll!CRhinoDisplayPipeline::CreateEngine() Line 2123 C++
RhinoCore.dll!CRhinoDisplayPipeline::InitializeEngine() Line 12890 C++
RhinoCore.dll!CRhinoDisplayPipeline::ClonePipeline(CRhinoViewport & vp) Line 16319 C++
RhinoCore.dll!CRhinoDisplayPipeline::DrawToDC(HDC__ * pDC, int nWidth, int nHeight, const CDisplayPipelineAttributes & attrs) Line 18360 C++
QtRhinoInsideTest.exe!QRhinoView::paintEvent(QPaintEvent * pEvent) Line 89 C++
Thanks,